<?php

/*******************************************************************************

 WINBINDER - The native Windows binding for PHP for PHP

 Copyright © Hypervisual - see LICENSE.TXT for details
 Author: Rubem Pechansky (http://winbinder.org/contact.php)

 Form editor - Main window

*******************************************************************************/

//------------------------------------------------------------ SYSTEM PARAMETERS

define("PATH_SCRIPT",	dirname(__FILE__) . "/");
define("PATH_INC",		PATH_SCRIPT . "../include/");
define("PATH_RES",		PATH_SCRIPT . "../resources/");
define("PATH_RESPVT",	PATH_SCRIPT . "resources/");	// For specific bitmaps, icons and cursors

//----------------------------------------------------------------- DEPENDENCIES

include PATH_INC . "winbinder.php";
include "fe_fileio.inc.php";
include "fe_project.inc.php";
include "fe_options.inc.php";

//-------------------------------------------------------------------- CONSTANTS

define("APPNAME", 			"WinBinder Form Editor");		// App name
define("VERSION", 			"0.5.047");						// App version

// Control identifiers

define('ID_NEW',	 		9001);
define('ID_ABOUT', 			9002);
define('ID_OPEN', 			9003);
define('ID_SAVE', 			9004);
define('ID_SAVEAS', 		9005);
define('ID_EXPORT',			9006);
define('ID_PREVIEW',		9007);

define('ID_CLOSE', 			9020);
define('ID_STATUSBAR',		9022);
define('ID_WEBSITE',		9023);
define('ID_FIND',			9024);

define('ID_DELETE',			9031);
define('ID_FORWARDS',		9032);
define('ID_BACKWARDS',		9033);
define('ID_PROJECT',		9034);
define('ID_OPTIONS',		9035);
define('ID_TOOLBOX',		9036);

// Other constants

define('EMPTY_CAPTION',		'(no caption)');
define('MIN_WIDTH',	 		185);
define('MIN_HEIGHT', 		575);

// Default values for empty projects

define('DEFAULT_WINCLASS',			'AppWindow');
define('DEFAULT_FORMVAR',			'$winmain');
define('DEFAULT_PARENT',			'null');
define('DEFAULT_PREFIX',			'IDC_');
define('DEFAULT_STARTVAL',			'1000');
define('DEFAULT_LOCALIZE',			false);
define('DEFAULT_LOCPREFIX',			'LANG_');
define('DEFAULT_ISTABPAGE',			false);
define('DEFAULT_TABNUMBER',			0);
define('DEFAULT_FILLLISTS',			false);
define('DEFAULT_FILLHEADERS',		false);
define('DEFAULT_IMAGENAMES',		false);
define('DEFAULT_INSERTONTABS',		true);
define('DEFAULT_STATICNULLID',		true);
define('DEFAULT_APPLYVALUES',		false);
define('DEFAULT_CTRLVAR',			'');
define('DEFAULT_STARTCTRLVAL',		1);

//----------------------------------------------------------- CLASS DECLARATIONS

class Wb {
}

//-------------------------------------------------------------- EXECUTABLE CODE

create_main_window();
wb_main_loop();

//-------------------------------------------------------------------- FUNCTIONS

// Create main window

