/*hdr
**      FILE:           LFileSelect.cpp
**      AUTHOR:         Matthew Allen
**      DATE:           20/5/2002
**      DESCRIPTION:    Common file/directory selection dialog
**
**      Copyright (C) 1998-2002, Matthew Allen
**              fret@memecode.com
*/

#include <stdio.h>
#include <stdlib.h>

#include "lgi/common/Lgi.h"
#include "lgi/common/Popup.h"
#include "lgi/common/List.h"
#include "lgi/common/TextLabel.h"
#include "lgi/common/Edit.h"
#include "lgi/common/Button.h"
#include "lgi/common/CheckBox.h"
#include "lgi/common/Combo.h"
#include "lgi/common/Tree.h"
#include "lgi/common/TableLayout.h"
#include "lgi/common/Box.h"
#include "lgi/common/FileSelect.h"
#include "lgi/common/Menu.h"

#define FSI_FILE			0
#define FSI_DIRECTORY		1
#define FSI_BACK			2
#define FSI_UPDIR			3
#define FSI_NEWDIR			4
#define FSI_DESKTOP			5
#define FSI_HARDDISK		6
#define FSI_CDROM			7
#define FSI_FLOPPY			8
#define FSI_NETWORK			9

enum DlgType
{
	TypeNone,
	TypeOpenFile,
	TypeOpenFolder,
	TypeSaveFile
};

class LFileSelectDlg;

char ModuleName[] = "File Select";

uint32_t IconBits[] = {
0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x0000F81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xC980FA8A, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x738E738E, 0xF81F738E, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F,
0xF81FF81F, 0x8430F81F, 0x84308430, 0x84308430, 0xF81F8430, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x9CE09CE0, 0x9CE09CE0, 0x00009CE0, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xCCE0F81F, 0x9800FCF9, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F,
0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x738E738E, 0xCE6C9E73, 0x738EC638, 0xF81F738E, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x9FFF738E, 0x9FFF9FFF, 0x9FFF9FFF, 0x00009FFF, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x9CE0F81F, 0xFFF9F7BE, 0xFFF3FFF9, 0x9CE0FFF3, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x9CE09CE0, 0x9CE09CE0, 0x00009CE0, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x0000F81F, 0xF81FF81F, 0xF81FF81F, 0x04F904F9,
0x04F904F9, 0xAD720313, 0xAD72AD72, 0xAD72AD72, 0xFE60CCE0, 0x00009B00, 0x0000AD72, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x738EF81F, 0x667334F3, 0xCE6C9E73, 0xC638B5B6, 0x3186C638, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFFF738E, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xF81FF81F, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0xF81F738E, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xCE6C9CE0, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0x9CE09CE0, 0x9CE09CE0, 0x9CE09CE0, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x0000F81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x9CE0F81F, 0xFFF9F7BE, 0xFFF3FFF9, 0x9CE0FFF3,
0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81F0000, 0x667F04F9, 0x031304F9, 0xFFFFCE73, 0xFFF9FFFF, 0xCCE0FFFF, 0x9B00FFF3, 0x04F90000, 0x00000313, 0xF81FF81F, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0xF81F738E, 0xF81FF81F, 0xF81FF81F, 0x6673738E, 0x34F36673, 0xCE736673, 0xB5B6C638, 0xB5B6DEFB, 0xF81F3186, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFFF738E, 0xFFFFFFFF, 0xCFFFCFFF, 0x0000CFFF, 0x738EF81F, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0x0000738E, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000, 0x0000FFFF, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF9FFF9, 0xCE6CFFF3,
0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0x00000000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xCE6C9CE0, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0x9CE09CE0, 0x9CE09CE0, 0x9CE09CE0, 0xF81FF81F, 0xF81FF81F, 0x9CE09CE0, 0x9CE09CE0, 0xF81F0000, 0x0000F81F, 0x0000F81F, 0x0000F81F, 0xF81FF81F, 0x04F904F9, 0xCE730313, 0xFFFFFFFF, 0xFFF9FFF9, 0xFE60CCE0, 0x00009B00, 0x667F3313, 0x00000313, 0x738EF81F, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0x0000738E, 0xF81FF81F, 0xF81FF81F, 0x34F98430, 0x667364F9, 0x84306679, 0xD6BAB5B6, 0xB5B6C638, 0xF81F3186, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xCFFF738E, 0xCFFFCFFF, 0xCFFFCFFF, 0x0000CFFF, 0xFFFF738E, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x9CF3FFFF, 0x0000738E, 0xFFFF0000, 0xFFFFFFFF,
0xFFFFFFFF, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xCE6CFE73, 0xF81F0000, 0xF81FF81F, 0x0000F81F, 0x000007FF, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF9FFF9, 0xCE6CFFF3, 0xF81F0000, 0x9CE0F81F, 0xFFF9F7BE, 0xFFF3FFF3, 0x00009CE0, 0xF81FF81F, 0xF81F0000, 0xF81F0000, 0xF81FF81F, 0x031304F9, 0xFFFFCE73, 0x94B294B2, 0xCCE094B2, 0x9B00FFF3, 0xAD720000, 0x3313FFF9, 0x00000313, 0xFFFF738E, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x9CF3FFFF, 0x0000738E, 0xF81FF81F, 0x738EF81F, 0xA53494B2, 0x667964F3, 0x00008430, 0xA5348430, 0xCE79B5B6, 0x3186CE79, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xCE79738E,
0xCE79C638, 0xC638B5B6, 0x0000B5B6, 0xD6BA738E, 0xC638C638, 0xC638C638, 0xC638C638, 0xB5B6C638, 0x04200660, 0x94B2B5B6, 0x0000738E, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xD699FFFF, 0xD699D699, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xCE6CFFF3, 0xF81F0000, 0xF81FF81F, 0x07FF0000, 0x000007FF, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0x0000FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xCE6CFE73, 0xF81F0000, 0xCE6C9CE0, 0xCE6CCE6C, 0xCE6CCE6C, 0x9CE0CE6C, 0x9CE09CE0, 0xF81F9CE0, 0x0000F81F, 0x0000F81F, 0xCE730313, 0xFFFFFFFF, 0xFFFF94B2, 0xFE60CCE0, 0x00009B00, 0xFFF9AD72, 0xCE73CE73, 0x00003313, 0xD6BA738E, 0xC638C638, 0xC638C638, 0xC638C638, 0xB5B6C638, 0x04200660, 0x94B2B5B6, 0x0000738E,
0xF81FF81F, 0x738EF81F, 0xB5B6B5B6, 0x8430CE79, 0xF81F0000, 0x84300000, 0xCE79CE79, 0x3186CE79, 0xF81FF81F, 0x84308430, 0x84308430, 0x84308430, 0xC638738E, 0x84308430, 0x84308430, 0x0000C638, 0xDEFB738E, 0xC638B5B6, 0xC638C638, 0xC638C638, 0xB5B6B5B6, 0xB5B6B5B6, 0x94B2B5B6, 0x0000738E, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xD699FFFF, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FE73, 0xCE6CFE73, 0xF81F0000, 0x0000F81F, 0x07FF07FF, 0x07FF07FF, 0x07FF07FF, 0x07FF07FF, 0x07FF07FF, 0xF81F0000, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0x00000000, 0xFFF30000, 0xFE73FFF3, 0xFE73FFF3, 0xCE6CFFF3, 0xF81F0000, 0xFFF99CE0, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF9FFF9, 0xFFF3FFF9, 0x0000CE6C, 0xF81F0000, 0xF81FF81F, 0xFFFFAD72, 0xFFF9FFFF, 0xFFFF94B2,
0x9B009CEC, 0x00000000, 0xCE73FFF9, 0xAD72FFF9, 0x000094B2, 0xDEFB738E, 0xC638B5B6, 0xC638C638, 0xC638C638, 0xB5B6B5B6, 0xB5B6B5B6, 0x94B2B5B6, 0x0000738E, 0xF81FF81F, 0x738EF81F, 0xF7BEE73C, 0xB5B6E73C, 0x00008430, 0xB5B68430, 0xF7BEEF7D, 0x3186CE79, 0x8430F81F, 0xC638C638, 0xC638C638, 0xC638C638, 0xCE79738E, 0x0000738E, 0xFFFF738E, 0x0000B5B6, 0xDEFB738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x94B2B5B6, 0x0000738E, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xD699FFFF, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xCE6CFFF3, 0xF81F0000, 0x0000F81F, 0x07FF07FF, 0x07FF07FF, 0x07FF07FF, 0x07FF07FF, 0x07FF07FF, 0xF81F0000, 0xF81FF81F, 0xFFF99CE0, 0x0000FFF3, 0x00000000, 0x00000000, 0xFFF3FFF3, 0xFFF3FE73,
0xCE6CFE73, 0xF81F0000, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFE73FFF3, 0x0000CE6C, 0x0000F81F, 0xF81FF81F, 0xFFFFAD72, 0xFFF9FFF9, 0xFFFF94B2, 0xFFFF0000, 0x0000FFF9, 0xFFF9CE73, 0xCE73AD72, 0x000094B2, 0xDEFB738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x94B2B5B6, 0x0000738E, 0x8430F81F, 0x84308430, 0xA5348430, 0xA534B5B6, 0x8430A534, 0xDEFB34F3, 0xFFFFE73C, 0xF81F3186, 0xFFFF8430, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 0x00000000, 0x00000000, 0xF81F0000, 0xD6BA738E, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x94B2B5B6, 0x0000738E, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xD699FFFF, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FE73, 0xFFF3FE73, 0xCE6CFE73, 0xF81F0000, 0xF81FF81F,
0x07FF0000, 0x000007FF, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0x0000FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xCE6CFFF3, 0xF81F0000, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FFF3, 0xFFF3FE73, 0x0000CE6C, 0xF81FF81F, 0xF81F0000, 0xFFF9AD72, 0xFFF9FFF9, 0xFFFF94B2, 0xFFFFFFFF, 0x0000FFF9, 0xCE73FFF9, 0xAD72CE73, 0x000094B2, 0xD6BA738E, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x94B2B5B6, 0x0000738E, 0xFFFF8430, 0xFFFFFFFF, 0xA534738E, 0xB5B6A534, 0xCE73D6BA, 0x34F96673, 0xB5B6CFFF, 0xF81F3186, 0xC6388430, 0xC638C638, 0xC638C638, 0xC638C638, 0xC638C638, 0xC638F800, 0x738E8430, 0xF81F0000, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0xF81F0000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xD699FFFF, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xFE73FFF3, 0xCE6CFE73, 0xF81F0000, 0xF81FF81F, 0x0000F81F, 0x000007FF, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0x0000FFF3, 0xFFF3FFF3, 0xFFF3FE73, 0xFFF3FE73, 0xCE6CFE73, 0xF81F0000, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FFF3, 0xFE73FFF3, 0xFE73FFF3, 0x0000CE6C, 0xF81FF81F, 0xF81FF81F, 0xFFF9AD72, 0xFFF9FFF9, 0xFFFF94B2, 0xFFFFFFFF, 0x0000FFF9, 0xCE73CE73, 0xCE73AD72, 0x000094B2, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0x738E738E, 0xF81F0000, 0xFFFF8430, 0xC638C638, 0x738EC638, 0xB5B6A534, 0xCE73CE79, 0x04F99E73, 0x000004F9, 0xF81FF81F, 0xC6388430, 0xC638C638, 0x84308430, 0x84308430, 0xC638C638, 0xC638C638, 0x738E8430,
0xF81F0000, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81FF81F, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xD699FFFF, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FE73, 0xFFF3FE73, 0xFFF3FE73, 0xFFF3FE73, 0xFE73FE73, 0xCE6CFE73, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0x00000000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FFF3, 0x0000FFF3, 0x00000000, 0x00000000, 0xFE730000, 0xCE6CFE73, 0xF81F0000, 0xFFF99CE0, 0xFFF3FFF3, 0xFFF3FE73, 0xFFF3FE73, 0xFFF3FE73, 0x0000CE6C, 0xF81FF81F, 0xF81FF81F, 0xFFF904F9, 0xFFF9FFF9, 0xFFF994B2, 0xFFF9FFF9, 0x0000FFF9, 0xAD72CE73, 0xAD72CE73, 0x00003313, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81FF81F, 0xFFFF8430, 0x31863186,
0x31863186, 0x84308430, 0xCE73CE79, 0x31869E73, 0x00003186, 0xF81FF81F, 0xC6388430, 0x84308430, 0x00000000, 0x00000000, 0x84308430, 0xC6388430, 0x738E8430, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xB5B6F81F, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xD699FFFF, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xCE6C9CE0, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0x0000F81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFF99CE0, 0xFFF3FE73, 0xFFF3FE73, 0xFFF3FE73, 0xFFF3FE73, 0xFE73FE73, 0xCE6CFE73, 0xF81F0000, 0xFFF99CE0, 0xFFF3FE73, 0xFE73FFF3, 0xFE73FFF3, 0xFE73FFF3, 0x0000CE6C, 0xF81FF81F, 0xF81FF81F, 0x04F904F9, 0xFFF9FFF9, 0x00000000, 0x00000000, 0x00000000,
0xCE73AD72, 0x3313AD72, 0x00003313, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFFF8430, 0x042007E0, 0xFFFFFFFF, 0xC638C638, 0x31863186, 0xC6383186, 0x0000738E, 0xF81FF81F, 0xC6388430, 0xC638C638, 0xFFFFFFFF, 0xFFFFFFFF, 0xC638C638, 0xC638C638, 0x738E8430, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xB5B6F81F, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xFFFF0000, 0xD699D699, 0xD699D699, 0xD699D699, 0xD699D699, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xCE6C9CE0, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xF81F0000,
0xCE6C9CE0, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0xCE6CCE6C, 0x0000CE6C, 0xF81FF81F, 0xF81FF81F, 0x667F04F9, 0xFFF904F9, 0xCE73FFF9, 0xCE73FFF9, 0xAD72CE73, 0xAD72CE73, 0x667F3313, 0x00003313, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x8430738E, 0x84308430, 0x84308430, 0x84308430, 0x84308430, 0x84308430, 0x00008430, 0xF81FF81F, 0x84308430, 0x84308430, 0x84308430, 0x84308430, 0x84308430, 0x84308430, 0x00008430, 0xF81FF81F, 0xB5B6F81F, 0xB5B6F81F, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xB5B6B5B6, 0xF81FB5B6, 0xF81FB5B6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F,
0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81FF81F, 0xF81FF81F, 0x03130313, 0x04F90313, 0x94B294B2, 0x94B294B2, 0x94B294B2, 0x331394B2, 0x33133313, 0x00003313, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81FF81F, 0x0000F81F, 0x0000F81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81F0000, 0xF81F0000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F,
0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F,
0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F, 0xF81FF81F};