function create_main_window()
{
	global $wb;

	// Include code for dialogs

	include "fe_winapi.inc.php";
	include "fe_form.inc.php";
	include "fe_draw.inc.php";
	include "fe_dlg_classes.php";

	init_dlls();

	$wb = new Wb;

	// Create main window (invisible) and controls

	include "fe_main.form.php";

	// Set minimum window size

	wb_set_area($wb->mainwin, WBC_MINSIZE, 0, 0, MIN_WIDTH, MIN_HEIGHT);
	$wb->statusbar = wb_create_control($wb->mainwin, StatusBar, "");

	// Control arrays

	$wb->options_array = array('wireframe', 'grid', 'showgrid', 'ghost', 'constructionlines', 'showhex', 'autophp', 'filepath', 'autopath');
	$wb->project_array = array('formvar', 'parent', 'prefix', 'startval', 'localize', 'locprefix', 'istabpage', 'tabnumber',
	'filllists', 'fillheaders', 'imagenames', 'insertontabs', 'applyvalues', 'ctrlvar', 'startctrlval', 'staticnullid');

	// Preset IDs

	$wb->presetids = array('IDABORT', 'IDCANCEL', 'IDCLOSE', 'IDDEFAULT', 'IDHELP', 'IDIGNORE', 'IDNO', 'IDOK', 'IDRETRY', 'IDYES');

	// List of control classes

	$wb->classes = array(

		array(PushButton,	"PushButton"),
		array(ImageButton,	"ImageButton"),
		array(InvisibleArea,"InvisibleArea"),

		array(CheckBox,		"CheckBox"),
		array(RadioButton,	"RadioButton"),
		array(HyperLink,	"HyperLink"),

		array(Label,		"Label"),
		array(EditBox,		"EditBox"),
		array(RTFEditBox,	"RTFEditBox"),

		array(Frame,		"Frame"),
		array(ListBox,		"ListBox"),
		array(ComboBox,		"ComboBox"),

		array(Spinner,		"Spinner"),
		array(ScrollBar,	"ScrollBar"),
		array(Slider,		"Slider"),

		array(Gauge,		"Gauge"),
		array(Calendar,		"Calendar"),
		array(HTMLControl,	"HTMLControl"),

		array(TabControl,	"TabControl"),
		array(ListView,		"ListView"),
		array(TreeView,		"TreeView"),
	);

	// Create buttons, one for each control

	$nclasses = count($wb->classes);
	for($i = 0; $i < $nclasses; $i++) {
		$const = "IDC_" . strtoupper($wb->classes[$i][1]);
		if(!defined($const))
			define($const, 8001 + $i);
	}

	// Create main menu

	$wb->mainmenu = wb_create_control($wb->mainwin, Menu, array(

		"&File",
			array(ID_NEW,			"&New project\tCtrl+N", 	"", PATH_RES . "menu_new.bmp",	"Ctrl+N"),
			array(ID_OPEN,			"&Open project...\tCtrl+O", "", PATH_RES . "menu_open.bmp",	"Ctrl+O"),
			null,
			array(ID_SAVE,			"&Save project\tCtrl+S",	"", PATH_RES . "menu_save.bmp",	"Ctrl+S"),
			array(ID_SAVEAS,		"Save project &As...\tCtrl+Shift+S",		'', '', 'Ctrl+Shift+S'),
			array(ID_EXPORT,		"Export &PHP code...\tCtrl+Shift+E",		'', '', 'Ctrl+Shift+E'),
			null,
			array(IDCLOSE,			"E&xit\tAlt+F4",			"", PATH_RES . "menu_exit.bmp"),

		"&Edit",
			array(ID_DELETE,		"&Delete control\tCtrl+Del","", "",	"Ctrl+Del"),
			null,
		  	array(ID_FORWARDS,		"Move forwards\tCtrl+PgDn",	"", "", "Ctrl+PgDn"),
		  	array(ID_BACKWARDS,		"Move backwards\tCtrl+PgUp","", "", "Ctrl+PgUp"),
			null,
		  	array(ID_PROJECT,		"Project properties...\tCtrl+Shift+P",	"", '', 'Ctrl+Shift+P'),
		  	null,
		  	array(ID_OPTIONS,		"Options...\tCtrl+Shift+O",				"", '', 'Ctrl+Shift+O'),

		"&View",
		  	array(ID_TOOLBOX,		"Controls window",		"", ""),
			null,
			array(ID_PREVIEW,		"&Preview form...",			"", "",	"F9"),

		"&Classes",

			// Alphabetical order

			array(IDC_CALENDAR,		"Calen&dar",		"", PATH_RESPVT . "menu_calendar.bmp"),
			array(IDC_CHECKBOX,		"&CheckBox",		"", PATH_RESPVT . "menu_checkbox.bmp"),
			array(IDC_COMBOBOX,		"C&omboBox",		"", PATH_RESPVT . "menu_combobox.bmp"),
			array(IDC_EDITBOX,		"&EditBox",			"", PATH_RESPVT . "menu_editbox.bmp"),
			array(IDC_FRAME,		"&Frame",			"", PATH_RESPVT . "menu_frame.bmp"),
			array(IDC_GAUGE,		"&Gauge",			"", PATH_RESPVT . "menu_gauge.bmp"),
			array(IDC_HTMLCONTROL,	"&HTMLControl",		"", PATH_RESPVT . "menu_htmlcontrol.bmp"),
			array(IDC_HYPERLINK,	"HyperLin&k",		"", PATH_RESPVT . "menu_hyperlink.bmp"),
			array(IDC_IMAGEBUTTON,	"&ImageButton",		"", PATH_RESPVT . "menu_imagebutton.bmp"),
			array(IDC_INVISIBLEAREA,"I&nvisibleArea",	"", PATH_RESPVT . "menu_invisiblearea.bmp"),
			array(IDC_LABEL,		"&Label",			"", PATH_RESPVT . "menu_label.bmp"),
			array(IDC_LISTBOX,		"List&Box",			"", PATH_RESPVT . "menu_listbox.bmp"),
			array(IDC_LISTVIEW,		"List&View",		"", PATH_RESPVT . "menu_listview.bmp"),
			array(IDC_PUSHBUTTON,	"P&ushButton",		"", PATH_RESPVT . "menu_pushbutton.bmp"),
			array(IDC_RADIOBUTTON,	"&RadioButton",		"", PATH_RESPVT . "menu_radiobutton.bmp"),
			array(IDC_RTFEDITBOX,	"RT&FEditBox",		"", PATH_RESPVT . "menu_rtfeditbox.bmp"),
			array(IDC_SCROLLBAR,	"ScrollB&ar",		"", PATH_RESPVT . "menu_scrollbar.bmp"),
			array(IDC_SLIDER,		"&Slider",			"", PATH_RESPVT . "menu_slider.bmp"),
			array(IDC_SPINNER,		"S&pinner",			"", PATH_RESPVT . "menu_spinner.bmp"),
			array(IDC_TABCONTROL,	"&TabControl",		"", PATH_RESPVT . "menu_tabcontrol.bmp"),
			array(IDC_TREEVIEW,		"TreeVie&w",		"", PATH_RESPVT . "menu_treeview.bmp"),

		"&Help",
			array(ID_WEBSITE,		"&Web site\tCtrl+Shift+W",	"", PATH_RES . "menu_web.bmp", 'Ctrl+Shift+W'),
			null,
			array(ID_ABOUT,			"&About this program...")
	));

	wb_set_selected($wb->mainmenu, ID_TOOLBOX, true);

	// Create toolbar

	$wb->toolbar = wb_create_control($wb->mainwin, ToolBar, array(
	  	null,
	  	array(ID_NEW,			NULL, "New project (Ctrl+N)",		0),
	  	array(ID_OPEN,			NULL, "Open project (Ctrl+O)",		1),
	  	array(ID_SAVE,			NULL, "Save project (Ctrl+S)",		2),
	  	null,
	  	array(ID_PROJECT,		NULL, "Project properties (Ctrl + Shift + P)",			3),
	  	array(ID_PREVIEW,		NULL, "Preview form (F9)",			22),
	  	null,
	  	array(ID_DELETE,		NULL, "Delete (Del)",				12),
	  	null,
	  	array(ID_FORWARDS,		NULL, "Move forwards (Ctrl+PgUp)",	24),
	  	array(ID_BACKWARDS,		NULL, "Move backwards (Ctrl+PgDn)",	25),

	  	null,
	  	array(ID_WEBSITE,		NULL, "Web site", 					11),

	), 0, 0, 16, 15, 0, 0, PATH_RESPVT . "toolbar.bmp");

	// Set up control and window classes

	$wb->classes = array(
		array(PushButton,	"PushButton"),
		array(ImageButton,	"ImageButton"),
		array(InvisibleArea,"InvisibleArea"),

		array(CheckBox,		"CheckBox"),
		array(RadioButton,	"RadioButton"),
		array(HyperLink,	"HyperLink"),

		array(Label,		"Label"),
		array(EditBox,		"EditBox"),
		array(RTFEditBox,	"RTFEditBox"),

		array(Frame,		"Frame"),
		array(ListBox,		"ListBox"),
		array(ComboBox,		"ComboBox"),

		array(Spinner,		"Spinner"),
		array(ScrollBar,	"ScrollBar"),
		array(Slider,		"Slider"),

		array(Gauge,		"Gauge"),
 		array(Calendar,		"Calendar"),
		array(HTMLControl,	"HTMLControl"),

		array(TabControl,	"TabControl"),
		array(ListView,		"ListView"),
		array(TreeView,		"TreeView"),
	);

	$wb->winclasses = array(
		array("AppWindow",			"Application window"),
		array("ResizableWindow",	"Resizable window"),
		array("ModalDialog",		"Modal dialog"),
		array("ModelessDialog",		"Modeless dialog"),
		array("TabPage",			"Tab page"),
		array("PopupWindow",		"Pop-up window"),
		array("ToolDialog",			"Tool dialog"),
		array("NakedWindow",		"Naked window")
	);
	$winclasses = array();
	foreach($wb->winclasses as $wclass)
		$winclasses[] = $wclass[1];
	wb_set_text(wb_get_control($wb->mainwin, IDC_CLASSES), $winclasses);

	// Initialize 'controls' TreeView

	$wb->tree = wb_get_control($wb->mainwin, IDC_CONTROLS);
	wb_set_image($wb->tree, PATH_RESPVT . "treeview.bmp", GREEN, 0, 58);
	wb_set_style($wb->tree, WBC_LINES);

	// Initialize 'styles' ListView

	$wb->stylelist = wb_get_control($wb->mainwin, IDC_STYLES);
	wb_set_text($wb->stylelist, array(array("Styles", 144)));
	wb_set_style($wb->stylelist, WBC_CHECKBOXES);

	// Set control ranges

	wb_set_range(wb_get_control($wb->mainwin, IDC_VALUESPINNER), 	-2147483647, 2147483647);
	wb_set_range(wb_get_control($wb->mainwin, IDC_LEFTSPINNER),		-32767, 32767);
	wb_set_range(wb_get_control($wb->mainwin, IDC_TOPSPINNER),		-32767, 32767);
	wb_set_range(wb_get_control($wb->mainwin, IDC_WIDTHSPINNER),	0, 32767);
	wb_set_range(wb_get_control($wb->mainwin, IDC_HEIGHTSPINNER),	0, 32767);

	// Set default values

	$wb->ghoststate = false;
	$wb->mouseop = false;
	$wb->wirestyle = 0;
	$wb->formwin = null;
	$wb->mousecpos = NOWHERE;
	$wb->filepath = PATH_SCRIPT;

	$wb->filefilter = array(
		array("WinBinder Project File",		"*.prj"),
		array("All files",					"*.*")
	);
	$wb->phpfilter = array(
		array("WinBinder PHP form",			"*.form.php"),
		array("PHP files",					"*.php?"),
		array("All files",					"*.*")
	);

	// Size, move and show main window

	read_settings();

	create_classes_dlg($wb->mainwin);
	wb_set_image($wb->mainwin, PATH_RESPVT . "wb.ico");
	wb_set_handler($wb->mainwin, "process_main");
	wb_set_visible($wb->mainwin, true);
	set_default_accel();

	start_empty_project();
}

/* Main window processing */

function process_main($window, $id, $ctrl, $lparam1=0, $lparam2=0)
{
	global $wb;

	switch($id) {

		//-------------------- Control / form properties

		case IDC_LEFT:
			if(!$wb->mouseop && ($wb->form[$wb->currentform]->nselcontrol >= 0)) {
				$wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->left = wb_get_value($ctrl);
				wb_refresh($wb->formwin, false);
			}
			break;

		case IDC_TOP:
			if(!$wb->mouseop && ($wb->form[$wb->currentform]->nselcontrol >= 0)) {
				$wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->top = wb_get_value($ctrl);
				wb_refresh($wb->formwin, false);
			}
			break;

		case IDC_WIDTH:
			if(!$wb->mouseop) {
				if($wb->form[$wb->currentform]->nselcontrol >= 0) {
					$wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->width = MAX(1, wb_get_value($ctrl));
					wb_refresh($wb->formwin, false);
				} else {
					$wb->form[$wb->currentform]->width = MAX(1, wb_get_value($ctrl));
					wb_set_size($wb->formwin, $wb->form[$wb->currentform]->width, $wb->form[$wb->currentform]->height);
				}
			}
			break;

		case IDC_HEIGHT:
			if(!$wb->mouseop) {
				if($wb->form[$wb->currentform]->nselcontrol >= 0) {
					$wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->height = MAX(1, wb_get_value($ctrl));
					wb_refresh($wb->formwin, false);
				} else {
					$wb->form[$wb->currentform]->height = MAX(1, wb_get_value($ctrl));
					wb_set_size($wb->formwin, $wb->form[$wb->currentform]->width, $wb->form[$wb->currentform]->height);
				}
			}
			break;

		case IDC_ID:
			if(wb_get_focus() != $ctrl) {	// Prevents cascading messages
				break;
			}
			$text = wb_get_text($ctrl);
			if($wb->form[$wb->currentform]->nselcontrol >= 0) {
				$id = $wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->id;
				$wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->id = $text;
				wb_refresh($wb->formwin, false);
			}
			break;

		case IDC_VALUEAUX:		// This is the hidden buddy control

			$value = wb_get_value($ctrl);
			if($wb->form[$wb->currentform]->nselcontrol >= 0) {
				$wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->value = $value;
			} else
				$wb->form[$wb->currentform]->value = $value;
			$vctrl = wb_get_control($wb->mainwin, IDC_VALUE);
			if(wb_get_focus() != $vctrl)
				wb_set_text($vctrl, sprintf($wb->showhex ? "#%08X" : "%d", $value));
			wb_refresh($wb->formwin, false);
			break;

		case IDC_VALUE:			// This control is shown

			if($wb->showhex)
				$value = hexdec(wb_get_text($ctrl));
	 		else
				$value = (int)wb_get_text($ctrl);

			if(wb_get_focus() == $ctrl)
				wb_set_value(wb_get_control($wb->mainwin, IDC_VALUEAUX), $value);
			break;

		case IDC_CLASSES:
			$winclass = wb_get_text($ctrl);
			foreach($wb->winclasses as $wclass) {
				if($wclass[1] == $winclass) {
					$wb->form[$wb->currentform]->cclass = $wclass[0];
					break;
				}
			}
			break;

		case IDC_CAPTION:
			if(wb_get_focus() != $ctrl) {	// Prevents cascading messages
				break;
			}
			$text = wb_get_text($ctrl);
			if($wb->form[$wb->currentform]->nselcontrol >= 0) {
				$wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol]->caption = $text;
				$id = $wb->form[$wb->currentform]->nselcontrol->id;
				wb_refresh($wb->formwin, false);
			} else {
				$wb->form[$wb->currentform]->caption = $text;
				$id = null;
				wb_set_text($wb->formwin, $text);
			}
			wb_set_text($wb->tree, $text ? str_replace("&", "", $text) : ($id ? $id : EMPTY_CAPTION), wb_get_selected($wb->tree));
			break;

		case IDC_STYLES:

			if(wb_get_focus() != $ctrl) {	// Prevents cascading messages
				break;
			}

			$form = &$wb->form[$wb->currentform];
			$ncurrent = $form->nselcontrol;
			$values = wb_get_value($wb->stylelist);
			$style = 0;
			if(is_array($values)) {

				// Get the current class styles

				if($ncurrent < 0) {
					$class = $form->cclass;
				} else {
					$ct = &$form->ct[$form->nselcontrol];
					$class = $ct->cclass;
				}
				$style_array = get_class_styles($class);

				// Assigns the style(s) to the form or control

				foreach($values as $val) {
					$style |= $style_array[$val][1];
				}
			}

			if($ncurrent < 0)
				$form->style = $style;
			else
				$form->ct[$form->nselcontrol]->style = $style;

			wb_refresh($wb->formwin, false);
			break;

		//-------------------- Control creation buttons (in alphabetical order)

		case IDC_CALENDAR:
			create_control("Calendar", null, 200, 160, 20, 20, null, WBC_BORDER);
			break;

		case IDC_CHECKBOX:
			create_control("CheckBox", null, 120, 15, 20, 20);
			break;

		case IDC_COMBOBOX:
			create_control("ComboBox", "Item1,Item2,Item3", 120, 60, 20, 20, null, WBC_READONLY);
			break;

		case IDC_EDITBOX:
			create_control("EditBox", null, 90, 20, 20, 20);
			break;

		case IDC_FRAME:
			create_control("Frame", null, 130, 130, 20, 20, $wb->form[$wb->currentform]->staticnullid ? '' : null);
			break;

		case IDC_GAUGE:
			create_control("Gauge", null, 100, 20, 20, 20, null, 0, 50);
			break;

		case IDC_HTMLCONTROL:
			create_control("HTMLControl", null, 160, 160, 20, 20, null, WBC_BORDER);
			break;

		case IDC_HYPERLINK:
			create_control("HyperLink", null, 140, 15, 20, 20, null, WBC_LINES, 0xC00000);
			break;

		case IDC_IMAGEBUTTON:
			create_control("ImageButton", null, 25, 25, 20, 20);
			break;

		case IDC_INVISIBLEAREA:
			create_control("InvisibleArea", null, 80, 80, 20, 20);
			break;

		case IDC_LABEL:
			create_control("Label", null, 90, 15, 20, 20, $wb->form[$wb->currentform]->staticnullid ? '' : null);
			break;

		case IDC_LISTBOX:
			create_control("ListBox", "Item1,Item2,Item3", 120, 60, 20, 20);
			break;

		case IDC_LISTVIEW:
			create_control("ListView", 'Head1,Head2,Head3,Head4', 245, 140, 20, 20);
			break;

		case IDC_PUSHBUTTON:
			create_control("PushButton", null, 90, 25, 20, 20);
			break;

		case IDC_RADIOBUTTON:
			create_control("RadioButton", null, 120, 15, 20, 20);
			break;

		case IDC_RTFEDITBOX:
			create_control("RTFEditBox", null, 120, 90, 20, 20);
			break;

		case IDC_SCROLLBAR:
			create_control("ScrollBar", null, 20, 150, 20, 20);
			break;

		case IDC_SLIDER:
			create_control("Slider", null, 100, 20, 20, 20, null, 0, 50);
			break;

		case IDC_SPINNER:
			create_control("Spinner", null, 20, 20, 20, 20, null, WBC_GROUP);
			break;

		case IDC_TABCONTROL:
			create_control("TabControl", 'Tab1,Tab2,Tab3', 340, 240, 20, 20);
			break;

		case IDC_TREEVIEW:
			create_control("TreeView", null, 140, 220, 20, 20);
			break;

		//-------------------- The treeview

		case IDC_CONTROLS:

			// Must prevent propagation of messages here

			$wb->form[$wb->currentform]->nselcontrol = -1;		// Start with no control selected
			$form = $wb->form[$wb->currentform];				// Auxiliary variable
			$node = wb_get_selected($ctrl);

			if($node == $wb->form[$wb->currentform]->treenode) {
				$wb->form[$wb->currentform]->nselcontrol = -1;
				update_control_data();
				wb_refresh($wb->formwin, false);
			} else {
				for($i = 0; $i < $form->numcontrols; $i++) {
					if($node == @$wb->form[$wb->currentform]->ct[$i]->treenode) {
						$wb->form[$wb->currentform]->nselcontrol = $i;
						update_control_data();
						wb_refresh($wb->formwin, false);
					}
				}
			}
			break;

		//-------------------- Commands

		case ID_FORWARDS:

			$form = $wb->form[$wb->currentform];
			$ct = $wb->form[$wb->currentform]->ct;
			$n = $form->nselcontrol;

			if($n < 0)
				break;
			if($n >= $form->numcontrols - 1)
				break;

			// Swap controls

			swap_controls($n, $n + 1);

			// Select the other control

			wb_set_selected($wb->tree, $wb->form[$wb->currentform]->ct[$n + 1]->treenode);
			update_control_data();
			break;

		case ID_BACKWARDS:

			$form = $wb->form[$wb->currentform];
			$ct = $wb->form[$wb->currentform]->ct;
			$n = $form->nselcontrol;

			if($n < 1)
				break;
			if($n >= $form->numcontrols)
				break;

			// Swap controls

			swap_controls($n, $n - 1);

			// Select the other control

			wb_set_selected($wb->tree, $wb->form[$wb->currentform]->ct[$n - 1]->treenode);
			update_control_data();
			break;

		case ID_DELETE:

			$form = $wb->form[$wb->currentform];
			$ct = $wb->form[$wb->currentform]->ct;
			$n = $form->nselcontrol;

			if($n < 0)
				break;
			if($n >= $form->numcontrols)
				break;

			// Select another control

			if($n > 0)
				wb_set_selected($wb->tree, $wb->form[$wb->currentform]->ct[$n - 1]->treenode);
			else
				wb_set_selected($wb->tree, 0);

			// Delete control

			delete_control($n);
			update_control_data();
			wb_refresh($wb->formwin, 1);
			break;

        case ID_NEW:
        	if($wb->numforms && $wb->form[$wb->currentform]->numcontrols)
				if(!wb_message_box($wb->mainwin, "Do you want to discard this project and create a new one?", APPNAME, WBC_QUESTION | WBC_YESNO))
					break;
			start_empty_project();
			wb_set_text($window, APPNAME);
        	break;

        case ID_OPEN:
        	if($wb->numforms && $wb->form[$wb->currentform]->numcontrols)
	        	if(!wb_message_box($wb->mainwin, "Do you want to discard this project and open another one?", APPNAME, WBC_QUESTION | WBC_YESNO))
	        		break;
			$filename = wb_sys_dlg_open($window, "Open Project", $wb->filefilter, $wb->filepath);
			if($filename) {
				start_empty_project();
				read_project($filename);
				wb_set_text($window, basename($filename) . " - " . APPNAME);
				$wb->proj_filename = $filename;
				if($wb->autopath)
					$wb->filepath = dirname($filename);
			}
            break;

        case ID_SAVE:
        	if(isset($wb->proj_filename)) {
				if($wb->autophp)
					save_phpcode($wb->proj_filename);
				save_project($wb->proj_filename);
			} else {
				$filename = wb_sys_dlg_save($window, "Save Project", $wb->filefilter, $wb->filepath, null, "prj");
				if($filename) {
					$wb->proj_filename = $filename;
					if($wb->autophp)
						save_phpcode($wb->proj_filename);
					if($wb->autopath)
						$wb->filepath = dirname($filename);
					save_project($wb->proj_filename);
				}
			}
			break;

        case ID_SAVEAS:

        	if($wb->proj_filename)
        		$path = basename($wb->proj_filename);
        	else
        		$path = $wb->filepath;

			$filename = wb_sys_dlg_save($window, "Save Winbinder Project", $wb->filefilter, $path, basename($wb->proj_filename), "prj");
			if($filename) {
				$wb->proj_filename = $filename;
				save_project($wb->proj_filename);
				if($wb->autophp)
					save_phpcode($wb->proj_filename);
				if($wb->autopath)
					$wb->filepath = dirname($filename);
			}
			break;

        case ID_EXPORT:
			$filename = wb_sys_dlg_save($window, "Export PHP Code", $wb->phpfilter, $wb->filepath, basename(str_replace(".prj", ".form.php", $wb->proj_filename)), "php");
			if($filename) {
				$wb->proj_filename = $filename;
				save_phpcode($wb->proj_filename);
			}
			break;

		case IDC_WIREFRAME:
			$val = wb_get_value($ctrl);
			$wb->wireframe = $val;
			wb_refresh($wb->formwin, false);
			break;

		case IDC_GRID:
			$wb->grid = wb_get_value($ctrl);
			wb_refresh($wb->formwin, false);
			break;

		case ID_TOOLBOX:
			if($wb->classdlg) {
				wb_set_selected($wb->mainmenu, $id, false);
				wb_destroy_window($wb->classdlg);
				$wb->classdlg = null;
			} else {
				wb_set_selected($wb->mainmenu, $id, true);
				create_classes_dlg($window);
			}
			break;

		case ID_ABOUT:
			wb_message_box($window,
			  APPNAME . " version: " . VERSION . "\r\n" .
			  "\r\nWinBinder version: " . WBC_VERSION .
			  "\r\nPHP version: " . PHP_VERSION .
			  "\r\nGDI objects: " . wb_get_system_info("gdiobjects") .
			  "\r\nUSER objects: " . wb_get_system_info("userobjects"),

			  "About " . APPNAME, WBC_INFO);
			break;

		case ID_WEBSITE:
			wb_exec('http://winbinder.org/');
			break;

		case ID_PROJECT:
			create_project_dlg($window);
			break;

		case ID_OPTIONS:
			create_options_dlg($window);
			break;

		case ID_PREVIEW:

			// Test the form

			global $test_form;

			if(!@$test_form) {

				// Change some values for the preview

				$formvar = $wb->form[$wb->currentform]->formvar;
				$parent = $wb->form[$wb->currentform]->parent;
				$istabpage = $wb->form[$wb->currentform]->istabpage;
				$wb->form[$wb->currentform]->formvar = "\$test_form";
				$wb->form[$wb->currentform]->parent = $window;
				$wb->form[$wb->currentform]->istabpage = false;

				// Create the preview window ($test_form)

				$phpcode = save_phpcode(null);
				if($phpcode) {
					//echo($phpcode);
					eval($phpcode);
					wb_set_visible($test_form, true);
					set_default_accel($test_form, false);
					wb_set_handler($test_form, "process_test_form");
				}

				// Restore values

				$wb->form[$wb->currentform]->formvar = $formvar;
				$wb->form[$wb->currentform]->parent = $parent;
				$wb->form[$wb->currentform]->istabpage = $istabpage;
				wb_main_loop();		// Stefano -- use wb_main_loop() for bug fix
			}
			break;

		case IDCLOSE:		// IDCLOSE is predefined
        	if($wb->numforms && $wb->form[$wb->currentform]->numcontrols)
				if(!wb_message_box($wb->mainwin, "Do you want to exit the program?", APPNAME, WBC_QUESTION | WBC_YESNO))
					break;
			save_settings($window);
			wb_destroy_window($window);
			break;
	}
}