LInlineBmp FileSelectIcons = { 160, 16, 16, IconBits };

enum Icons2Idx
{
	IcoApps,
	IcoHome,
	IcoDesktop,
	IcoDocuments,
	IcoDownloads,
	IcoMovies,
	IcoMusic,
	IcoPhotos,
	IcoFolder,
	IcoComputer,
	IcoCDROM,
	IcoDrive,	
};

uint32_t Icons2[] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF7FFFFFF, 0xFFF56264, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000FFFF, 0x0E000000, 0xFFFFFF93, 0xFFFFFFFF, 0xFFFFFFFF, 0xC3FFFFFF, 0x04042368, 0xFFB86421, 0xFFFFFFFF, 0xFFFFFFFF, 0x000000FF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x5487BCEF, 0xFFFF1821, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xBFFFFFFF, 0x06062568, 0xFFBF6825, 0xFFFFFFFF, 0xFFFFFFFF, 0x43B0FFFF, 0x31313131, 0x31313131, 0xB0413131, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x62A4F8FF, 0xA8664D45, 0xFFFFFFF8, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x180089FF, 0xFFFFFFF5, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x31DEFFFF, 0xDD2F0000, 0xFF0000FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x9800FFFF, 0x02319498, 0xFFFF8029, 0xFFFFFFFF, 0xFFFFFFFF, 0x0445DFFF, 0x1616120C, 0x3D040C14, 0xFFFFFFD5, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF, 0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x23568CCF, 0x00000000,
0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0060FFFF, 0x88000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x4141D9FF, 0xB2B2A483, 0x414180A4, 0xFFFFFFD7, 0xFFFFFFFF, 0xBA35F6FF, 0xD9D9D9D9, 0xD9D9D9D9, 0x35BAD9D9, 0xFFFFFFF3, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x5E1F0E92, 0x2C4D4D76, 0xFFFF900F, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000D4FF, 0xFFFFFF7C, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0010B5FF, 0x0E000000, 0xFF0000B4, 0xFFFFFFFF, 0x1DC3FFFF, 0x00000000, 0x00000000, 0x00000000, 0xC11A0000, 0xFFFFFFFF, 0xFEFEFFFF, 0x9800FFFF, 0x00969898, 0xFF7E1AE3, 0xFFFFFFFF, 0xFFFFFFFF, 0x160C10C9, 0x16161616, 0x0C161616, 0xFFFFBC09,
0xFFFFFFFF, 0x000000FF, 0xCFCFCFCF, 0xCFCFCFCF, 0x0000CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xE500FFFF, 0x00CBE5E5, 0xFFFFFF98, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xC9900CC5, 0xB4B4B4C5, 0x78B4B4B4, 0xFFFFC30B, 0xFFFFFFFF, 0xD937D3FF, 0x1212127C, 0xD5701212, 0x37D9BAB2, 0xFFFFFFD3, 0x087EFFFF, 0x00000000, 0x00000000, 0x00000000, 0x7E080000, 0xFFFFFFFF, 0x3FF3FFFF, 0x94C15A16, 0x73C17070, 0xF442285B, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x006899A9, 0xFFFFE006, 0xFFFFFFFF, 0xFFFFFFFF, 0xFDFFFFFF, 0x0E000080, 0x000EABAB, 0xFF000000, 0xFFFFFFFF, 0xC321FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x1FC1FFFF, 0xFFFFFFFF,
0x000000FF, 0x47000000, 0x00989898, 0x7E18D6FF, 0xFFFFFFFF, 0xDFFFFFFF, 0x16160E12, 0x00000008, 0x16160800, 0xFFD7090E, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF, 0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0x0200F3FF, 0x0014BCFF, 0x14000000, 0xFFFFFFBE, 0xFFFFFFFF, 0xE500FFFF, 0xBAE5E5E5, 0x00000060, 0x00000000, 0x64000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xD9FFFFFF, 0xE7FFAC0E, 0xB4B4B6C3, 0xB4B4B4B4, 0xFFD70D81, 0xFFFFFFFF, 0xD943C3FF, 0xD9D9D9D9, 0xA2CBD9D9, 0x43D9B2C7, 0xFFFFFFBF, 0xCD0AFFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x0ACDCDCD, 0xFFFFFFFF, 0x2339FCFF, 0x6A92AA68, 0x6BBA6B6B, 0x3C249298, 0xFFFFFFFE, 0xFFFFFFFF, 0xDCFFFFFF, 0x0E9D0004, 0xFFFF5800, 0xFFFFFFFF, 0xFFFFFFFF, 0x49ECFFFF,
0xD22D0000, 0x2BD1F2F2, 0xEB000000, 0xFFFFFFFF, 0x0800FFFF, 0x08080808, 0x08080808, 0x06060606, 0x00060606, 0xFFFFFFFF, 0xE3E300FF, 0x04025CD9, 0x0098983D, 0x25DDFFFF, 0xFFFFFF8C, 0x45FFFFFF, 0x1616160A, 0xFFFFFF00, 0x161600FF, 0xFF340B16, 0xFFFFFFFF, 0x000000FF, 0xCFCFCFCF, 0xCFCFCFCF, 0x0000CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x62270000, 0xFFFF007E, 0xFFFFFFFF, 0xFFFFFFFF, 0x66431FCF, 0x43666666, 0xFFFFD723, 0xFFFFFFFF, 0xE500FFFF, 0xE5E5E5E5, 0xE5E5E5E5, 0xE5E5E5E5, 0x00E5E5E5, 0xFFFFFFFF, 0x020274FF, 0x02020202, 0x02020202, 0x02020202, 0xFFFFFF74, 0x39FFFFFF, 0xFFFFFF8A, 0x76769CD5, 0xB2B4B494, 0xFF3877B2, 0xFFFFFFFF, 0xD954A8FF, 0xAAC3DBD9, 0xC7989E9E, 0x54D9AAF3, 0xFFFFFFAA, 0xCD00FFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x00CDCDCD, 0xFFFFFFFF, 0x641691FF, 0x6666B47A,
0x9CB66C66, 0x176365A6, 0xFFFFFF94, 0xFFFFFFFF, 0xA5FFFFFF, 0x8DEE1F7E, 0xFFC80000, 0xFFFFFFFF, 0xFFFFFFFF, 0x001FCCFF, 0x91EC5C00, 0xEB854343, 0x1D00005A, 0xFFFFFFCB, 0x9800FFFF, 0x97979798, 0x97979797, 0x96969696, 0x00969696, 0xFFFFFFFF, 0xE3E300FF, 0x8700DDE3, 0x00982502, 0x02000000, 0xFFFFFF0C, 0x02CDFFFF, 0x16161616, 0xFFFFFF00, 0x161600FF, 0xB8031616, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF, 0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x763B0400, 0xFFFFEBB0, 0xFFFF00FF, 0xFFFFFFFF, 0x00000035, 0x2D583D12, 0x582D1212, 0x00000E39, 0xFFFF3D00, 0x1000FFFF, 0x00000000, 0x00000000, 0x00000000, 0x00100000, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xCDD1D1D1, 0xFFFFFF04, 0x41BCFFFF, 0xF6FCDBC9, 0x8A8A6074, 0xB2AE5A5E, 0xBA40B2B2, 0xFFFFFFFF, 0xD96698FF, 0xDBB2AAD5, 0xF3E5EDED,
0x66D9A6F3, 0xFFFFFF94, 0xCD00FFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x00CDCDCD, 0xFFFFFFFF, 0x604F10FB, 0x606068B4, 0x96FCD160, 0x92A66E60, 0xFFFFF611, 0xFFFFFFFF, 0x0AF7FFFF, 0xFDFFDE1F, 0xFF6A002F, 0xFFFFFFFF, 0xFFFFFFFF, 0x0400069B, 0x43F2F291, 0xF133DEDE, 0x00028EF1, 0xFFFF9C04, 0xA000FFFF, 0x97979798, 0x97979797, 0x96969696, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0xFE00E3E3, 0x98250AC5, 0x2D949898, 0xFFFFFF00, 0x0C74FFFF, 0x16161616, 0xFFFFFF00, 0x161600FF, 0x620C1616, 0xFFFFFFFF, 0x000000FF, 0xCFCFCFCF, 0xCFCFCFCF, 0x0000CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE700, 0xFFFFFFFF, 0xFFFF00FF, 0xFFFFFFFF, 0x66666600, 0x8C143966, 0x148CCFCD, 0x122F5239, 0xFFFF005E, 0x9C00FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x009CB2B2, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xD1D1D1D1,
0xFFFFFF02, 0x8366FFFF, 0x70C9BABA, 0xE7E7E794, 0xB25990E7, 0x6581B2B2, 0xFFFFFFFF, 0xD9767EFF, 0xCDF3BFB6, 0xF3CD8585, 0x76D99AF1, 0xFFFFFF7C, 0xCD00FFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x00CDCDCD, 0xFFFFFFFF, 0xC9B125AC, 0x8C6060E5, 0x60DBC5B8, 0x5868A4AC, 0xFFFFA61B, 0xFFFFFFFF, 0x0082FFFF, 0xFFFFFF31, 0xE30000E1, 0xFFFFFFFF, 0xFFFFFFFF, 0xC20E0068, 0x43F2F2F2, 0xF133FFFF, 0x0AC1F1F1, 0xFFFF6600, 0xA000FFFF, 0x97979798, 0x97979797, 0x96969696, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0xFE00E3E3, 0x2B0EC9FE, 0x92969898, 0xFFFFFF00, 0x1231FFFF, 0x16161616, 0xFFFFFF00, 0x161600FF, 0x1F141616, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF, 0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFF00FF, 0xFFFFFFFF, 0x66666600, 0x62DB1F49, 0xD7620A0A, 0x12314721, 0xFFFF005E,
0xB200FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x00B2B2B2, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xD1D1D1D1, 0xFFFFFF02, 0xA823FFFF, 0x5E94B4B4, 0x5E5EBFE7, 0x925FE7BF, 0x22A6B2B2, 0xFFFFFFFF, 0xD98C68FF, 0x6CF3EDA0, 0xF370D1D5, 0x8CD9A0ED, 0xFFFFFF68, 0xCD00FFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x00CDCDCD, 0xFFFFFFFF, 0xFF622B66, 0x7EA2B6FF, 0xBCC35254, 0x5252526C, 0xFFFF642B, 0x0818FFFF, 0x0000E231, 0x0A0A23D8, 0x35006A7E, 0x166A78B0, 0xFFFFFFFF, 0xF2007AFE, 0x43F2F2F2, 0xF1334747, 0x00F1F1F1, 0xFFFFFE78, 0xA000FFFF, 0x97979798, 0x97979797, 0x96969696, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0x0000E3E3, 0x00060000, 0x96969898, 0xFFFFFF00, 0x1414FFFF, 0x00081216, 0xFFFFFF00, 0x080000FF, 0x04161612, 0xFFFFFFFF, 0x000000FF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFF00, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFF00FF, 0xFFFFFFFF, 0x66666600, 0x394BAE1F, 0x4B396060, 0x5E521DB0, 0xFFFF0066, 0xB200FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x00B2B2B2, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xD1D1D1D1, 0xFFFFFF02, 0xB206FFFF, 0x8A76B4B4, 0xF6F65EE7, 0x7588E75E, 0x05B0B2B2, 0xFFFFFFFF, 0xD99E52FF, 0xAAF3EDA0, 0xF3A86E6E, 0x9CD9A0ED, 0xFFFFFF50, 0xCD00FFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x00CDCDCD, 0xFFFFFFFF, 0xB8492F4D, 0x49494994, 0xA8FF7E49, 0x49494949, 0xFFFF4531, 0x0000FFFF, 0x640043AB, 0x00000064, 0x0002CD00, 0x0008A8C1, 0xFFFFFFFF, 0xF200FFFF, 0xE2F2F2F2, 0xF1DFD2D2, 0x00F1F1F1, 0xFFFFFFFF, 0xA000FFFF, 0x97979798, 0x97979797, 0x96969696, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0xE3E3E3E3, 0x005ADDE3, 0x96969898, 0xFFFFFF00, 0x141AFFFF, 0xFF980816,
0xFFFFFFFF, 0x98FFFFFF, 0x04161608, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF, 0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFF00FF, 0xFFFFFFFF, 0x64666600, 0x660ADF00, 0x0A666666, 0x666402DF, 0xFFFF0066, 0xB200FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x00B2B2B2, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xD1D1D1D1, 0xFFFFFF02, 0xAC0CFFFF, 0x8A76B4B4, 0xF6F65EE7, 0x7588E55E, 0x05B2B2B2, 0xFFFFFFFF, 0xD9AC39FF, 0xF3F6C3B6, 0xF6F3EDED, 0xAED9B6C3, 0xFFFFFF39, 0xCD00FFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x00CDCDCD, 0xFFFFFFFF, 0xA8413F49, 0x41414141, 0x83C98841, 0x41414141, 0xFFFF452B, 0x4308FFFF, 0xD20200C6, 0x0A0A0A0A, 0x8AB25A00, 0x1808C383, 0xFFFFFFFF, 0xF200FFFF, 0xF2F2F2F2, 0xF1F1F2F2, 0x00F1F1F1, 0xFFFFFFFF, 0xA000FFFF, 0x97979798, 0x97979797,
0x96969696, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0xE3E3E3E3, 0x00D9E3E3, 0x96969898, 0xFFFFFF00, 0x1235FFFF, 0xBC001216, 0xFFFFFFFF, 0x02BCFFFF, 0x21141612, 0xFFFFFFFF, 0x000000FF, 0xCFCFCFCF, 0xCFCFCFCF, 0x0000CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFF00FF, 0xFFFFFFFF, 0x64666600, 0x660CDD04, 0x0C666666, 0x666204DD, 0xFFFF0066, 0xB200FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x00B2B2B2, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xD1D1D1D1, 0xFFFFFF02, 0xA227FFFF, 0x6094B4B4, 0x605EBFE7, 0x925FE5BF, 0x21A8B2B2, 0xFFFFFFFF, 0xD9C123FF, 0xE5BAAAD5, 0xBAE3F8FA, 0xC1D9D5AA, 0xFFFFFF23, 0xCD00FFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x00CDCDCD, 0xFFFFFFFF, 0xA8435A5E, 0x3B3B3B3B, 0xB43FA83B, 0x3B3B3B3D, 0xFFFF702B, 0xF9FFFFFF, 0xFF9F0012, 0xFFFFFFFF, 0x47FFFFFF,
0xFFFF7E00, 0xFFFFFFFF, 0xF200FFFF, 0x00F2F2F2, 0xF1000000, 0x00F1F1F1, 0xFFFFFFFF, 0xA000FFFF, 0x97979798, 0x97979797, 0x96969696, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0xE3E3E3E3, 0x00DDE3E3, 0x9696989A, 0xFFFFFF00, 0x0C6CFFFF, 0x0C0E1616, 0xFFFFFFDB, 0x0E0EDBFF, 0x640C1616, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF, 0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFF00F5, 0xFFFFFFFF, 0x66666600, 0x392DC716, 0x2D396666, 0x666614C9, 0xFFFF0066, 0xB200FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x00B2B2B2, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xD1D1D1D1, 0xFFFFFF02, 0x885EFFFF, 0x5AB4B4B4, 0xE7E7E790, 0xC76F92E5, 0x5C85B8B8, 0xFFFFFFFF, 0xD9D30AFF, 0xAAC3DBD9, 0xC3AA9E9E, 0xD5D9D9DB, 0xFFFFFF08, 0xCD0AFFFF, 0xCDCDCDCD, 0xCDCDCDCD, 0xCDCDCDCD, 0x0ACDCDCD,
0xFFFFFFFF, 0xE1A814AC, 0x33333388, 0x56337C54, 0x70416EA2, 0xFFFFA62B, 0x51FFFFFF, 0xFFFB1200, 0xFFFFFFFF, 0xCBFFFFFF, 0xFFDBB03F, 0xFFFFFFFF, 0xF200FFFF, 0x00F2F2F2, 0xF1000000, 0x00F1F1F1, 0xFFFFFFFF, 0xA000FFFF, 0x4B4B9798, 0x4B4B4B4B, 0x49494949, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0xE3E3E3E3, 0x00DDE3E3, 0x9696989A, 0xFFFFFF00, 0x02C7FFFF, 0x0C161616, 0xFFFFF323, 0x160C23F3, 0xB9041616, 0xFFFFFFFF, 0x000000FF, 0xCFCFCFCF, 0xCFCFCFCF, 0x0000CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0xFAFFFFFF, 0xFFFFFF00, 0x8EDDFFFF, 0xFFFF0035, 0xFFFFFFFF, 0x66666600, 0x2FD93741, 0xD92F0E0E, 0x66663F39, 0xFFFF0066, 0xB002FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x00B0B2B2, 0xFFFFFFFF, 0xD1D102FF, 0xD1D1D1D1, 0xD1D1D1D1, 0xD1D1D1D1, 0xFFFFFF02, 0x43BAFFFF, 0xAEB4B4B4, 0x888A5E5A, 0xFAF4735F, 0xB841C7D9, 0xFFFFFFFF,
0xD18C2FFF, 0xD9D9D9D9, 0xD9D9D9D9, 0x8ED1D9D9, 0xFFFFFF2F, 0x087EFFFF, 0x00000000, 0x00000000, 0x00000000, 0x7C080000, 0xFFFFFFFF, 0xFF720CFC, 0x2B2B49ED, 0x2B2B458E, 0x62EDFF9A, 0xFFFFF80C, 0x76F0FFFF, 0xFFFF9702, 0xFFFFFFFF, 0xFFFFFFFF, 0xE50C0094, 0xFFFFFFFF, 0xF200FFFF, 0x00F2F2F2, 0xF1006A00, 0x00F1F1F1, 0xFFFFFFFF, 0xA000FFFF, 0xFF4B9798, 0xFFFF4BFF, 0x49FFFF4B, 0x009E9696, 0xFFFFFFFF, 0xE3E300FF, 0xE3E3E3E3, 0x00E3E3E3, 0x00000000, 0xFFFFFF00, 0x45FFFFFF, 0x1616160A, 0xFFFF410A, 0x16160A41, 0xFF350C16, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF, 0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0x398CDBFF, 0xFFFFFF00, 0x000085FF, 0xFFFF0000, 0xFFFFFFFF, 0x66666600, 0xBC353966, 0x35BCDBDB, 0x66666639, 0xFFFF0066, 0xB302FFFF, 0xB2B2B2B2, 0xB2B2B2B2, 0xB2B2B2B2, 0x00B2B2B2, 0xFFFFFFFF, 0x02020202,
0x02020202, 0x02020202, 0x02020202, 0xFFFF0202, 0x39FFFFFF, 0xB4B4B478, 0x757594B4, 0xFFFFD39A, 0xFF378CFF, 0xFFFFFFFF, 0x165000FF, 0x16161616, 0x16161616, 0x50161616, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x787878FF, 0xFFFFFF78, 0xFFFFFFFF, 0xFFFFFFFF, 0xA40A90FF, 0xAA947892, 0x9E98C9FF, 0x21BFFAAC, 0xFFFFFF96, 0x376EFFFF, 0xFFFFFEB7, 0xFFFFFFFF, 0xFFFFFFFF, 0x7C000083, 0xFFFFFFFF, 0xF300FFFF, 0x00F2F2F2, 0xF1005800, 0x00F1F1F1, 0xFFFFFFFF, 0x7421FFFF, 0xFF4B9798, 0xFFFF4BFF, 0x49FFFF4B, 0x1F749696, 0xFFFFFFFF, 0xE3E300FF, 0xE3E3E3E3, 0x00E3E3E3, 0xFEFEFFFE, 0xFFFFFFFF, 0xDFFFFFFF, 0x16160E12, 0x6A680816, 0x16161608, 0xFFD9080E, 0xFFFFFFFF, 0x000000FF, 0xCFCFCFCF, 0xCFCFCFCF, 0x0000CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0x0000008A, 0xFFFFFF00, 0x00000CFF, 0xFFFF0C00, 0xFFFFFFFF, 0x66666600, 0x18436666,
0x43180000, 0x66666666, 0xFFFF0066, 0x9902FFFF, 0x98989899, 0x98989898, 0x98989898, 0x00989898, 0xFFFFFFFF, 0x02020280, 0x02020202, 0x02020202, 0x02020202, 0xFFFF7F02, 0xD9FFFFFF, 0xB4B4830E, 0xB2B2B2B4, 0xFFE5C1B4, 0xFFD90CAA, 0xFFFFFFFF, 0x1D9800FF, 0x98989898, 0x984B984B, 0x9898984B, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x9E9E9ED3, 0xFFFFD39E, 0xFFFFFFFF, 0xFFFFFFFF, 0x0A3BFFFF, 0x2F1D1DA4, 0x1D1D50D1, 0x3F081D1D, 0xFFFFFFFF, 0x2129FFFF, 0xFFFFFFE2, 0xFFFFFFFF, 0xFFFFFFFF, 0x450039F1, 0xFFFFFFFF, 0xF300FFFF, 0x00F2F2F2, 0xF1000000, 0x00F1F1F1, 0xFFFFFFFF, 0x10C3FFFF, 0x00000000, 0x00000000, 0x00000000, 0xBE100000, 0xFFFFFFFF, 0xE3E300FF, 0xE3E3E3E3, 0x00E3E3E3, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x160C0EC9, 0x0C0C1616, 0x0C161616, 0xFFFFBE0A, 0xFFFFFFFF, 0x00FF00FF, 0xCFCFCFCF, 0xCFCFCFCF,
0xFF00CFCF, 0xFFFFFF00, 0xFFFFFFFF, 0x0000000C, 0xFFFFFF04, 0x00001AFF, 0xFFFF4D00, 0xFFFFFFFF, 0x00000045, 0x00000000, 0x00000000, 0x00000000, 0xFFFF4300, 0x0235FFFF, 0x00020202, 0x00000000, 0x00000000, 0x31000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xB4780CC5, 0xB2B2B2B2, 0x8CC7C3B2, 0xFFFFC30A, 0xFFFFFFFF, 0x1D9800FF, 0x98989898, 0x984B984B, 0x9800984B, 0xFFFFFF00, 0xFFFFFFFF, 0xFFFFFFFF, 0x64646464, 0xFFFF6464, 0xFFFFFFFF, 0xFFFFFFFF, 0x39F6FFFF, 0x1616391D, 0x16161694, 0xF63D0610, 0xFFFFFFFF, 0xE82BFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x665CFEFF, 0xFFFFFFFF, 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000000FF, 0x00000000, 0x00000000, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0x043DDDFF, 0x1616120C, 0x35040C14, 0xFFFFFFD5, 0xFFFFFFFF, 0x000000FF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFF00, 0xFFFFFFFF, 0x0000001F, 0xFFFFFF43, 0x181DB8FF, 0xFFFFED5C, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x4239D9FF, 0xACB0A481, 0x374180A0, 0xFFFFFFD7, 0xFFFFFFFF, 0x1D7810FF, 0x98989898, 0x984B984B, 0x7898984B, 0xFFFFFF10, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x080C1088, 0x08080C62, 0xFFFE880A, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xBEFFFFFF, 0x020A2766, 0xFFB6621F, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x6E2521B8, 0xFFFFFFF1, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xB8FFFFFF, 0x08022164, 0xFFB86427, 0xFFFFFFFF, 0xFFFFFFFF, 0x00028CFF, 0x00000000, 0x00000000, 0x02000000, 0xFFFFFF8C, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x62A8FAFF, 0xAC624349, 0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
};