function process_test_form($window, $id)
{
	global $wb, $test_form;

	switch($id) {
		case 0:
			break;

		case IDOK:
		case IDCLOSE:
		case IDCANCEL:
			set_default_accel();
			wb_destroy_window($window);
			$test_form = null;
			break;
	}
}

//---------------------------------------------------------- AUXILIARY FUNCTIONS

/* Start a new project */

function start_empty_project()
{
	global $wb;

	if($wb->formwin)
		wb_set_visible($wb->formwin, false);

	$wb->numforms = 0;
	$wb->form = null;
	$wb->currentform = -1;
	wb_create_items($wb->tree, null, true);
	$wb->rootnode = 0;
	$wb->project = null;

	$title = '(Empty Form)';

	// Create a new form

	if(!$wb->formwin)
		create_form($wb->mainwin, $title, 540, 470);
	else
		reset_form(DEFAULT_WINCLASS, $wb->mainwin, $title, 540, 470);

	update_control_data(true);
}

/* Create a new control */

function create_control($class, $caption, $width, $height, $left, $top, $id=null, $style=0, $value=0, $update = true)
{
	global $wb;

	if(!$wb->numforms)
		return;

	$wb->form[$wb->currentform]->numcontrols++;
	$ncurrent = $wb->form[$wb->currentform]->numcontrols - 1;

	if($id === null) {
		$index = ++$wb->form[$wb->currentform]->ncurrindex;
		$id = $wb->form[$wb->currentform]->prefix . strtoupper($class) . ($wb->form[$wb->currentform]->startval + $index);
	}

	if(!isset($wb->form[$wb->currentform]))
		$wb->form[$wb->currentform] = new stdclass;

	if(!isset($wb->form[$wb->currentform]->ct[$ncurrent]))
		$wb->form[$wb->currentform]->ct[$ncurrent] = new stdclass;

	$wb->form[$wb->currentform]->ct[$ncurrent]->cclass = $class;
	$wb->form[$wb->currentform]->ct[$ncurrent]->caption = ($caption !== null) ? $caption : ($class . $wb->form[$wb->currentform]->numcontrols);
	$wb->form[$wb->currentform]->ct[$ncurrent]->width = max(1, $width);
	$wb->form[$wb->currentform]->ct[$ncurrent]->height = max(1, $height);
	$wb->form[$wb->currentform]->ct[$ncurrent]->left = $left;
	$wb->form[$wb->currentform]->ct[$ncurrent]->top = $top;
	$wb->form[$wb->currentform]->ct[$ncurrent]->id = $id;
	$wb->form[$wb->currentform]->ct[$ncurrent]->style = (int)$style;
	$wb->form[$wb->currentform]->ct[$ncurrent]->value = (int)$value;

	// Select icon for treeview item based on $class

	$class_icon = 10 + 2 * array_search(array(constant($class), $class), $wb->classes);

	// Create treeview item

	$ct = $wb->form[$wb->currentform]->ct[$ncurrent];
	$node = wb_create_items($wb->tree, array(
		array($ct->caption ? str_replace("&", "", $ct->caption) : ($ct->id ? $ct->id : EMPTY_CAPTION), $ncurrent, $wb->form[$wb->currentform]->treenode, $class_icon, $class_icon + 1, 2)
	));
	wb_set_selected($wb->tree, $node);

	$wb->form[$wb->currentform]->ct[$ncurrent]->treenode = $node;
	$wb->form[$wb->currentform]->nselcontrol = $ncurrent;

	if($update)
		update_control_data();
	wb_refresh($wb->formwin);
}

/* Show control or form data */

function update_control_data($force=false)
{
	global $wb;
	static $id_main = array(IDC_ID, IDC_TOP, IDC_LEFT, IDC_TOPSPINNER, IDC_LEFTSPINNER);
	static $id_tool = array(ID_DELETE, ID_FORWARDS, ID_BACKWARDS);
	static $lastctrl = -2;

	$form = $wb->form[$wb->currentform];
	$ncurrent = $form->nselcontrol;

	if($ncurrent < 0) {

		// It's a form

		foreach($id_main as $id)
			wb_set_enabled(wb_get_control($wb->mainwin, $id), false);
		foreach($id_tool as $id)
			wb_set_enabled(wb_get_control($wb->toolbar, $id), false);

		$id = wb_get_control($wb->mainwin, IDC_ID);
		wb_set_text($id, "");
		$class = $wb->form[$wb->currentform]->cclass;
		$styles = $form->style;
		$size = wb_get_size($wb->formwin);
		wb_set_text(wb_get_control($wb->mainwin, IDC_VALUEAUX), $wb->form[$wb->currentform]->value);
		wb_set_text(wb_get_control($wb->mainwin, IDC_WIDTH), $size[0]);
		wb_set_text(wb_get_control($wb->mainwin, IDC_HEIGHT), $size[1]);
		wb_set_text(wb_get_control($wb->mainwin, IDC_CAPTION), wb_get_text($wb->formwin));
		wb_set_text(wb_get_control($wb->mainwin, IDC_TOP), 0);
		wb_set_text(wb_get_control($wb->mainwin, IDC_LEFT), 0);
		wb_set_selected($wb->tree, $wb->form[$wb->currentform]->treenode);
		wb_set_text($wb->statusbar, $class . ' "' . $wb->form[$wb->currentform]->caption . '"');

		// Select class in combo box

		wb_set_visible(wb_get_control($wb->mainwin, IDC_CLASS), false);
		for($i = 0; $i < count($wb->winclasses); $i++) {
			if($wb->winclasses[$i][0] == $class)
				wb_set_selected(wb_get_control($wb->mainwin, IDC_CLASSES), $i);
		}
		wb_set_visible(wb_get_control($wb->mainwin, IDC_CLASSES), true);

	} else {

		// It's a control

		$ct = $wb->form[$wb->currentform]->ct[$wb->form[$wb->currentform]->nselcontrol];

		foreach($id_main as $id)
			wb_set_enabled(wb_get_control($wb->mainwin, $id), true);
		foreach($id_tool as $id)
			wb_set_enabled(wb_get_control($wb->toolbar, $id), true);

		$class = $ct->cclass;
		$styles = $ct->style;
		$forwards = wb_get_control($wb->toolbar, ID_FORWARDS);
		$backwards = wb_get_control($wb->toolbar, ID_BACKWARDS);
		wb_set_enabled($forwards, ($ncurrent < $form->numcontrols - 1));
		wb_set_enabled($backwards, ($ncurrent >= 1));
		$id = wb_get_control($wb->mainwin, IDC_ID);
		wb_set_text($id, (string)$ct->id);
		wb_set_text(wb_get_control($wb->mainwin, IDC_CAPTION), $ct->caption);
		wb_set_text(wb_get_control($wb->mainwin, IDC_VALUEAUX), $ct->value);
		wb_set_text(wb_get_control($wb->mainwin, IDC_TOP), $ct->top);
		wb_set_text(wb_get_control($wb->mainwin, IDC_LEFT), $ct->left);
		wb_set_text(wb_get_control($wb->mainwin, IDC_WIDTH), $ct->width);
		wb_set_text(wb_get_control($wb->mainwin, IDC_HEIGHT), $ct->height);
		wb_set_visible(wb_get_control($wb->mainwin, IDC_CLASS), true);
		wb_set_text(wb_get_control($wb->mainwin, IDC_CLASS), $class);
		wb_set_visible(wb_get_control($wb->mainwin, IDC_CLASSES), false);
		wb_set_selected($wb->tree, $ct->treenode);
		wb_set_text($wb->statusbar, $class . ' "' . str_replace("&", "", $ct->caption) . '" (' . $ct->id . ')');
	}
	wb_set_enabled(wb_get_control($wb->toolbar, ID_SAVE), $form->numcontrols > 0);

	// Fill up styles list if control did not change

	if($force || ($ncurrent != $lastctrl)) {

		wb_delete_items($wb->stylelist, null);
		$stylelist = get_class_styles($class);
		wb_create_items($wb->stylelist, $stylelist);
		for($i = 0; $i < count($stylelist); $i++) {
			if($styles & $stylelist[$i][1])
				wb_set_value($wb->stylelist, $i, true);
		}
	}

	$lastctrl = $ncurrent;
}