LInlineBmp TreeIconsImg = { 308, 22, 8, Icons2 };


//////////////////////////////////////////////////////////////////////////
char *LFileType::DefaultExtension()
{
	char *Status = 0;
	auto T = LString(Extension()).SplitDelimit(";");
	if (T.Length())
	{
		char s[256];
		strcpy(s, T[0]);
		char *Dir = strchr(s, '.');
		if (Dir)
		{
			Status = NewStr(Dir+1);
			if (Status) strlwr(Status);
		}
	}
	return Status;
}

//////////////////////////////////////////////////////////////////////////
class LFolderItem : public LListItem
{
	LFileSelectDlg *Dlg;
	LString Path;

public:
	char *File;
	bool IsDir;

	LFolderItem(LFileSelectDlg *dlg, char *FullPath, LDirectory *Dir);
	~LFolderItem();

	void OnActivate();
	const char *GetText(int i);
	int GetImage(int Flags);
	void OnSelect();
	void OnDelete(bool Ask = true);
	void OnRename();
	void OnMouseClick(LMouse &m);
};


//////////////////////////////////////////////////////////////////////////
// This is just a private data container to make it easier to change the
// implementation of this class without effecting headers and applications.
class LFileSelectPrivate
{
	friend class LFileSelect;
	friend class LFileSelectDlg;
	friend class GFolderList;

	LView *Parent;
	LFileSelect *Select;

	DlgType Type;
	char *Title;
	char *DefExt;
	bool MultiSelect;
	List<char> Files;
	int CurrentType;
	List<LFileType> Types;
	List<char> History;
	bool ShowReadOnly;
	bool ReadOnly;
	
	bool EatClose;

public:
	static LImageList *BtnIcons, *TreeIcons;
	static char *InitPath;
	static bool InitShowHiddenFiles;
	static LRect InitSize;

	LFileSelectPrivate(LFileSelect *select)
	{
		ShowReadOnly = false;
		ReadOnly = false;
		EatClose = false;
		Select = select;
		Type = TypeNone;
		Title = 0;
		DefExt = 0;
		MultiSelect = false;
		Parent = 0;
		CurrentType = -1;

		if (!BtnIcons)
			BtnIcons = new LImageList(16, 16, FileSelectIcons.Create(0xF81F));
		if (!TreeIcons)
		{
			LAutoPtr<LSurface> a(TreeIconsImg.Create(0xF81F));
			LAutoPtr<LMemDC> m(new LMemDC(a->X(), a->Y(), System32BitColourSpace));
			if (a && m)
			{
				LColour fore(128, 128, 128);
				for (int y=0; y<a->Y(); y++)
				{
					uint8_t *i = (uint8_t*)(*a)[y];
					auto *e = i + a->X();
					System32BitPixel *o = (System32BitPixel*)(*m)[y];
					while (i < e)
					{
						o->r = (int)fore.r() * *i / 255;
						o->g = (int)fore.g() * *i / 255;
						o->b = (int)fore.b() * *i / 255;
						o->a = *i;
						i++;
						o++;
					}
				}
				
				TreeIcons = new LImageList(22, 22, m.Release());
			}
		}
	}

	virtual ~LFileSelectPrivate()
	{
		DeleteArray(Title);
		DeleteArray(DefExt);

		Types.DeleteObjects();
		Files.DeleteArrays();
		History.DeleteArrays();
	}
};

LImageList *LFileSelectPrivate::BtnIcons = NULL;
LImageList *LFileSelectPrivate::TreeIcons = NULL;
char *LFileSelectPrivate::InitPath = 0;
bool LFileSelectPrivate::InitShowHiddenFiles = false;
LRect LFileSelectPrivate::InitSize(0, 0, 600, 500);

//////////////////////////////////////////////////////////////////////////
// This class implements the UI for the selector.
class LFileSelectDlg;

class GFolderView
{
protected:
	LFileSelectDlg *Dlg;

public:
	GFolderView(LFileSelectDlg *dlg)
	{
		Dlg = dlg;
	}

	virtual void OnFolder() {}
};

class GFolderDrop : public LDropDown, public GFolderView
{
public:
	GFolderDrop(LFileSelectDlg *dlg, int Id, int x, int y, int cx, int cy);

	void OnFolder();

	bool OnLayout(LViewLayoutInfo &Inf)
	{
		Inf.Width.Min = 
			Inf.Width.Max = 18;
		return true;
	}
};

class GIconButton : public LLayout
{
	LImageList *Icons;
	int Icon;
	bool Down;

public:
	GIconButton(int Id, int x, int y, int cx, int cy, LImageList *icons, int icon)
	{
		Icons = icons;
		Icon = icon;
		SetId(Id);
		LRect r(x, y, x+cx, y+cy);
		SetPos(r);
		Down = false;
		SetTabStop(true);
	}

	void OnPaint(LSurface *pDC)
	{
		LRect c = GetClient();
		LColour Background(L_MED);
		c.Offset(-c.x1, -c.y1);
		LWideBorder(pDC, c, Down ? DefaultSunkenEdge : DefaultRaisedEdge);
		pDC->Colour(Background);
		pDC->Rectangle(&c);
		
		int x = (c.X()-Icons->TileX()) / 2;
		int y = (c.Y()-Icons->TileY()) / 2;

		if (Focus())
		{
			#if WINNATIVE
			RECT r = c;
			DrawFocusRect(pDC->Handle(), &r);
			#endif
		}

		Icons->Draw(pDC, c.x1+x+Down, c.y1+y+Down, Icon, Background, !Enabled());
	}

	void OnFocus(bool f)
	{
		Invalidate();
	}

	void OnMouseClick(LMouse &m)
	{
		if (Enabled())
		{
			bool Trigger = Down && !m.Down();

			Capture(Down = m.Down());
			if (Down) Focus(true);
			Invalidate();		

			if (Trigger)
			{
				LViewI *n=GetNotify()?GetNotify():GetParent();
				if (n)
					n->OnNotify(this, LNotification(m));
			}
		}
	}

	void OnMouseEnter(LMouse &m)
	{
		if (IsCapturing())
		{
			Down = true;
			Invalidate();
		}
	}

	void OnMouseExit(LMouse &m)
	{
		if (IsCapturing())
		{
			Down = false;
			Invalidate();
		}
	}

	bool OnKey(LKey &k)
	{
		if (k.c16 == ' ' || k.c16 == LK_RETURN)
		{
			if (Enabled() && Down ^ k.Down())
			{
				Down = k.Down();
				Invalidate();

				if (!Down)
				{
					LViewI *n=GetNotify()?GetNotify():GetParent();
					if (n) n->OnNotify(this, LNotifyActivate);
				}
			}
			
			return true;
		}
		
		return false;
	}
	
	bool OnLayout(LViewLayoutInfo &Inf)
	{
		Inf.Width.Min = Inf.Width.Max = Icons->TileX() + 4;
		Inf.Width.Max += 4;
		Inf.Height.Min = Inf.Height.Max = Icons->TileY() + 4;
		Inf.Height.Max += 4;
		return true;
	}
};

class GFolderList : public LList, public GFolderView
{
	LString FilterKey;

public:
	GFolderList(LFileSelectDlg *dlg, int Id, int x, int y, int cx, int cy);
	~GFolderList()
	{
	}	

	void OnFolder();
	bool OnKey(LKey &k);
	void SetFilterKey(LString s) { FilterKey = s; OnFolder(); }
};