/* Delete control of index $index */

function delete_control($index)
{
	global $wb;

	$form = $wb->form[$wb->currentform];
	$curr = $form->ct[$index];

	// Remove an item from the control array

	array_splice($wb->form[$wb->currentform]->ct, $index, 1);
	$wb->form[$wb->currentform]->numcontrols--;
	wb_delete_items($wb->tree, $curr->treenode);
}


/* Swaps controls of indices $index_curr and $index_next */

function swap_controls($index_curr, $index_next)
{
	global $wb;

	$form = $wb->form[$wb->currentform];

	$curr = $form->ct[$index_curr];
	$next = $form->ct[$index_next];

	// Swap controls

	$wb->form[$wb->currentform]->ct[$index_curr] = $next;
	$wb->form[$wb->currentform]->ct[$index_next] = $curr;

	// Restore control tree nodes

	$wb->form[$wb->currentform]->ct[$index_curr]->treenode = $curr->treenode;
	$wb->form[$wb->currentform]->ct[$index_next]->treenode = $next->treenode;

	// Swap treeview icons

	$class = $next->cclass;
	$class_icon = 10 + 2 * array_search(array(constant($class), $class), $wb->classes);
	wb_set_item_image($wb->tree, array($class_icon, $class_icon + 1), $curr->treenode);
	$class = $curr->cclass;
	$class_icon = 10 + 2 * array_search(array(constant($class), $class), $wb->classes);
	wb_set_item_image($wb->tree, array($class_icon, $class_icon + 1), $next->treenode);

	// Swap treeview icons

	wb_set_text($wb->tree, $next->caption ? str_replace("&", "", $next->caption) : ($next->id ? $next->id : EMPTY_CAPTION), $curr->treenode);
	wb_set_text($wb->tree, $curr->caption ? str_replace("&", "", $curr->caption) : ($curr->id ? $curr->id : EMPTY_CAPTION), $next->treenode);

	wb_set_value($wb->tree, $next->id, $curr->treenode);
	wb_set_value($wb->tree, $curr->id, $next->treenode);
}