#define IDC_STATIC					-1
#define IDD_FILE_SELECT				1000
#define IDC_PATH					1002
#define IDC_DROP					1003
#define IDC_BACK					1004
#define IDC_UP						1005
#define IDC_NEW						1006
#define IDC_VIEW					1007
#define IDC_FILE					1010
#define IDC_TYPE					1011
#define IDC_SHOWHIDDEN				1012
#define IDC_SUB_TBL					1013
#define IDC_BOOKMARKS				1014
#define IDC_FILTER					1015
#define IDC_FILTER_CLEAR			1016

#if 1
#define USE_FOLDER_CTRL				1

enum FolderCtrlMessages
{
	M_DELETE_EDIT				=	M_USER + 100,
	M_NOTIFY_VALUE_CHANGED,
	M_LOST_FOCUS,
};

class FolderCtrlEdit : public LEdit
{
public:
	FolderCtrlEdit(int id, LRect c) :
		LEdit(id, c.x1, c.y1, c.X()-1, c.Y()-1)
	{
	}

	void OnFocus(bool f)
	{
		printf("OnFocus(%i)\n", f);
		if (!f && GetParent())
			GetParent()->PostEvent(M_LOST_FOCUS);
	}
};

class FolderCtrl : public LView
{
	struct Part
	{
		LAutoPtr<LDisplayString> ds;
		LRect Arrow;
		LRect Text;
	};
	
	LEdit *e;
	LArray<Part> p;
	Part *Over;
	ssize_t Cursor;

	Part *HitPart(int x, int y, int *Sub = NULL)
	{
		for (unsigned i=0; i<p.Length(); i++)
		{
			if (p[i].Arrow.Overlap(x, y))
			{
				if (Sub) *Sub = 1;
				return p.AddressOf(i);
			}
			if (p[i].Text.Overlap(x, y))
			{
				if (Sub) *Sub = 0;
				return p.AddressOf(i);
			}
		}

		return NULL;
	}
	
public:
	FolderCtrl(int id)
	{
		e = NULL;
		Cursor = 0;
		SetId(id);
	}
	
	~FolderCtrl()
	{
	}
	
	const char *GetClass() { return "FolderCtrl"; }
	
	bool OnLayout(LViewLayoutInfo &Inf)
	{
		if (Inf.Width.Min == 0)
		{
			Inf.Width.Min = -1;
			Inf.Width.Max = -1;
		}
		else
		{
			Inf.Height.Min = GetFont()->GetHeight() + 4;
			Inf.Height.Max = Inf.Height.Min;
		}
		return true;
	}

	LString NameAt(ssize_t Level)
	{
		LString n;
		#ifndef WINDOWS
		n += "/";
		#endif
		for (unsigned i=0; i<=Level && i<p.Length(); i++)
		{
			n += (const char16*) *(p[i].ds.Get());
			n += DIR_STR;
		}

		return n;		
	}

	const char *Name()
	{
		LString n = NameAt(Cursor);
		LBase::Name(n);
		return LBase::Name();
	}
	
	bool Name(const char *n)
	{
		if (n && LView::Name() && !strcmp(n, LView::Name()))
			return true;

		bool b = LView::Name(n);
		
		Over = NULL;
		LString Nm(n);
		LString::Array a = Nm.SplitDelimit(DIR_STR);
		p.Length(0);
		for (size_t i=0; i<a.Length(); i++)
		{
			Part &n = p.New();
			n.ds.Reset(new LDisplayString(GetFont(), a[i]));
		}

		Cursor = p.Length() - 1;
		Invalidate();
		return b;
	}
	
	void OnPaint(LSurface *pDC)
	{
		LRect c = GetClient();
		LThinBorder(pDC, c, EdgeWin7Sunken);
		
		LFont *f = GetFont();
		f->Transparent(false);
		
		LDisplayString Arrow(f, ">");
		for (unsigned i=0; i<p.Length(); i++)
		{
			Part *n = p.AddressOf(i);
			LColour Fore(Cursor == i ? L_FOCUS_SEL_FORE : L_TEXT);
			LColour Bk(	Cursor == i
						?
						LColour(L_FOCUS_SEL_BACK)
						:
						(
							n == Over
							?
							GdcMixColour(LColour(L_FOCUS_SEL_BACK), LColour(L_WORKSPACE), 0.15f)
							:
							LColour(L_WORKSPACE)
						)
					);
			
			// Layout and draw arrow
			n->Arrow.ZOff(Arrow.X()+1, c.Y()-1);
			n->Arrow.Offset(c.x1, c.y1);
			f->Colour(LColour(192,192,192), Bk);
			Arrow.DrawCenter(pDC, &n->Arrow);
			c.x1 = n->Arrow.x2 + 1;

			if (n->ds)
			{
				// Layout and draw text
				n->Text.ZOff(n->ds->X() + 4, c.Y()-1);
				n->Text.Offset(c.x1, c.y1);
				f->Colour(Fore, Bk);
				n->ds->DrawCenter(pDC, &n->Text);
				c.x1 = n->Text.x2 + 1;
			}
		}
		if (p.Length() == 0)
		{
			// Layout and draw arrow for the "root folder"
			f->Colour(LColour(192,192,192), L_WORKSPACE);
			LRect a;
			a.ZOff(Arrow.X()+1, c.Y()-1);
			a.Offset(c.x1, c.y1);
			Arrow.DrawCenter(pDC, &a);
			c.x1 = a.x2 + 1;
		}
		
		pDC->Colour(L_WORKSPACE);
		pDC->Rectangle(&c);
	}
	
	void ExitEditMode()
	{
		if (e)
		{
			Name(e->Name());
			DeleteObj(e);

			PostEvent(M_DELETE_EDIT);
			PostEvent(M_NOTIFY_VALUE_CHANGED);
			
			Invalidate();
		}
	}

	void OnMouseClick(LMouse &m)
	{
		if (m.IsContextMenu())
		{
		}
		else if (m.Left())
		{
			if (m.Down())
			{
				Over = HitPart(m.x, m.y);
				if (p.PtrCheck(Over))
				{
					// Over a path node...
					Cursor = Over - p.AddressOf(0);
					Part &o = p[Cursor];
					Invalidate();
					SendNotify(LNotifyValueChanged);

					if (o.Arrow.Overlap(m.x, m.y))
					{
						// Show sub-menu at this level
						ShowMenu(Cursor);
					}
				}
				else if (!e)
				{
					// In empty space
					LRect c = GetClient();
					e = new FolderCtrlEdit(GetId()+1, c);
					if (e)
					{
						e->Attach(this);

						LString s = Name();
						e->Name(s);
						e->SetCaret(s.Length());
						e->Focus(true);
					}
				}
			}
		}
	}

	void OnMouseMove(LMouse &m)
	{
		Part *o = Over;
		Over = HitPart(m.x, m.y);
		if (o != Over)
			Invalidate();
	}
	
	void OnMouseExit(LMouse &m)
	{
		if (Over)
		{
			Over = NULL;
			Invalidate();
		}
	}

	int OnNotify(LViewI *c, LNotification n)
	{
		if (e != NULL &&
			c->GetId() == e->GetId())
		{
			if (n.Type == LNotifyReturnKey)
			{
				ExitEditMode();
			}
		}

		return 0;
	}

	LMessage::Result OnEvent(LMessage *m)
	{
		switch (m->Msg())
		{
			case M_LOST_FOCUS:
			{
				ExitEditMode();
				break;
			}
			case M_DELETE_EDIT:
			{
				DeleteObj(e);
				break;
			}
			case M_NOTIFY_VALUE_CHANGED:
			{
				SendNotify(LNotifyValueChanged);
				break;			
			}
		}

		return LView::OnEvent(m);
	}

	virtual bool ShowMenu(ssize_t Level)
	{
		if (Level <= 0)
			return false;

		LString dir = NameAt(Level-1);
		LSubMenu s;
		LDirectory d;

		LString::Array Opts;
		for (int b = d.First(dir); b; b = d.Next())
		{
			if (d.IsDir())
			{
				Opts.New() = d.GetName();
				s.AppendItem(d.GetName(), (int)Opts.Length());
			}
		}

		Part &i = p[Level];
		LPoint pt(i.Arrow.x1, i.Arrow.y2+1);
		PointToScreen(pt);
		int Cmd = s.Float(this, pt.x, pt.y, true);
		if (Cmd)
		{
			LString np;
			np = dir + DIR_STR + Opts[Cmd-1];
			Name(np);
			PostEvent(M_NOTIFY_VALUE_CHANGED);
		}
		else return false;

		return true;
	}
};

#else
#define USE_FOLDER_CTRL				0
#endif


class LFileSelectDlg :
	public LDialog
{
	LRect OldPos;
	LRect MinSize;
	LArray<LString> Links;
	LArray<LFolderItem*> Hidden;
	
public:
	LFileSelectPrivate *d;

	LTableLayout *Tbl;
	LBox *Sub;

	LTree *Bookmarks;
	LTextLabel *Ctrl1;

	#if USE_FOLDER_CTRL
	FolderCtrl *Ctrl2;
	#else
	LEdit *Ctrl2;
	#endif
	
	GFolderDrop *Ctrl3;
	GIconButton *BackBtn;
	GIconButton *UpBtn;
	GIconButton *NewDirBtn;
	GFolderList *FileLst;
	LTextLabel *Ctrl8;
	LTextLabel *Ctrl9;
	LEdit *FileNameEdit;
	LCombo *FileTypeCbo;
	LButton *SaveBtn;
	LButton *CancelBtn;
	LCheckBox *ShowHidden;
	LEdit *FilterEdit;

	LFileSelectDlg(LFileSelectPrivate *Select);
	~LFileSelectDlg();

	int OnNotify(LViewI *Ctrl, LNotification n);
	void OnUpFolder();
	void SetFolder(char *f);
	void OnFolder();
	void OnFile(char *f);
	void OnFilter(const char *Key);

	bool OnViewKey(LView *v, LKey &k)
	{
		if (k.vkey == LK_UP && k.Alt())
		{
			if (k.Down())
			{
				UpBtn->SendNotify();
			}
			
			return true;
		}

		return false;
	}
	
	void Add(LTreeItem *i, LVolume *v)
	{
		if (!i || !v)
			return;
		
		auto Path = v->Path();
		i->SetText(v->Name());
		i->SetText(Path, 1);
		
		for (unsigned n=0; n<Links.Length(); n++)
		{
			if (Path && !Stricmp(Path, Links[n].Get()))
			{
				Links.DeleteAt(n--);
				break;
			}
		}
		
		for (LVolume *cv = v->First(); cv; cv = cv->Next())
		{
			LTreeItem *ci = new LTreeItem;
			if (ci)
			{
				i->Insert(ci);
				Add(ci, cv);
			}
		}

		i->Expanded(true);
	}
};

LFileSelectDlg::LFileSelectDlg(LFileSelectPrivate *select)
{
	SaveBtn = NULL;
	BackBtn = NULL;
	CancelBtn = NULL;
	ShowHidden = NULL;
	FileTypeCbo = NULL;
	FileNameEdit = NULL;
	Ctrl8 = NULL;
	Ctrl9 = NULL;
	FileLst = NULL;
	Ctrl3 = NULL;
	BackBtn = NULL;
	UpBtn = NULL;
	NewDirBtn = NULL;
	Ctrl2 = NULL;
	Sub = NULL;
	Bookmarks = NULL;
	FilterEdit = NULL;

	d = select;
	SetParent(d->Parent);
	MinSize.ZOff(450, 300);
	OldPos.Set(0, 0, 475, 350 + LAppInst->GetMetric(LGI_MET_DECOR_Y) );
	SetPos(OldPos);

	int x = 0, y = 0;
	AddView(Tbl = new LTableLayout);

	// Top Row
	auto *c = Tbl->GetCell(x++, y);
	c->Add(Ctrl1 = new LTextLabel(IDC_STATIC, 0, 0, -1, -1, "Look in:"));
	c->VerticalAlign(LCss::Len(LCss::VerticalMiddle));
	c = Tbl->GetCell(x++, y);
	#if USE_FOLDER_CTRL
	c->Add(Ctrl2 = new FolderCtrl(IDC_PATH));
	#else
	c->Add(Ctrl2 = new LEdit(IDC_PATH, 0, 0, 245, 21, ""));
	#endif
	c = Tbl->GetCell(x++, y);
	c->Add(Ctrl3 = new GFolderDrop(this, IDC_DROP, 336, 7, 16, 21));
	c = Tbl->GetCell(x++, y);
	c->Add(BackBtn = new GIconButton(IDC_BACK, 378, 7, 27, 21, d->BtnIcons, FSI_BACK));
	c = Tbl->GetCell(x++, y);
	c->Add(UpBtn = new GIconButton(IDC_UP, 406, 7, 27, 21, d->BtnIcons, FSI_UPDIR));
	c = Tbl->GetCell(x++, y);
	c->Add(NewDirBtn = new GIconButton(IDC_NEW, 434, 7, 27, 21, d->BtnIcons, FSI_NEWDIR));

	// Folders/items row
	x = 0; y++;
	c = Tbl->GetCell(x, y, true, 6, 1);
	c->Add(Sub = new LBox(IDC_SUB_TBL));
	Sub->AddView(Bookmarks = new LTree(IDC_BOOKMARKS, 0, 0, -1, -1));
	Bookmarks->GetCss(true)->Width(LCss::Len(LCss::LenPx, 150.0f));
	Bookmarks->SetImageList(d->TreeIcons, false);
	
	LTableLayout *t;
	Sub->AddView(t = new LTableLayout(11));
	
	// Filter / search row
	c = t->GetCell(0, 0);
	c->Add(new LCheckBox(IDC_FILTER_CLEAR, 0, 0, -1, -1, "Filter items:"));
	c->VerticalAlign(LCss::Len(LCss::VerticalMiddle));
	c = t->GetCell(1, 0);
	c->Add(FilterEdit = new LEdit(IDC_FILTER, 0, 0, 60, 20));
	c = t->GetCell(0, 1, true, 2);
	c->Add(FileLst = new GFolderList(this, IDC_VIEW, 14, 35, 448, 226));
	
	// File name row
	x = 0; y++;
	c = Tbl->GetCell(x++, y);
	c->Add(Ctrl8 = new LTextLabel(IDC_STATIC, 14, 275, -1, -1, "File name:"));
	c = Tbl->GetCell(x, y, true, 2);
	x += 2;
	c->Add(FileNameEdit = new LEdit(IDC_FILE, 100, 268, 266, 21, ""));
	c = Tbl->GetCell(x, y, true, 3);
	c->Add(SaveBtn = new LButton(IDOK, 392, 268, 70, 21, "Ok"));

	// 4th row
	x = 0; y++;
	c = Tbl->GetCell(x++, y);
	c->Add(Ctrl9 = new LTextLabel(IDC_STATIC, 14, 303, -1, -1, "Files of type:"));
	c = Tbl->GetCell(x, y, true, 2);
	x += 2;
	c->Add(FileTypeCbo = new LCombo(IDC_TYPE, 100, 296, 266, 21, ""));
	c = Tbl->GetCell(x++, y, true, 3);
	c->Add(CancelBtn = new LButton(IDCANCEL, 392, 296, 70, 21, "Cancel"));

	// 5th row
	x = 0; y++;
	c = Tbl->GetCell(x++, y, true, 6);
	c->Add(ShowHidden = new LCheckBox(IDC_SHOWHIDDEN, 14, 326, -1, -1, "Show hidden files."));

	// Init
	if (BackBtn)
		BackBtn->Enabled(false);
	if (SaveBtn)
		SaveBtn->Enabled(false);
	if (FileLst)
		FileLst->MultiSelect(d->MultiSelect);
	if (ShowHidden)
		ShowHidden->Value(d->InitShowHiddenFiles);

	// Load types
	if (!d->Types.Length())
	{
		LFileType *t = new LFileType;
		if (t)
		{
			t->Description("All Files");
			t->Extension(LGI_ALL_FILES);
			d->Types.Insert(t);
		}
	}
	for (auto t: d->Types)
	{
		char s[256];
		sprintf(s, "%s (%s)", t->Description(), t->Extension());
		if (FileTypeCbo)
			FileTypeCbo->Insert(s);
	}
	d->CurrentType = 0;

	// File + Path
	char *File = d->Files[0];
	if (File)
	{
		char *Dir = strrchr(File, DIR_CHAR);
		if (Dir)
		{
			OnFile(Dir + 1);
		}
		else
		{
			OnFile(File);
		}
	}
	
	if (d->InitPath)
	{
		SetFolder(d->InitPath);
	}
	else
	{
		SetFolder(LGetExePath());
	}
	OnFolder();

	// Size/layout
	SetPos(d->InitSize);
	MoveToCenter();

	RegisterHook(this, LKeyEvents);
	FileLst->Focus(true);
	
	LgiGetUsersLinks(Links);

	auto v = FileDev->GetRootVolume();
	if (v)
	{
		for (auto vol = v; vol; vol = vol->Next())
		{
			if (auto *ti = new LTreeItem)
			{
				Bookmarks->Insert(ti);
				Add(ti, vol);
				ti->Expanded(true);
			}
		}
	}
	
	if (Links.Length())
	{
		if (auto *ti = new LTreeItem)
		{
			ti->SetText("Bookmarks");
			Bookmarks->Insert(ti);
			
			for (unsigned n=0; n<Links.Length(); n++)
			{
				LTreeItem *ci = new LTreeItem;
				if (ci)
				{
					char *p = Links[n];
					char *leaf = strrchr(p, DIR_CHAR);
					ci->SetText(leaf?leaf+1:p, 0);
					ci->SetText(p, 1);
					ti->Insert(ci);
				}
			}

			ti->Expanded(true);
		}
	}
}

LFileSelectDlg::~LFileSelectDlg()
{
	UnregisterHook(this);
	d->InitShowHiddenFiles = ShowHidden ? ShowHidden->Value() : false;
	d->InitSize = GetPos();

	auto CurPath = GetCtrlName(IDC_PATH);
	if (ValidStr(CurPath))
	{
		DeleteArray(d->InitPath);
		d->InitPath = NewStr(CurPath);
	}
}

void LFileSelectDlg::OnFile(char *f)
{
	if (d->Type != TypeOpenFolder)
	{
		FileNameEdit->Name(f ? f : (char*)"");
		SaveBtn->Enabled(ValidStr(f));
	}
}

void LFileSelectDlg::SetFolder(char *f)
{
	auto CurPath = GetCtrlName(IDC_PATH);
	if (CurPath)
	{
		d->History.Insert(NewStr(CurPath));
		SetCtrlEnabled(IDC_BACK, true);
	}
	
	SetCtrlName(IDC_PATH, f);
}

void LFileSelectDlg::OnFolder()
{
	if (Ctrl3)
		Ctrl3->OnFolder();
	if (FileLst)
		FileLst->OnFolder();

	auto CurPath = GetCtrlName(IDC_PATH);
	if (CurPath && UpBtn)
		UpBtn->Enabled(strlen(CurPath)>3);
}

void LFileSelectDlg::OnUpFolder()
{
	auto Cur = GetCtrlName(IDC_PATH);
	if (Cur)
	{
		char Dir[MAX_PATH];
		strcpy(Dir, Cur);
		if (strlen(Dir) > 3)
		{
			LTrimDir(Dir);

			if (!strchr(Dir, DIR_CHAR))
				strcat(Dir, DIR_STR);

			SetFolder(Dir);
			OnFolder();
		}
	}
}



void LFileSelectDlg::OnFilter(const char *Key)
{
	if (FileLst)
		FileLst->SetFilterKey(Key);
}