/* Return an array of styles according to $class */

function get_class_styles($class)
{
	switch($class) {

		case 'AppWindow':
		case 'ResizableWindow':
		case 'ModalDialog':
		case 'ModelessDialog':
		case 'TabPage':				// TabPage is a window class; don't mix up with TabControl
		case 'PopupWindow':
		case 'ToolDialog':
		case 'NakedWindow':
			return array(
				array('Initially invisible',	WBC_INVISIBLE),
				array('Always on top',			WBC_TOP),
				array('Custom draw',			WBC_CUSTOMDRAW),
				array('Minimize to task bar',	WBC_TASKBAR),
				array('Notify',					WBC_NOTIFY),
			);

		case 'Label':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('With border',			WBC_BORDER),
				array('Centered',				WBC_CENTER),
				array('Ellipsis',				WBC_ELLIPSIS),
				array('Multi-line',				WBC_MULTILINE),
				array('Right-aligned',			WBC_RIGHT),
				array('Text at bottom',			WBC_BOTTOM),
				array('Text on top',			WBC_TOP),
			);

		case 'HyperLink':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Centered',				WBC_CENTER),
				array('Underlined',				WBC_LINES),
			);

		case 'EditBox':
			return array(
				array('Centered',				WBC_CENTER),
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Multi-line',				WBC_MULTILINE),
				array('Number field',			WBC_NUMBER),
				array('Password field',			WBC_MASKED),
				array('Read-only',				WBC_READONLY),
				array('Right-aligned',			WBC_RIGHT),
			);

		case 'RTFEditBox':
			return array(
				array('Centered',				WBC_CENTER),
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Read-only',				WBC_READONLY),
				array('Right-aligned',			WBC_RIGHT),
			);

		case 'ListView':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('With grid lines',		WBC_LINES),
				array('With check boxes',		WBC_CHECKBOXES),
				array('Single select',			WBC_SINGLE),
				array('Sortable',				WBC_SORT),
			);

		case 'PushButton':
		case 'Calendar':
		case 'HTMLControl':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('With border',			WBC_BORDER),
			);

		case 'RadioButton':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Group start',			WBC_GROUP),
			);

		case 'Spinner':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Attach to edit control',	WBC_GROUP),
			);

		case 'Frame':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Image',					WBC_IMAGE),
				array('With border',			WBC_BORDER),
			);

		case 'ComboBox':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Sorted',					WBC_SORT),
				array('Read-only',				WBC_READONLY),
			);

		case 'ListBox':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Sorted',					WBC_SORT),
			);

		case 'TreeView':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('With grid lines',		WBC_LINES),
			);

		case 'ImageButton':
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
				array('Transparent',			WBC_TRANSPARENT),
				array('Auto-repeat',			WBC_AUTOREPEAT),
			);

		default:
			return array(
				array('Disabled',				WBC_DISABLED),
				array('Invisible',				WBC_INVISIBLE),
			);
	}
}

function set_default_accel($window=null, $main=true)
{
	global $wb;

	$window = $window ? $window : $wb->mainwin;

	if($main) {
		wb_create_control($window, Accel, array(
			array(ID_NEW,		'ctrl+N'),
			array(ID_OPEN,		'ctrl+O'),
			array(ID_SAVE,		'ctrl+S'),
			array(ID_SAVEAS,	'ctrl+shift+S'),
			array(ID_EXPORT,	'ctrl+shift+E'),
			array(ID_OPTIONS,	'ctrl+shift+O'),
			array(ID_PROJECT,	'ctrl+shift+P'),
			array(ID_WEBSITE,	'ctrl+shift+W'),
			array(ID_PREVIEW,	'F9'),
			array(ID_DELETE,	'ctrl+Del'),
			array(ID_FORWARDS,	'ctrl+PgDn'),
			array(ID_BACKWARDS,	'ctrl+PgUp'),
		));
	} else {
		wb_create_control($window, Accel, array(
			array(IDCANCEL,		'esc'),
			array(IDOK,			'enter'),
		));
	}
}

//------------------------------------------------------------------ END OF FILE

?>