int LFileSelectDlg::OnNotify(LViewI *Ctrl, LNotification n)
{
	switch (Ctrl->GetId())
	{
		case IDC_BOOKMARKS:
		{
			if (n.Type == LNotifyItemSelect && Bookmarks)
			{
				LTreeItem *s = Bookmarks->Selection();
				if (s)
				{
					const char *p = s->GetText(1);
					if (LDirExists(p))
					{
						SetCtrlName(IDC_PATH, p);
						OnFolder();
					}
				}
			}
			break;
		}
		case IDC_PATH:
		{
			if (n.Type == LNotifyValueChanged)
				OnFolder();
			break;
		}
		case IDC_VIEW:
		{
			if (FileLst)
			{
				/*	These functions are handled by the list 
					control's OnKey implementation
					
				if (Flags == GLIST_NOTIFY_RETURN)
				{
					List<LListItem> s;
					if (FileLst->GetSelection(s))
					{
						LFolderItem *i = dynamic_cast<LFolderItem*>(s.First());
						if (i)
						{
							i->OnActivate();
						}
					}
				}
				else if (Flags == GLIST_NOTIFY_BACKSPACE)
				{
					OnUpFolder();
				}
				*/
			}
			break;
		}
		case IDC_FILE:
		{
			auto f = Ctrl->Name();
			if (!f)
				break;

			if (n.Type == LNotifyReturnKey)
			{
				// allow user to insert new type by typing the pattern into the file name edit box and
				// hitting enter
				if (strchr(f, '?') || strchr(f, '*'))
				{
					// it's a mask, push the new type on the the type stack and
					// refilter the content
					int TypeIndex = -1;
					
					int n = 0;
					for (auto t: d->Types)
					{
						if (t->Extension() &&
							stricmp(t->Extension(), f) == 0)
						{
							TypeIndex = n;
							break;
						}
						n++;
					}
					
					// insert the new type if not already there
					if (TypeIndex < 0)
					{
						LFileType *n = new LFileType;
						if (n)
						{
							n->Description(f);
							n->Extension(f);							
							TypeIndex = (int)d->Types.Length();
							d->Types.Insert(n);
							FileTypeCbo->Insert(f);
						}
					}
					
					// select the new type
					if (TypeIndex >= 0)
					{
						FileTypeCbo->Value(d->CurrentType = TypeIndex);
					}
					
					// clear the edit box
					Ctrl->Name("");
					
					// Update and don't do normal save btn processing.
					OnFolder();
					
					// Skip the IDOK message generated by the default button
					d->EatClose = true;
					printf("%s:%i - eat close true\n", _FL);
					break;
				}
				
				if (LDirExists(f))
				{
					// Switch to the folder...
					SetCtrlName(IDC_PATH, f);
					OnFolder();
					Ctrl->Name(NULL);
					d->EatClose = true;
				}
				else if (LFileExists(f))
				{
					// Select the file...
					d->Files.Insert(NewStr(f));
					EndModal(IDOK);
					break;
				}
			}
			
			bool HasFile = ValidStr(f);
			bool BtnEnabled = SaveBtn->Enabled();
			if (HasFile ^ BtnEnabled)
			{
				SaveBtn->Enabled(HasFile);
			}
			break;
		}
		case IDC_BACK:
		{
			auto It = d->History.rbegin();
			char *Dir = *It;
			if (Dir)
			{
				d->History.Delete(Dir);
				SetCtrlName(IDC_PATH, Dir);
				OnFolder();
				DeleteArray(Dir);

				if (!d->History[0])
				{
					SetCtrlEnabled(IDC_BACK, false);
				}
			}
			break;
		}
		case IDC_SHOWHIDDEN:
		{
			FileLst->OnFolder();
			break;
		}
		case IDC_TYPE:
		{
			d->CurrentType = (int)FileTypeCbo->Value();
			FileLst->OnFolder();

			if (d->Type == TypeSaveFile)
			{
				// change extension of current file
				LFileType *Type = d->Types.ItemAt(d->CurrentType);
				auto File = FileNameEdit->Name();
				if (Type && File)
				{
					char *Ext = strchr(File, '.');
					if (Ext)
					{
						char *DefExt = Type->DefaultExtension();
						if (DefExt)
						{
							Ext++;
							char s[256];
							ZeroObj(s);
							memcpy(s, File, Ext-File);
							strcat(s, DefExt);

							OnFile(s);

							DeleteArray(DefExt);
						}
					}
				}
			}
			break;
		}
		case IDC_UP:
		{
			OnUpFolder();
			break;
		}
		case IDC_FILTER:
		{
			const char *n = Ctrl->Name();
			SetCtrlValue(IDC_FILTER_CLEAR, ValidStr(n));
			OnFilter(n);
			break;
		}
		case IDC_FILTER_CLEAR:
		{
			if (!Ctrl->Value())
			{
				SetCtrlName(IDC_FILTER, NULL);
				OnFilter(NULL);
			}
			break;
		}
		case IDC_NEW:
		{
			LInput Dlg(this, "", "Create new folder:", "New Folder");
			if (Dlg.DoModal())
			{
				char New[256];
				strcpy(New, GetCtrlName(IDC_PATH));
				if (New[strlen(New)-1] != DIR_CHAR) strcat(New, DIR_STR);
				strcat(New, Dlg.GetStr());

				FileDev->CreateFolder(New);
				OnFolder();
			}
			break;
		}
		case IDOK:
		{
			if (d->EatClose)
			{
				printf("%s:%i - SKIPPING eat close false\n", _FL);
				d->EatClose = false;
				break;
			}
			
			auto Path = GetCtrlName(IDC_PATH);
			auto File = GetCtrlName(IDC_FILE);
			if (Path)
			{
				char f[MAX_PATH];
				d->Files.DeleteArrays();

				if (d->Type == TypeOpenFolder)
				{
					d->Files.Insert(NewStr(Path));
				}
				else
				{
					List<LListItem> Sel;
					if (d->Type != TypeSaveFile &&
						FileLst &&
						FileLst->GetSelection(Sel) &&
						Sel.Length() > 1)
					{
						for (auto i: Sel)
						{
							LMakePath(f, sizeof(f), Path, i->GetText(0));
							d->Files.Insert(NewStr(f));
						}
					}
					else if (ValidStr(File))
					{
						if (strchr(File, DIR_CHAR))
							strcpy_s(f, sizeof(f), File);
						else
							LMakePath(f, sizeof(f), Path, File);
						d->Files.Insert(NewStr(f));
					}
				}
			}

			// fall thru
		}
		case IDCANCEL:
		{
			EndModal(Ctrl->GetId());
			break;
		}
	}

	return 0;
}

//////////////////////////////////////////////////////////////////////////
class GFileSystemItem : public LTreeItem
{
	class GFileSystemPopup *Popup;
	LString Path;

public:
	GFileSystemItem(GFileSystemPopup *popup, LVolume *vol, char *path = 0);

	char *GetPath()
	{
		return Path;
	}

	void OnPath(const char *p);
	void OnMouseClick(LMouse &m);
	bool OnKey(LKey &k);
};

#define IDC_TREE 100
class GFileSystemPopup : public LPopup
{
	friend class GFileSystemItem;

	LFileSelectDlg *Dlg;
	LTree *Tree;
	GFileSystemItem *Root;

public:
	GFileSystemPopup(LView *owner, LFileSelectDlg *dlg, int x) : LPopup(owner)
	{
		Dlg = dlg;
		LRect r(0, 0, x, 150);
		SetPos(r);
		Children.Insert(Tree = new LTree(IDC_TREE, 1, 1, X()-3, Y()-3));
		if (Tree)
		{
			Tree->Sunken(false);

			LVolume *v = FileDev->GetRootVolume();
			if (v)
			{
				Tree->SetImageList(Dlg->d->BtnIcons, false);
				Tree->Insert(Root = new GFileSystemItem(this, v));
				
				for (auto next = v->Next(); next; next = next->Next())
				{
					Tree->SetImageList(Dlg->d->BtnIcons, false);
					Tree->Insert(Root = new GFileSystemItem(this, next));
				}
			}
		}
	}

	~GFileSystemPopup()
	{
	}

	void Visible(bool i)
	{
		if (i && Root)
		{
			Root->OnPath(Dlg->GetCtrlName(IDC_PATH));
		}

		LPopup::Visible(i);
	}

	void OnPaint(LSurface *pDC)
	{
		// Draw border
		LRect c = GetClient();
		c.Offset(-c.x1, -c.y1);
		pDC->Colour(L_BLACK);
		pDC->Box(&c);
		c.Inset(1, 1);
	}

	void OnActivate(GFileSystemItem *i)
	{
		if (i)
		{
			Dlg->SetFolder(i->GetPath());
			Dlg->OnFolder();
			Visible(false);
		}
	}
};

GFileSystemItem::GFileSystemItem(GFileSystemPopup *popup, LVolume *Vol, char *path)
{
	Popup = popup;
	Expanded(true);

	if (Vol)
	{
		Path = Vol->Path();
		SetText(Vol->Name());
		
		switch (Vol->Type())
		{
			case VT_FLOPPY:
				SetImage(FSI_FLOPPY);
				break;
			case VT_HARDDISK:
			case VT_RAMDISK:
				SetImage(FSI_HARDDISK);
				break;
			case VT_CDROM:
				SetImage(FSI_CDROM);
				break;
			case VT_NETWORK_SHARE:
				SetImage(FSI_NETWORK);
				break;
			case VT_DESKTOP:
				SetImage(FSI_DESKTOP);
				break;
			default:
				SetImage(FSI_DIRECTORY);
				break;
		}

		for (LVolume *v=Vol->First(); v; v=v->Next())
		{
			Insert(new GFileSystemItem(Popup, v));
		}
	}
	else
	{
		Path = NewStr(path);
		SetText(strrchr(Path, DIR_CHAR)+1);
		SetImage(FSI_DIRECTORY);
	}
}

void GFileSystemItem::OnPath(const char *p)
{
	switch (GetImage())
	{
		case FSI_DESKTOP:
		{
			if (p &&
				Path &&
				stricmp(Path, p) == 0)
			{
				Select(true);
				p = 0;
			}
			break;
		}
		case FSI_DIRECTORY:
		{
			return;
		}
		default:
		{
			LTreeItem *Old = Items[0];
			if (Old)
			{
				Old->Remove();
				DeleteObj(Old);
			}
			break;
		}
	}

	if (p)
	{
		auto PathLen = strlen(Path);
		if (Path &&
			strnicmp(Path, p, PathLen) == 0 &&
			(p[PathLen] == DIR_CHAR || p[PathLen] == 0)
			#ifdef LINUX
			&& strcmp(Path, "/") != 0
			#endif
			)
		{
			LTreeItem *Item = this;

			if (GetImage() != FSI_DESKTOP &&
				strlen(p) > 3)
			{
				auto Start = p + strlen(Path);
				if (Start)
				{
					char s[256];
					strcpy(s, Path);

					auto T = LString(Start).SplitDelimit(DIR_STR);
					for (int i=0; i<T.Length(); i++)
					{
						if (s[strlen(s)-1] != DIR_CHAR) strcat(s, DIR_STR);
						strcat(s, T[i]);

						GFileSystemItem *New = new GFileSystemItem(Popup, 0, s);
						if (New)
						{
							Item->Insert(New);
							Item = New;
						}
					}
				}
			}

			if (Item)
			{
				Item->Select(true);
			}
		}
	}

	for (auto item: Items)
	{
		GFileSystemItem *i = dynamic_cast<GFileSystemItem*>(item);
		if (i)
			i->OnPath(p);
	}
}

void GFileSystemItem::OnMouseClick(LMouse &m)
{
	if (m.Left() && m.Down())
	{
		Popup->OnActivate(this);
	}
}

bool GFileSystemItem::OnKey(LKey &k)
{
	if ((k.c16 == ' ' || k.c16 == LK_RETURN))
	{
		if (k.Down() && k.IsChar)
		{
			Popup->OnActivate(this);
		}
		
		return true;
	}
	
	return false;
}

GFolderDrop::GFolderDrop(LFileSelectDlg *dlg, int Id, int x, int y, int cx, int cy) :
	LDropDown(Id, x, y, cx, cy, 0),
	GFolderView(dlg)
{
	SetPopup(new GFileSystemPopup(this, dlg, cx + (dlg->Ctrl2 ? dlg->Ctrl2->X() : 0) ));
}

void GFolderDrop::OnFolder()
{
}

//////////////////////////////////////////////////////////////////////////
#define IDM_OPEN				1000
#define IDM_CUT					1001
#define IDM_COPY				1002
#define IDM_RENAME				1003
#define IDM_PROPERTIES			1004
#define IDM_CREATE_SHORTCUT		1005
#define IDM_DELETE				1006

LFolderItem::LFolderItem(LFileSelectDlg *dlg, char *FullPath, LDirectory *Dir)
{
	Dlg = dlg;
	Path = FullPath;
	File = strrchr(Path, DIR_CHAR);
	if (File) File++;
	IsDir = Dir->IsDir();
}

LFolderItem::~LFolderItem()
{
}

const char *LFolderItem::GetText(int i)
{
	return File;
}

int LFolderItem::GetImage(int Flags)
{
	return IsDir ? 1 : 0;
}

void LFolderItem::OnSelect()
{
	if (!IsDir && File)
	{
		Dlg->OnFile(Select() ? File : 0);
	}
}

void LFolderItem::OnDelete(bool Ask)
{
	if (!Ask || LgiMsg(Parent, "Do you want to delete '%s'?", ModuleName, MB_YESNO, Path.Get()) == IDYES)
	{
		bool Status = false;

		if (IsDir)
		{
			Status = FileDev->RemoveFolder(Path, true);
		}
		else
		{
			Status = FileDev->Delete(Path);
		}

		if (Status)
		{
			Parent->Remove(this);
			delete this;
		}
	}
}

void LFolderItem::OnRename()
{
	LInput Inp(Dlg, File, "New name:", Dlg->Name());
	if (Inp.DoModal())
	{
		char Old[256];
		strcpy(Old, Path);

		char New[256];
		File[0] = 0;
		LMakePath(New, sizeof(New), Path, Inp.GetStr());
		
		if (FileDev->Move(Old, New))
		{
			DeleteArray(Path);
			Path = NewStr(New);
			File = strrchr(Path, DIR_CHAR);
			if (File) File++;
			Update();
		}
		else
		{
			LgiMsg(Dlg, "Renaming '%s' failed.", Dlg->Name(), MB_OK);
		}
	}
}

void LFolderItem::OnActivate()
{
	if (File)
	{
		if (IsDir)
		{
			char Dir[256];
			strcpy(Dir, Dlg->GetCtrlName(IDC_PATH));
			if (Dir[strlen(Dir)-1] != DIR_CHAR) strcat(Dir, DIR_STR);
			strcat(Dir, File);
			Dlg->SetFolder(Dir);
			Dlg->OnFolder();
		}
		else // Is file
		{
			Dlg->OnNotify(Dlg->SaveBtn, LNotifyActivate);
		}
	}
}

void LFolderItem::OnMouseClick(LMouse &m)
{
	if (m.Down())
	{
		if (m.Left())
		{
			if (m.Double())
			{
				OnActivate();
			}
		}
		else if (m.Right())
		{
			LSubMenu *RClick = new LSubMenu;
			if (RClick)
			{
				RClick->AppendItem("Select", IDM_OPEN, true);
				RClick->AppendSeparator();
				RClick->AppendItem("Cut", IDM_CUT, false);
				RClick->AppendItem("Copy", IDM_COPY, false);
				RClick->AppendSeparator();
				RClick->AppendItem("Create Shortcut", IDM_CREATE_SHORTCUT, false);
				RClick->AppendItem("Delete", IDM_DELETE, true);
				RClick->AppendItem("Rename", IDM_RENAME, true);
				RClick->AppendSeparator();
				RClick->AppendItem("Properties", IDM_PROPERTIES, false);

				if (Parent->GetMouse(m, true))
				{
					switch (RClick->Float(Parent, m.x, m.y))
					{
						case IDM_OPEN:
						{
							break;
						}
						case IDM_DELETE:
						{
							OnDelete();
							break;
						}
						case IDM_RENAME:
						{
							OnRename();
							break;
						}
					}
				}

				DeleteObj(RClick);
			}
		}
	}
}

int GFolderItemCompare(LListItem *A, LListItem *B, NativeInt Data)
{
	LFolderItem *a = dynamic_cast<LFolderItem*>(A);
	LFolderItem *b = dynamic_cast<LFolderItem*>(B);
	if (a && b)
	{
		if (a->IsDir ^ b->IsDir)
		{
			if (a->IsDir) return -1;
			else return 1;
		}
		else if (a->File && b->File)
		{
			return stricmp(a->File, b->File);
		}
	}

	return 0;
}

GFolderList::GFolderList(LFileSelectDlg *dlg, int Id, int x, int y, int cx, int cy) :
	LList(Id, x, y, cx, cy),
	GFolderView(dlg)
{
	SetImageList(Dlg->d->BtnIcons, false);
	ShowColumnHeader(false);
	AddColumn("Name", cx-20);
	SetMode(LListColumns);
}

bool GFolderList::OnKey(LKey &k)
{
	bool Status = LList::OnKey(k);
	
	switch (k.vkey)
	{
		case LK_BACKSPACE:
		{
			if (k.Down() && GetWindow())
			{
				// Go up a directory
				LViewI *v = GetWindow()->FindControl(IDC_UP);
				if (v)
				{
					GetWindow()->OnNotify(v, LNotifyBackspaceKey);
				}
			}
			Status = true;
			break;
		}
		case LK_RETURN:
		#ifdef LK_KP_ENTER
		case LK_KP_ENTER:
		#endif
		{
			if (k.Down() && GetWindow())
			{
				LFolderItem *Sel = dynamic_cast<LFolderItem*>(GetSelected());
				if (Sel)
				{
					if (Sel->IsDir)
					{
						auto Cur = GetWindow()->GetCtrlName(IDC_PATH);
						if (Cur)
						{
							char Path[256];
							LMakePath(Path, sizeof(Path), Cur, Sel->GetText(0));
							if (LDirExists(Path))
							{
								GetWindow()->SetCtrlName(IDC_PATH, Path);
								Dlg->OnFolder();
							}
						}
					}
					else
					{
						LViewI *Ok = GetWindow()->FindControl(IDOK);
						if (Ok)
						{
							GetWindow()->SetCtrlName(IDC_FILE, Sel->GetText(0));
							GetWindow()->OnNotify(Ok, LNotification(k));
						}
					}
				}
			}
			Status = true;
			break;
		}
		case LK_DELETE:
		{
			if (k.Down() && !k.IsChar && GetWindow())
			{
				List<LListItem> Sel;
				if (GetSelection(Sel))
				{
					LStringPipe Msg;
					Msg.Push("Do you want to delete:\n\n");
					
					List<LFolderItem> Delete;
					for (auto i: Sel)
					{
						LFolderItem *s = dynamic_cast<LFolderItem*>(i);
						if (s)
						{
							Delete.Insert(s);
							Msg.Push("\t");
							Msg.Push(s->GetText(0));
							Msg.Push("\n");
						}
					}
					
					char *Mem = Msg.NewStr();
					if (Mem)
					{
						if (LgiMsg(this, Mem, ModuleName, MB_YESNO) == IDYES)
						{
							for (auto d: Delete)
							{
								d->OnDelete(false);
							}
						}
						DeleteArray(Mem);
					}
				}
			}
			Status = true;
			break;
		}
	}

	// LgiTrace("%s:%i GFolderList::OnKey, key=%i down=%i status=%i\n", _FL, k.vkey, k.Down(), Status);
	
	return Status;
}

void GFolderList::OnFolder()
{
	Empty();

	LDirectory Dir;
	List<LListItem> New;

	// Get current type
	LFileType *Type = Dlg->d->Types.ItemAt(Dlg->d->CurrentType);
	List<char> Ext;
	if (Type)
	{
		auto T = LString(Type->Extension()).SplitDelimit(";");
		for (int i=0; i<T.Length(); i++)
		{
			Ext.Insert(NewStr(T[i]));
		}
	}

	// Get items
	if (!Dlg->Ctrl2)
		return;
		
	bool ShowHiddenFiles = Dlg->ShowHidden ? Dlg->ShowHidden->Value() : false;
	for (auto Found = Dir.First(Dlg->Ctrl2->Name()); Found; Found = Dir.Next())
	{
		char Name[LDirectory::MaxPathLen];
		Dir.Path(Name, sizeof(Name));
		
		bool Match = true;
		if (!ShowHiddenFiles && Dir.IsHidden())
		{
			Match = false;
		}
		else if (!Dir.IsDir() &&
				Ext.Length() > 0)
		{
			Match = false;
			for (auto e: Ext)
			{
				bool m = MatchStr(e, Name);
				if (m)
				{
					Match = true;
					break;
				}
			}
		}
		
		if (FilterKey && Match)
			Match = stristr(Dir.GetName(), FilterKey) != NULL;

		if (Match)
			New.Insert(new LFolderItem(Dlg, Name, &Dir));
	}

	// Sort items...
	New.Sort(GFolderItemCompare);

	// Display items...
	Insert(New);
}

//////////////////////////////////////////////////////////////////////////
LFileSelect::LFileSelect()
{
	d = new LFileSelectPrivate(this);
}

LFileSelect::~LFileSelect()
{
	DeleteObj(d);
}

void LFileSelect::ShowReadOnly(bool b)
{
	d->ShowReadOnly = b;;
}

bool LFileSelect::ReadOnly()
{
	return d->ReadOnly;
}

const char *LFileSelect::Name()
{
	return d->Files[0];
}

bool LFileSelect::Name(const char *n)
{
	d->Files.DeleteArrays();
	if (n)
	{
		d->Files.Insert(NewStr(n));
	}

	return true;
}

char *LFileSelect::operator [](size_t i)
{
	return d->Files.ItemAt(i);
}

size_t LFileSelect::Length()
{
	return d->Files.Length();
}

size_t LFileSelect::Types()
{
	return d->Types.Length();
}

void LFileSelect::ClearTypes()
{
	d->Types.DeleteObjects();
}

LFileType *LFileSelect::TypeAt(ssize_t n)
{
	return d->Types.ItemAt(n);
}

bool LFileSelect::Type(const char *Description, const char *Extension, int Data)
{
	LFileType *Type = new LFileType;
	if (Type)
	{
		Type->Description(Description);
		Type->Extension(Extension);
		d->Types.Insert(Type);
	}

	return Type != 0;
}

ssize_t LFileSelect::SelectedType()
{
	return d->CurrentType;
}

LViewI *LFileSelect::Parent()
{
	return d->Parent;
}

void LFileSelect::Parent(LViewI *Window)
{
	d->Parent = dynamic_cast<LView*>(Window);
}

bool LFileSelect::MultiSelect()
{
	return d->MultiSelect;
}

void LFileSelect::MultiSelect(bool Multi)
{
	d->MultiSelect = Multi;
}

#define CharPropImpl(Func, Var)				\
	char *LFileSelect::Func()				\
	{										\
		return Var;							\
	}										\
	void LFileSelect::Func(const char *i)	\
	{										\
		DeleteArray(Var);					\
		if (i)								\
		{									\
			Var = NewStr(i);				\
		}									\
	}

CharPropImpl(InitialDir, d->InitPath);
CharPropImpl(Title, d->Title);
CharPropImpl(DefaultExtension, d->DefExt);

bool LFileSelect::Open()
{
	LFileSelectDlg Dlg(d);

	d->Type = TypeOpenFile;
	Dlg.Name("Open");
	if (Dlg.SaveBtn)
		Dlg.SaveBtn->Name("Open");

	return Dlg.DoModal() == IDOK;
}

bool LFileSelect::OpenFolder()
{
	LFileSelectDlg Dlg(d);

	d->Type = TypeOpenFolder;
	Dlg.SaveBtn->Enabled(true);
	Dlg.FileNameEdit->Enabled(false);
	Dlg.Name("Open Folder");
	Dlg.SaveBtn->Name("Open");

	return Dlg.DoModal() == IDOK;
}

bool LFileSelect::Save()
{
	LFileSelectDlg Dlg(d);
	
	d->Type = TypeSaveFile;
	Dlg.Name("Save As");
	Dlg.SaveBtn->Name("Save As");

	return Dlg.DoModal() == IDOK;
}

///////////////////////////////////////////////////////////////////////////////////
#if defined(LINUX)
#include "lgi/common/Net.h"
#endif
bool LgiGetUsersLinks(LArray<LString> &Links)
{
	LString Folder = LGetSystemPath(LSP_USER_LINKS);
	if (!Folder)
		return false;
	
	#if defined(WINDOWS)
		LDirectory d;
		for (int b = d.First(Folder); b; b = d.Next())
		{
			char *s = d.GetName();
			if (s && stristr(s, ".lnk"))
			{
				char lnk[MAX_PATH];
				if (d.Path(lnk, sizeof(lnk)) &&
					LResolveShortcut(lnk, lnk, sizeof(lnk)))
				{
					Links.New() = lnk;
				}
			}
		}		
	#elif defined(LINUX)
		char p[MAX_PATH];
		if (!LMakePath(p, sizeof(p), Folder, "bookmarks"))
		{
			LgiTrace("%s:%i - Failed to make path '%s'\n", _FL, Folder.Get());
			return false;
		}

		if (!LFileExists(p))
			return false;
			
		LAutoString Txt(LReadTextFile(p));
		if (!Txt)
		{
			LgiTrace("%s:%i - failed to read '%s'\n", _FL, p);
			return false;
		}

		LString s = Txt.Get();
		LString::Array a = s.Split("\n");
		for (unsigned i=0; i<a.Length(); i++)
		{
			LUri u(a[i]);
			if (u.sProtocol.Equals("file"))
				Links.New() = u.sPath;
		}
	#else
		LAssert(!"Not impl yet.");
		return false;
	#endif
	
	return true;
}
