////////////////////////////////////////////////////////////
///////                                            /////////
///////   QUASK FORM SCRIPT - (C) 2005 Quask Ltd   /////////
///////                                            /////////
////////////////////////////////////////////////////////////


//=========================================================
//=============== DYNAMIC FORM DATA =======================
//=========================================================


//---------------------------------------------------------
//------------------------ Form  --------------------------
//---------------------------------------------------------


f_appversion = "1.0.175.0";				//DLL Version
f_title = "DAPC rev1";					//Title of form
f_guid = "3C916361F53C4A1B9856172532054FEC";					//GUID of form
f_version = "xxx-xxxxxx";				//Version of form
f_tag = "";					//Form Tag
f_preview = false;					//Preview Mode?
f_unbranded = true;					//Unbranded?
f_trialversion = false;				//Trial Version?
f_singleresponse = false;				//Is it a single-response form?
f_readonly = false;					//Is the whole form read-only?
f_noscripts = false;					//Don't allow any script to run (when viewing data in FA)
f_allowpreload = true;				//Not in Presto
f_forcefocus = true;					//Make sure page scrolls down/up so that the page/object that is displayed is visible (IE only)
f_aftersend = "0";				//0..default, 1...Fill again, 2..Close Window, 9..Demo Mode (Close upon Send)
f_hourglass = 6;					//If >0, use hourglass between pages
f_requirespopup = false;				//If true, needs be able to create pop-up windows (GetURL(), Upload)
f_splitpage = false;					//If true, every page is on a new HTML page
f_encryption = false;					//If true, preload-data and submit data is encrypted

f_self_url = "formrender.asp";				//Page that renders form ie. myself (for email embedded success url)
f_data_url = "http://surveys.sel.sony.com/FormServer/public.asmx/submit";				//URL for sending data to
f_src_url = "http://surveys.sel.sony.com/FormServer/dhtmlform/3C916361F53C4A1B9856172532054FEC.xml";				//XML source of this form (for QPD viewer)
f_success_url = "";			//URL that is displayed when data sending was successful ("" if this page)
f_failure_url = "";			//URL that is displayed when data sending failed ("" if this page)
f_upload_url = "";				//URL for file uploading
f_servercomm_url = "http://surveys.sel.sony.com/FormServer/svrcomm.aspx";			//URL for server communication
f_sendformmanager = false;			//Sends data to FormManager instead of POST
f_unload_url = "http://surveys.sel.sony.com/FormServer/svrcomm.aspx?qf_event=close&instid=";				//URL that is called window OnUnload event
f_keepalive_url = "";			//URL that is triggered are regular intervals to inform FormServer that the form is still "alive"
f_keepalive_mins = 15;				//Number minutes of the interval
f_initial_workflowstage = "New";	//Default value for this SystemProperty
f_intitial_workflowlevel = "0";	//Default value for this SystemProperty

f_events = ["11", "12", "13"];						//OnLoad, OnSend, OnReset
f_page_w = 600;						//Width of page
f_page_h = 800;						//Height of page
f_page_start = 0;					//First page to be shown

f_loading_image_id = "q_loadpic";		//<img id=...> of loading image in html page

f_skin = false;					//Has skin or not
f_skin_w = 0;					//Width of skin-element (Must be 0 if no skin)
f_skin_h = 0;					//Width of skin-element (Must be 0 if no skin)
f_skin_btns = 0;				//0=No buttons, 1=Send/Reset only, 2=Page Navi only, 3=All on one line, 4=All on two lines
f_skin_defaultcolor = "ffffff";	//Color that is drawn in the middle (Sending...)

//Fonts
f_fonts = [
	"10pt|Arial|0",
	"14pt|Arial|1",
	"12pt|Arial|1",
	"18pt|Arial|1",
	"10pt|Arial|2",
	"10pt|Arial|1",
	"9pt|Arial|1",
	"9pt|Arial|0",
	"9pt|Arial|2",
	"20pt|Arial|1",
	"18pt|Arial|3",
	"16pt|Arial|1",
	"18pt|Arial|0"
	];


//---------------------------------------------------------
//------------------------ Pages --------------------------
//---------------------------------------------------------


f_page_def = [
	["ffffff", "Greeting", "1", 0, 0],
	["ffffff", "Survey 1", "9", 0, 0],
	["ffffff", "Survey 2", "36", 0, 0]
	];


//---------------------------------------------------------
//--------------------- Controls  -------------------------
//---------------------------------------------------------


//Bass class: type, id, page, x, y, width, height, frame, framepic, padding, backcol, forecol, tab, zorder, required, font
f_controls_def = [

	//------------------ Labels  -----------------------

	//---- Page 0 ("Greeting") ----

	//Picture Label ("Shape 2")
	[6, "2", "TAG_4", 0, 0, 1, 0, 750, 600, 50, 0, 0, 0, "ffffff", "2e64e2", 1, 0,
		7, 600, 50, 0],

	//Text Label ("lab_DAPC")
	[1, "6", "TAG_6", 0, 0, 1, 64, 272, 489, 28, 0, 0, 0, "", "2e64e2", 3, 12,
		0, 5, 0],

	//Text Label ("Lab_survey")
	[1, "7", "TAG_7", 0, 0, 1, 152, 332, 280, 80, 0, 0, 0, "", "000000", 4, 1,
		1, 5, 0],

	//Text Label ("Lab_footerg")
	[1, "22", "TAG_22", 0, 0, 1, 20, 760, 280, 28, 0, 0, 0, "", "000080", 5, 5,
		2, 5, 0],

	//Text Label ("Label 1")
	[1, "83", "TAG_83", 0, 0, 1, 104, 436, 392, 52, 0, 0, 0, "", "000000", 6, 0,
		3, 5, 0],


	//---- Page 1 ("Survey 1") ----

	//Picture Label ("Shape 3")
	[6, "10", "TAG_4", 0, 1, 1, 0, 750, 600, 50, 0, 0, 0, "ffffff", "2e64e2", 1, 0,
		7, 600, 50, 0],

	//Text Label ("Lab_Q1")
	[1, "14", "TAG_14", 0, 1, 1, 16, 32, 556, 20, 0, 0, 0, "", "000000", 3, 5,
		4, 5, 0],

	//Text Label ("Lab_Q1pls")
	[1, "15", "TAG_15", 0, 1, 1, 32, 52, 428, 20, 0, 0, 0, "", "000000", 4, 8,
		5, 5, 0],

	//Text Label ("Lab_Q1VD")
	[1, "16", "TAG_16", 0, 1, 1, 32, 72, 88, 32, 0, 0, 0, "", "000000", 5, 0,
		6, 5, 0],

	//Text Label ("Lab_Q1NSD")
	[1, "17", "TAG_17", 0, 1, 1, 268, 72, 88, 52, 0, 0, 0, "", "000000", 6, 7,
		7, 5, 0],

	//Text Label ("Lab_Q1VS")
	[1, "18", "TAG_18", 0, 1, 1, 520, 72, 72, 32, 0, 0, 0, "", "000000", 7, 7,
		8, 5, 0],

	//Text Label ("Lab_Q2")
	[1, "20", "TAG_20", 0, 1, 2, 16, 184, 548, 20, 0, 0, 0, "", "000000", 9, 5,
		9, 5, 0],

	//Text Label ("Lab_Q3")
	[1, "21", "TAG_21", 0, 1, 2, 16, 340, 468, 16, 0, 0, 0, "", "000000", 10, 5,
		10, 5, 0],

	//Text Label ("Lab_footer1")
	[1, "23", "TAG_23", 0, 1, 2, 20, 760, 280, 28, 0, 0, 0, "", "000080", 11, 5,
		2, 5, 0],

	//Text Label ("Lab_Q2VD")
	[1, "24", "TAG_16", 0, 1, 2, 32, 228, 88, 32, 0, 0, 0, "", "000000", 12, 0,
		6, 5, 0],

	//Text Label ("Lab_Q2NSD")
	[1, "25", "TAG_17", 0, 1, 2, 272, 228, 88, 52, 0, 0, 0, "", "000000", 13, 7,
		7, 5, 0],

	//Text Label ("Lab_Q2VS")
	[1, "26", "TAG_18", 0, 1, 2, 524, 228, 72, 32, 0, 0, 0, "", "000000", 14, 7,
		8, 5, 0],

	//Text Label ("Lab_Q2pls")
	[1, "28", "TAG_28", 0, 1, 3, 32, 204, 428, 20, 0, 0, 0, "", "000000", 16, 8,
		5, 5, 0],

	//Text Label ("Lab_Q3VD")
	[1, "29", "TAG_16", 0, 1, 3, 32, 380, 88, 32, 0, 0, 0, "", "000000", 17, 0,
		6, 5, 0],

	//Text Label ("Lab_Q3NSD")
	[1, "30", "TAG_17", 0, 1, 3, 272, 380, 88, 52, 0, 0, 0, "", "000000", 18, 7,
		7, 5, 0],

	//Text Label ("Lab_Q3VS")
	[1, "31", "TAG_18", 0, 1, 3, 524, 380, 72, 32, 0, 0, 0, "", "000000", 19, 7,
		8, 5, 0],

	//Text Label ("Lab_Q3pls")
	[1, "33", "TAG_28", 0, 1, 4, 32, 356, 428, 20, 0, 0, 0, "", "000000", 21, 8,
		5, 5, 0],

	//Text Label ("Lab_Q4")
	[1, "34", "TAG_34", 0, 1, 4, 16, 496, 532, 28, 0, 0, 0, "", "000000", 22, 5,
		11, 5, 0],

	//Text Label ("Lab_Q5VD")
	[1, "63", "TAG_16", 0, 1, 5, 32, 632, 88, 32, 0, 0, 0, "", "000000", 24, 0,
		6, 5, 0],

	//Text Label ("Lab_Q5NSD")
	[1, "64", "TAG_17", 0, 1, 5, 272, 632, 88, 52, 0, 0, 0, "", "000000", 25, 7,
		7, 5, 0],

	//Text Label ("Lab_Q5VS")
	[1, "65", "TAG_18", 0, 1, 5, 524, 632, 72, 32, 0, 0, 0, "", "000000", 26, 7,
		8, 5, 0],

	//Text Label ("Lab_Q5pls")
	[1, "67", "TAG_28", 0, 1, 6, 32, 608, 428, 20, 0, 0, 0, "", "000000", 28, 8,
		5, 5, 0],

	//Text Label ("Lab_Q5")
	[1, "68", "TAG_52", 0, 1, 6, 16, 588, 496, 20, 0, 0, 0, "", "000000", 29, 5,
		12, 5, 0],


	//---- Page 2 ("Survey 2") ----

	//Picture Label ("Shape 4")
	[6, "37", "TAG_4", 0, 2, 1, 0, 750, 600, 50, 0, 0, 0, "ffffff", "2e64e2", 1, 0,
		7, 600, 50, 0],

	//Text Label ("Lab_footer2")
	[1, "41", "TAG_41", 0, 2, 1, 20, 760, 280, 28, 0, 0, 0, "", "000080", 4, 5,
		2, 5, 0],

	//Text Label ("Lab_Q6DW")
	[1, "47", "TAG_16", 0, 2, 2, 36, 96, 76, 32, 0, 0, 0, "", "000000", 5, 7,
		13, 5, 0],

	//Text Label ("Lab_Q6MMN")
	[1, "48", "TAG_17", 0, 2, 2, 280, 96, 72, 52, 0, 0, 0, "", "000000", 6, 7,
		14, 5, 0],

	//Text Label ("Lab_Q6DW")
	[1, "49", "TAG_18", 0, 2, 2, 528, 96, 72, 32, 0, 0, 0, "", "000000", 7, 7,
		15, 5, 0],

	//Text Label ("Lab_Q6pls")
	[1, "51", "TAG_28", 0, 2, 3, 36, 68, 428, 20, 0, 0, 0, "", "000000", 9, 8,
		16, 5, 0],

	//Text Label ("Lab_Q6")
	[1, "53", "TAG_53", 0, 2, 3, 16, 32, 544, 32, 0, 0, 0, "", "000000", 10, 5,
		17, 5, 0],

	//Text Label ("Lab_Q7")
	[1, "54", "TAG_54", 0, 2, 3, 16, 200, 536, 40, 0, 0, 0, "", "000000", 11, 5,
		18, 5, 0],

	//Text Label ("Lab_Q7pls")
	[1, "55", "TAG_55", 0, 2, 3, 36, 232, 428, 20, 0, 0, 0, "", "000000", 12, 8,
		19, 5, 0],

	//Text Label ("Lab_Q7k")
	[1, "56", "TAG_56", 0, 2, 3, 36, 256, 116, 20, 0, 0, 0, "", "000000", 13, 6,
		20, 5, 0],

	//Text Label ("Lab_Q7c")
	[1, "57", "TAG_57", 0, 2, 3, 36, 308, 116, 20, 0, 0, 0, "", "000000", 14, 6,
		21, 5, 0],

	//Text Label ("Lab_Q7r")
	[1, "58", "TAG_58", 0, 2, 3, 36, 356, 116, 20, 0, 0, 0, "", "000000", 15, 6,
		22, 5, 0],

	//Text Label ("Lab_Q8")
	[1, "62", "TAG_62", 0, 2, 6, 16, 428, 552, 36, 0, 0, 0, "", "000000", 17, 5,
		23, 5, 0],

	//Text Label ("Lab_ths2")
	[1, "81", "TAG_81", 0, 2, 7, 112, 644, 368, 36, 0, 0, 0, "", "2e64e2", 19, 10,
		24, 5, 0],


	//------------- User Drawn Controls  ---------------

	//---- Page 0 ("Greeting") ----


	//---- Page 1 ("Survey 1") ----

	//Tickbox Group ("Tickbox_Q1")
	[7, "19", "TAG_19", 1, 1, 1, 32, 124, 556, 24, 0, 0, 0, "ffffff", "000000", 8, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[48, 8, 28, 15, 28, 27, 0],
			[96, 8, 28, 15, 30, 29, 0],
			[144, 8, 28, 15, 32, 31, 0],
			[192, 8, 28, 15, 34, 33, 0],
			[240, 8, 28, 15, 36, 35, 0],
			[296, 8, 28, 15, 38, 37, 0],
			[352, 8, 28, 15, 40, 39, 0],
			[400, 8, 28, 15, 42, 41, 0],
			[448, 8, 28, 15, 44, 43, 0],
			[496, 8, 34, 15, 46, 45, 0]
		],
		0],

	//Tickbox Group ("Tickbox_Q2")
	[7, "27", "TAG_19", 1, 1, 2, 32, 280, 556, 24, 0, 0, 0, "ffffff", "000000", 15, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[48, 8, 28, 15, 28, 27, 0],
			[96, 8, 28, 15, 30, 29, 0],
			[144, 8, 28, 15, 32, 31, 0],
			[192, 8, 28, 15, 34, 33, 0],
			[240, 8, 28, 15, 36, 35, 0],
			[300, 8, 28, 15, 38, 37, 0],
			[352, 8, 28, 15, 40, 39, 0],
			[400, 8, 28, 15, 42, 41, 0],
			[448, 8, 28, 15, 44, 43, 0],
			[496, 8, 34, 15, 46, 45, 0]
		],
		0],

	//Tickbox Group ("Tickbox_Q3")
	[7, "32", "TAG_19", 1, 1, 3, 32, 432, 556, 24, 0, 0, 0, "ffffff", "000000", 20, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[48, 8, 28, 15, 28, 27, 0],
			[96, 8, 28, 15, 30, 29, 0],
			[144, 8, 28, 15, 32, 31, 0],
			[192, 8, 28, 15, 34, 33, 0],
			[240, 8, 28, 15, 36, 35, 0],
			[300, 8, 28, 15, 38, 37, 0],
			[352, 8, 28, 15, 40, 39, 0],
			[400, 8, 28, 15, 42, 41, 0],
			[448, 8, 28, 15, 44, 43, 0],
			[496, 8, 34, 15, 46, 45, 0]
		],
		0],

	//Tickbox Group ("Tickbox_Q5")
	[7, "66", "TAG_19", 1, 1, 5, 32, 688, 556, 24, 0, 0, 0, "ffffff", "000000", 27, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[48, 8, 28, 15, 28, 27, 0],
			[96, 8, 28, 15, 30, 29, 0],
			[144, 8, 28, 15, 32, 31, 0],
			[192, 8, 28, 15, 34, 33, 0],
			[240, 8, 28, 15, 36, 35, 0],
			[300, 8, 28, 15, 38, 37, 0],
			[352, 8, 28, 15, 40, 39, 0],
			[400, 8, 28, 15, 42, 41, 0],
			[448, 8, 28, 15, 44, 43, 0],
			[496, 8, 34, 15, 46, 45, 0]
		],
		0],


	//---- Page 2 ("Survey 2") ----

	//Tickbox Group ("Tickbox_Q6")
	[7, "50", "TAG_19", 1, 2, 2, 36, 136, 556, 24, 0, 0, 0, "ffffff", "000000", 8, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[52, 8, 28, 15, 28, 27, 0],
			[100, 8, 28, 15, 30, 29, 0],
			[148, 8, 28, 15, 32, 31, 0],
			[196, 8, 28, 15, 34, 33, 0],
			[248, 8, 28, 15, 36, 35, 0],
			[300, 8, 28, 15, 38, 37, 0],
			[352, 8, 28, 15, 40, 39, 0],
			[400, 8, 28, 15, 42, 41, 0],
			[448, 8, 28, 15, 44, 43, 0],
			[496, 8, 34, 15, 46, 45, 0]
		],
		0],

	//Tickbox Group ("Tickbox_Q7k")
	[7, "59", "TAG_59", 0, 2, 3, 36, 272, 532, 24, 0, 0, 0, "ffffff", "000000", 16, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[44, 8, 28, 15, 28, 27, 0],
			[88, 8, 28, 15, 30, 29, 0],
			[136, 8, 28, 15, 32, 31, 0],
			[180, 8, 28, 15, 34, 33, 0],
			[224, 8, 28, 15, 36, 35, 0],
			[268, 8, 28, 15, 38, 37, 0],
			[312, 8, 28, 15, 40, 39, 0],
			[356, 8, 28, 15, 42, 41, 0],
			[400, 8, 28, 15, 44, 43, 0],
			[444, 8, 34, 15, 46, 45, 0],
			[492, 9, 39, 15, 48, 47, 0]
		],
		0],

	//Tickbox Group ("Tickbox_Q7k1")
	[7, "84", "TAG_84", 0, 2, 7, 36, 324, 532, 24, 0, 0, 0, "ffffff", "000000", 20, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[44, 8, 28, 15, 28, 27, 0],
			[88, 8, 28, 15, 30, 29, 0],
			[136, 8, 28, 15, 32, 31, 0],
			[180, 8, 28, 15, 34, 33, 0],
			[224, 8, 28, 15, 36, 35, 0],
			[268, 8, 28, 15, 38, 37, 0],
			[312, 8, 28, 15, 40, 39, 0],
			[356, 8, 28, 15, 42, 41, 0],
			[400, 8, 28, 15, 44, 43, 0],
			[444, 8, 34, 15, 46, 45, 0],
			[492, 9, 39, 15, 48, 47, 0]
		],
		0],

	//Tickbox Group ("Tickbox_Q7k2")
	[7, "85", "TAG_85", 0, 2, 8, 36, 372, 532, 24, 0, 0, 0, "ffffff", "000000", 21, 6,
		0, 0, 0, 14, 8, 1, 13, 0,
		[
			[0, 8, 28, 15, 26, 25, 0],
			[44, 8, 28, 15, 28, 27, 0],
			[88, 8, 28, 15, 30, 29, 0],
			[136, 8, 28, 15, 32, 31, 0],
			[180, 8, 28, 15, 34, 33, 0],
			[224, 8, 28, 15, 36, 35, 0],
			[268, 8, 28, 15, 38, 37, 0],
			[312, 8, 28, 15, 40, 39, 0],
			[356, 8, 28, 15, 42, 41, 0],
			[400, 8, 28, 15, 44, 43, 0],
			[444, 8, 34, 15, 46, 45, 0],
			[492, 9, 39, 15, 48, 47, 0]
		],
		0],


	//---------------- All others  ---------------------

	//---- Page 0 ("Greeting") ----

	//Button ("AB_nextg")
	[12, "5", "TAG_6", 0, 0, 1, 488, 760, 100, 26, 0, 0, 0, "2e64e2", "000080", 2, 0,
		0, 49, 8, "", 0],


	//---- Page 1 ("Survey 1") ----

	//Button ("AB_next1")
	[12, "13", "TAG_6", 0, 1, 1, 488, 760, 100, 26, 0, 0, 0, "2e64e2", "000080", 2, 0,
		0, 49, 8, "", 0],

	//Drop-Down Selection ("Drop down_Q4")
	[9, "35", "TAG_35", 1, 1, 4, 32, 528, 232, 22, 0, 0, 0, "ffffff", "000000", 23, 0,
		[50, 51, 52, 53, 54],
		[25, 27, 29, 31, 33],
		0, 0, 0],


	//---- Page 2 ("Survey 2") ----

	//Button ("AB_back")
	[12, "39", "TAG_5", 0, 2, 1, 376, 760, 100, 26, 0, 0, 0, "2e64e2", "000080", 2, 0,
		0, 55, 9, "", 0],

	//Button ("AB_send")
	[12, "40", "TAG_6", 0, 2, 1, 488, 760, 100, 26, 0, 0, 0, "2e64e2", "000080", 3, 0,
		0, 56, 1, "", 0],

	//Text Input ("Text Input_Q8")
	[2, "71", "TAG_71", 0, 2, 6, 32, 480, 544, 104, 0, 0, 0, "ffffff", "000000", 18, 0,
		1, 350, 0, 57, 57, 0],

	null]; //Last one is empty



//---------------------------------------------------------
//--------------------- Resources -------------------------
//---------------------------------------------------------


//Resources 0..gif, 1..jpg, 2..wav, 3..mid, 4..mp3
f_resources_path = "http://surveys.sel.sony.com/FormServer/dhtmlform/3C916361F53C4A1B9856172532054FEC_gfx/";
f_resources_type = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

//String Table
f_strings = [
	"SONY Direct Accessories and Parts Center",
	"Customer Satisfaction Survey",
	"SONY DAPC Customer Satisfaction Survey",
	"Thank you for your business with us. &nbsp;We value your feedback and suggestions. &nbsp;Please click NEXT to start survey.",
	"1. &nbsp;How satisfied were you with the ease of navigation within the Sony DAPC web site?",
	"Please select one, with 10 meaning most satisfied",
	"Very Dissatisfied",
	"Neither Satisfied or Dissatisfied",
	"Very Satisfied",
	"2. &nbsp;How satisfied were you with the ease of locating the item(s) you needed? ",
	"3. &nbsp;How satisfied are you with the competitiveness of our pricing?",
	"4. &nbsp;If you did not place an order,",
	"5. &nbsp;How would you rate your overall experience with Sony's DAPC web site?",
	"Definitely Would Not",
	"Might or Might Not",
	"Definitely Would",
	"Please select one, with 10 meaning definitely would<br>",
	"6. &nbsp;Based on your recent experience with the Sony DAPC web site, how likely are you to recommend Sony for Electronics products to family, friends or others?",
	"7. &nbsp;If you contacted Sony DAPC customer service, please rate their performance in the following areas:",
	"Please select one, with 10 meaning excellent",
	"Knowledge",
	"Courtesy",
	"Responsiveness",
	"8. &nbsp;What is one thing Sony's Direct Accessories and Parts web site could do that would increase your likelihood to recommend Sony?",
	"Thank you for the participation.",
	"1",
	"0",
	"2",
	"1",
	"3",
	"2",
	"4",
	"3",
	"5",
	"4",
	"6",
	"5",
	"7",
	"6",
	"8",
	"7",
	"9",
	"8",
	"10",
	"9",
	"11",
	"10",
	"12",
	"N/A",
	"NEXT",
	"Please check one &lt;&lt;&lt;&lt;",
	"Price too high",
	"Item was unavailable",
	"Looking for information (shopping only)",
	"Other",
	"BACK",
	"SEND",
	""
	];


//---------------------------------------------------------
//------------------- User Scripts ------------------------
//---------------------------------------------------------


function q_RunScript2(script_id, current_obj, current_page, params)
{
	switch(script_id)
	{
		case "13":
		{

		};
		break;

		case "12":
		{

		};
		break;

		case "11":
		{

		};
		break;

	};
}



//=========================================================
//======================= TEXTS ===========================
//=========================================================


var q_Texts = [
			"`<obppp705:09K`<b",
			"`<ob9:/Q~'95(9,N`<b",
			"`<ob}:925=X~705:09K~=*=Z`<b",
			"`<obp*09K~%22)8++9;;)K~=*=Z`<b",
			"`<obp9;0/~05~:92258~9<~%20/~0=;~1,/8~+56J`<b",
			":::::",
			"p=*=:~96*~:09K~)/%~9,/89<~0/5*+9)-~+56*~,9'+0=~9+=92N\np:9,9'+0=~099<~*/0~+=6~0/5*+9)-~%,/*=:0=1~]",
			"_1,/8~+56*~05~:2958~6;=9~*9+9,~/*~*0='~)/%~9,)+~)/%~9,]",
			"",
			"p0/5*;0)8~*05,.~+w,9+'/,\\~,)/%~705+)~+97=.~92705+~*05,.~0=;~)/%~r%29(5*=0,9*2]\n\np1,/8~9*92.1/;~96*~*05,.~/*~7/2=5:~6;=9~0/~w*05,Nw~++9,N\n\np1,/8~+56*~05~97=.~6;=9~,/8~7/2=5:~*05,N~=~6*5'~:9*09+9,.~9<~225'~)/E",
			"p705*05,.~:96+5058~+=6~97=.~+56*~,9*8=~05=7=~*05,N~++9,.~:0=~+97=.~,96*/~96*~/*~9*=75(=P\n\np:9*05,.~9<~225'~97=.~*09,,);~96*~%20O\n\np915*~96*~*=~97=.~90/~705*05,.~+*,/..)+~%20/~,9+'/,<~,)/E",
			"`=ob3+=)M`l2-?*+a++=2;~30=2<?a*97,=*~|1,/8o1/;p3+=)-p'''ood.**6|a89,6~=b~%<~:9,9'/.",
			"'/:05G~9+/2[",
			"05=7=~05~225X",
			"9)05*0/[",
			"ppp+25=*9Z",
			"p'/:05'~'90~=~05~:9%=2.+5:~9<~225'~0/5*=1,580/[`,<b`,<b`<obppp705:09K`<b",
			"p++9,::=~25=19~:52=(~=~,9*0Y",
			"pRLI~:52=(~=~,9*0Y",
			"",
			""
	];



//=========================================================
//============ CROSS-BROWSER HANDLING LIBRARY =============
//=========================================================


//Browser Flags
var q_bIE = false; 
var q_bDOM2 = false; 
var q_bMac = false; 
var q_bMoz15 = false;
var q_bFirefox = false; 
var q_bFirefox2 = false;

if(document.all) q_bIE = true;
else if(document.getElementById) q_bDOM2 = true;
if(navigator.appVersion.indexOf("Mac")>=0) q_bMac = true;
if(navigator.userAgent.indexOf("Mozilla")>=0 && (navigator.userAgent.indexOf("1.5")>=0 || navigator.userAgent.indexOf("1.4"))>=0) q_bMoz15 = true;
if(navigator.userAgent.indexOf("Firefox")>=0) q_bFirefox = true;
if(navigator.userAgent.indexOf("Firefox/2")>=0) q_bFirefox2 = true;

if((!q_bDOM2 && !q_bIE)									        //Unidentified browser
	|| (q_bIE && navigator.appVersion.indexOf("MSIE 4.")!=-1))	//IE4 not supported (yet)
{	
	alert("Your browser version cannot render the form on this page.\nPlease upgrade your browser.");
}
if(q_bDOM2 && navigator.userAgent.indexOf("Netscape6")!=-1)
{
	//N6 recommend update to N7
	alert("We recommend that you upgrade your browser to the latest version in order to render the form on this page.");
}


//--- Layor-Stylesheet Helpers ---

function q_Style(id)
{
	if(q_bIE) return document.all[id].style;
	if(q_bDOM2) return document.getElementById(id).style;
}

function q_GetLeft(id)
{
	if(q_bIE) return q_Style(id).pixelLeft;
	if(q_bDOM2) {l=parseInt(q_Style(id).left); if(l*0!=0)l=0; return l;};
}

function q_SetLeft(id, x)
{
	if(q_bIE) q_Style(id).pixelLeft = x;
	if(q_bDOM2) q_Style(id).left = x + "px";
}

function q_GetTop(id)
{
	if(q_bIE) return q_Style(id).pixelTop;
	if(q_bDOM2) {t=parseInt(q_Style(id).top); if(t*0!=0)t=0; return t;};
}

function q_SetTop(id, y)
{
	if(q_bIE) q_Style(id).pixelTop = y;
	if(q_bDOM2) q_Style(id).top = y+"px";
}

function q_SetHeight(id, y)
{
	if(q_bIE) q_Style(id).pixelHeight = y;
	if(q_bDOM2) q_Style(id).height = y+"px";
}

function q_SetVisible(id, v)
{
	q_Style(id).visibility = v?'visible':'hidden';
}

function q_SetBackCol(id,c)
{
	q_Style(id).backgroundColor = c;
}

function q_SetColor(id,c)
{
	q_Style(id).color = c;
}

function q_SetZOrder(id,z)
{
	q_Style(id).zIndex = z;
}

function q_SetBorder(id, s, c)
{
	q_Style(id).border = s +"px solid #"+c;
}

function q_GetImage(id, p)
{
    return document.images[p];
}

function q_SetElementBackCol(e, c) //Set color of e.g. <input type=text> element
{
	e.style.backgroundColor=c;
}

function q_SetTransparency(id, v) //0 to 100
{
	if(q_bIE)
	{
		if(v>=0 && v<100)document.all[id].style.filter = "alpha(opacity="+v+")";
		else document.all[id].style.filter = "alpha(enabled=false)";
	}
//	if(q_bDOM2) q_Style(id).MozOpacity=v/100;
}

function q_SetHTML(id, text)
{
	if(q_bIE) document.all[id].innerHTML = text;
	if(q_bDOM2) document.getElementById(id).innerHTML = text;
}

function q_GetBrowserWidth()
{
    return document.body.clientWidth;
}

function q_GetBrowserHeight()
{
	return document.body.clientHeight;
}

function q_PreLoadSound(i)
{
	if(q_bIE) document.writeln('<embed name=q_snd_'+i+' autostart=false autoplay=false src="'+f_resources[i].src+'" hidden=true></embed>');
}

function q_PlaySound(i, loop)
{
	if(q_bIE)
	{
		if(loop)document.all['q_snd_loop'].src=f_resources[i].src;
		else document.all['q_snd_noloop'].src=f_resources[i].src;
	}
	if(q_bDOM2)
		q_OpenWindow(f_resources[i].src, 200, 30);
}

function q_SetHourglass(b)
{
	if(q_bIE) document.body.style.cursor=b?'wait':'default';
}

function q_GetButtonHeight(h)
{
	return h-((q_bMac&&q_bIE)?5:0);
}

function q_GetButtonWidth(w)
{
	return w-((q_bMac&&q_bIE)?10:0);
}

function q_GetControlHeight(h)
{
	return h-((q_bMac&&q_bIE)?4:0);
}

function q_GetControlWidth(w)
{
	return w-((q_bMac&&q_bIE)?4:0);
}

function q_GetComboBoxHeight(h)
{
	return h-((q_bMac&&q_bIE)?4:0)-((q_bFirefox||q_bDOM2)?2:0);
}

function q_SupportsMultipagePrinting()
{
	return q_bIE; //IE only
}

function q_GetCaretPos(e)
{
	//Mozilla/Firefox
	if(e.selectionStart) return e.selectionStart;
	
	//IE
	if(e.createTextRange)
	{
		var c = document.selection.createRange(),
			p=0,
			t = e.createTextRange();

		if(t)
		{
			while(c.compareEndPoints("StartToStart", t) > 0)
			{
				t.moveStart("character", 1);
				p++;
			}
			return p;
		}
	}

	//Not supported
	return -1;
}

function q_SetCaretPos(e, p)
{
	//Mozilla/Firefox
	if(e.setSelectionRange) e.setSelectionRange(p, p);
	
	//IE
	else if(e.createTextRange)
	{
		var r = e.createTextRange();
		r.collapse(true);
		r.moveEnd("character", p);
		r.moveStart("character", p);
		r.select();
	}
}


//--- Event Helpers ---

function q_CaptureEvents()
{
	if(q_bDOM2) document.captureEvents(Event.MOUSEDOWN|Event.MOUSEMOVE|Event.MOUSEUP);
}

function q_GetEventTarget(e)
{
	if(q_bIE) return event.srcElement;
	if(q_bDOM2) return e.target;
}

function q_GetEventKey(e)
{
	if(q_bIE) return event.keyCode;
	if(q_bDOM2) return e.which;
}

function q_GetEventX(e)
{
	if(q_bIE) return document.body.scrollLeft+event.clientX;
	if(q_bDOM2) return e.pageX;
}

function q_GetEventY(e)
{
	if(q_bIE) return document.body.scrollTop+event.clientY;
	if(q_bDOM2) return e.pageY;
}

function q_ScrollIn(x,y,w,h)
{
	if(f_forcefocus)
	{
		var go = false;
		
		//Current Position
		var stx = 0, sty = 0;
		if(document.body.scrollLeft)
		    stx = document.body.scrollLeft;
		if(document.body.scrollTop)
		    sty = document.body.scrollTop;
		if(window.pageXOffset)
		    stx = window.pageXOffset;
		if(window.pageYOffset)
		    sty = window.pageYOffset;

        if(stx>0 || sty>0)
        {		
		    //Make sure the bottom/right point isn't out of the bottom/right
		    if(x+w>stx+q_GetBrowserWidth()) {go=true; stx = x+w-q_GetBrowserWidth();}
		    if(y+h>sty+q_GetBrowserHeight()) {go=true; sty = y+h-q_GetBrowserHeight();}

		    //Make sure the top/left point isn't out of the top/left (leave 8px gap)
		    if(x<stx) {go=true; stx=x-8; if(stx<0) stx=0}
		    if(y<sty) {go=true; sty=y-8; if(sty<0) sty=0;}
    		
		    //Scroll?
		    if(go) self.scrollTo(stx, sty);
	    }
	}
}

//=========================================================
//=================== FORM OBJECT =========================
//=========================================================


q_Init();


//---------------------------------------------------------
//------------------- Initializing Stuff ------------------
//---------------------------------------------------------


function q_Init()	//Must be called first, while page is loading
{
	var i,j,n;

	//---- Init Global Variables ---

	f_previous_onload = null; // Remember any other script's Onload event(s)
	f_absolute_pos = false;	// false = form is always at same coordinate (provided by User in windows.q_pos)
							// true = form is whereever the Loading pic is (moves on resize)
	f_form_x = 0;		//Current coordinates of form 
	f_form_y = 0;		//Current coordinates of form
	f_page_x = 0;		//Location of page (not skin)
	f_page_y = 0;		//Location of page (not skin)

	f_capturing_control = -1;		//Event handling
	f_flashing_steps = -1;			//Flashing Steps (Countdown)
	f_flashing_controls = null;		//Array of item indexs that are currently flashing
	f_disableskin = true;			//Is set to true once Send button is pressed
	f_confirmationmode = -1;		//Is set when only "Success" (1) or "Failure" (0) messages should be displayed (no form)
	f_current_control = -1;			//Control that has focus (used by scripting)
	f_scripts_disabled = false;		//Used during "Reset"
	f_preloading = false;			//Used during "Preloading Data", so that certain script functions are disabled
	f_multipageprinting = false;	//True while multipage printing is in progress
	f_additional_data = "";			//Additional string that is send with response data (usewd by WorkFlow)
	f_first_time_page = true;		//Used by GoToPage2 to know if it displaying a page for the 1st time
	f_currenteventsource = null;	//Used to avoid endless loops in event triggered scripting
	f_emailembedded = false;		//If true, form is embeded in email
	f_encrypted_preload = new Array();	//Preload data that has been encrypted
    f_debug_obj = null;             //Debug ActiveX object
    f_scripts_stack = new Array();  //Callstack for user scripting
	f_pagehistory = new Array();    //Stack for history of displayed pages

	f_current_page = -1;

	f_pressed_skinbutton = -1;
	f_pressed_skinbutton_x = -1;
	f_pressed_skinbutton_y = -1;
	
	f_msgbox_w = 200;									//Default width of Message box 
	if(f_msgbox_w>f_page_w-8) f_msgbox_w = f_page_w-8;	//Adapt width to small forms
	if(f_msgbox_w<100) f_msgbox_w=120;					//Minimum width
	f_msgbox_h = 150;	//Approx. height of Message box 


	//--- Calculate initial position of form ---
	
	//Did user provide absolute coordinates for the form?
	var p = window["q_pos"];
	if(p)
	{
		f_absolute_pos = true;
		f_form_x = p[0];
		f_form_y = p[1];
	}

	//Calculate page coordinates (not skin)
	f_page_x = f_form_x + f_skin_w;
	f_page_y = f_form_y + f_skin_h;


	//--- Decode Texts ---
	
	for(i=0; i<q_Texts.length; i++)
		q_Texts[i] = q_StupidDecode(q_Texts[i]);
		
	
	//--- Parse QueryString ---
	
	f_querystring = new Array();
	var qs = ""+location.search;
	if(qs.length>1)
	{
		qs = q_Unescape(qs.substring(qs.lastIndexOf("?")+1));
		var s = qs.split("&");
		for(i=0; i<s.length; i++)
		{
			var ss = s[i].split("=");
			if(ss.length>1)
				f_querystring[ss[0]] = ss[1];
		}
	}	


	//--- Parse Encoded QueryString ---
	
	if(f_querystring["qp"])
	{
		var s = q_QueryStringDecode(f_querystring["qp"], parseInt("0x"+f_guid.substring(0,2))&255).split("&");
		for(i=0; i<s.length; i++)
		{
			var ss = s[i].split("=");
			if(ss.length>1)
				f_querystring[ss[0]] = ss[1];
		}	
	}
			
			
	//--- Confirmation Mode (Data Success or Failure message only) ---
	
	var cf = f_querystring["fcSuccess"];
	if(cf=="0" || cf=="1") f_confirmationmode = parseInt(cf);
	
	//Special cases of AfterSend that affect Confirmation Mode
	switch(f_querystring["fcAfterSend"])
	{
		case "5":	//Re-start the form without confirmation

			if(f_confirmationmode==1)
			{			
				//Success: Restart form
				var l = "" + self.location;
				self.location = l.substring(0, l.lastIndexOf("?"));
			}	
			else
			{
				//Failure: Show failure confirmation with restart-link
				f_querystring["fcAfterSend"] = "1";
			}
			break;
			
		case "6":	//Close the browser window without confirmation

			if(f_confirmationmode==1)
			{			
				//Success: Close window
				self.close();
			}
			else
			{
				//Failure: Show failure confirmation with close-link
				f_querystring["fcAfterSend"] = "2";
			}
			break;
	}
		

	//--- Is there a RID ? ---
	
	f_rid = ""+f_querystring["fcRID"];
	if(f_rid.indexOf("undefined")>=0) f_rid="";


	//--- Preload Images ---

	f_loading = new Image();						//Loading image used in HTML
	f_loading.src = f_resources_path + "sl.gif";	//Must be first so it shows quickest
	f_resources_app = Array("gif", "jpg", "wav", "mid", "mp3");
	f_resources_n = f_resources_type.length; //Number of Resources

	//Control's Images Resources
	f_resources = new Array();						//0 must always be nope.gif; 1-5 must be Quask logo
	var m = (f_confirmationmode<0)?f_resources_n:6;	//Only do 1st 5, if in confirmation mode
	for(i=0; i<m; i++)
	{
		f_resources[i] = new Image();
		f_resources[i].src = f_resources_path + i + "."+f_resources_app[f_resources_type[i]];
	}

    if(f_skin)
    {
	    //Skin Buttons Images
	    f_skin_but_n = new Array();	//Normal State
	    f_skin_but_p = new Array(); //Pressed State
	    var si=0;
	    if(f_skin_btns==1) si=3;	//Preload Send/Reset/Print
	    if(f_skin_btns>1) si=5;		//Preload all buttons
	    for(i=0; i<si; i++)
	    {
		    f_skin_but_n[i] = new Image();
		    f_skin_but_n[i].src = f_resources_path + "s"+(5+i*2)+".gif";
		    f_skin_but_p[i] = new Image();
		    f_skin_but_p[i].src = f_resources_path + "s"+(6+i*2)+".gif";
	    }
    	
	    //Skin Quask Logo
	    f_skinlogo = f_resources_path+"s4.gif";
    }
    

    //--- Create Page and Control Objects ---
    
	//Don't do all the page and object creation, if in confirmation mode
	if(f_confirmationmode<0)
	{		
		
		//--- Create Pages Objects ---

		f_pages_n = f_page_def.length;	//Number Of pages in Form
		f_pages = new Array();
		for(i=0; i<f_pages_n; i++) f_pages[i] = new q_page(i, f_page_def[i]);

		//Page order
		f_page_order = new Array();
		for(i=0; i<f_pages_n; i++) f_page_order[i] = i;
		
		//Randomize Page Order					
		var random_found = -1;
		for(i=0; i<=f_pages_n; i++)
		{
			if(i!=f_pages_n && f_pages[i].randomize)
			{
				//New Randomize Sequence found
				if(random_found<0) random_found=i;
			}
			else 
			{
				if(random_found>=0)
				{
					//Existing Randomize Sequence has ended
					q_Randomize(f_page_order, random_found, i);
					random_found = -1;
				}
			}
		}
		
		//Page Order set from pre-load data?
		i = "qo_po";
		j = ",";
		n = null;
		if(f_encrypted_preload[i]) n = f_encrypted_preload[i].split(j);
		if(window[i]) n = window[i].split(j);
		if(f_querystring[i]) n = f_querystring[i].split(j);
		if(n!=null && n.length==f_page_order.length)	//Validate
			f_page_order = n;

		
		//--- Create Controls Objects ---

		f_controls_n = f_controls_def.length-1;	//Number of controls in form
		f_controls = new Array(f_controls_n);
		for(i=0; i<f_controls_n; i++)
		    f_controls[i] = new q_ctrl(i, f_controls_def[i]);
		
	
		//--- Is it Single Response and already answered? ---
		
		if(f_singleresponse && q_CheckSingleResponse(f_rid + f_guid))
			f_confirmationmode = 2;


		//-- Handle Email Embed stuff ---
		
		if(window.qs_emailembedded)
		{
			f_emailembedded = true;
			
			//Follow up URLs (cannot come back to myself)
			if(f_success_url=="") f_success_url = f_self_url; 
			if(f_failure_url=="") f_failure_url = f_self_url; 
		}
	}


	//--- System Variables (they are sent to the Data-handling script) ---
	
	f_system = new Array();
	
	//Default Send/Failure URLs
	if(f_success_url=="") f_success_url = self.location;
	if(f_failure_url=="") f_failure_url = self.location;

	//Source location (is it only relative or full?)
	if(f_src_url.indexOf("//")<0)
	{
		//Construct full path
		var l = self.location,
			pn = l.pathname,
			pns = pn.lastIndexOf("/");
		if(pns>0) pn = pn.substring(0, pns);
		else pn = "";
		f_src_url = "http://" + l.host + pn + "/" + f_src_url;
	}
		
	//Set required values. More can be added by scripting
	f_system["appName"] = "HTML Form";
	f_system["appVersion"] = f_appversion;
	f_system["guid"] = f_guid;
	f_system["version"] = f_version;
	f_system["tag"] = f_tag;
	f_system["title"] = f_title;
	f_system["successURL"] = f_success_url;
	f_system["failureURL"] = f_failure_url;
	f_system["singleResponse"] = f_singleresponse?"true":"false";
	f_system["rid"] = f_rid;
	f_system["source"] = f_src_url;
	f_system["afterSend"] = f_aftersend;
	f_system["ipAddress"] = ""; //To be filled in by ASP/PHP script
	f_system["workflowstage"] = f_initial_workflowstage;	//Default
	f_system["workflowlevel"] = f_intitial_workflowlevel;	//Default
	f_system["WFSCtr"] = 0;     //WorkFlow Counter
    f_system["WFFCtr"] = 0;     //WorkFlow Counter
	//f_system["started"] = 0;	//Used by split-page, if 1 then this is not the 1st time we are starting..


	//---- Decrypt Encrypted Preload Data ---
	
	if(f_encryption && window["q_epl"])
	{
		//Get it and split it by line ("\n")
		var arr = (q_DecryptPreloadData(window["q_epl"])).split("\n");
		n=0;
		for(i=0; i<arr.length; i++)
		{
			//Find first "="
			var g=arr[i].indexOf("=");
			if(g>0) f_encrypted_preload[n++] = Array(arr[i].substring(0,g), arr[i].substring(g+1));
			//alert(arr[i]);
		}
	}

	//--- Preload any System Variables / Form Properties ---

	//Overrides from Encrytped Preload Data
	for(n in f_encrypted_preload) q_HandlePreloadPoperties(f_encrypted_preload[n][0], f_encrypted_preload[n][1]);

	//Overrides from JavaScript
	for(n in window) q_HandlePreloadPoperties(n, window[n]);

	//Overrides data from QueryString
	for(n in f_querystring) q_HandlePreloadPoperties(n, f_querystring[n]);
}


//--- Write all HTML for Form ---

function q_WriteHTML() //Must be called after q_Init() !!!
{
	var h = "";


    //--- Write some generic styles ---
    
   	var h = '<style type="text/css">';
	
	h +='.st_d {position: absolute; visibility: hidden; top: 0; left: '+((q_bMoz15)?'-1000':'0')+'}\n'
	 +  '#p_d {left: ' + f_page_x + 'px; top: ' + f_page_y + 'px}\n'
	 +	'.st_nb {background-image: none}\n'
	 +	'.st_p {cursor: hand; cursor: pointer}\n'
	 +	'.st_op {filter:alpha(opacity=100)}\n'
	 +	'.st_ql {font-size: ' + ((f_page_w>200)?9:8) + 'pt; font-family: Sans-Serif; color: #637628}\n'
	 +	'.st_ql2 {font-size: ' + ((f_page_w>200)?8:7) + 'pt; font-family: Sans-Serif; color: #939393}\n';

	//Skin Styles
	if(f_skin)
	    h += "#s_d {left: " + f_form_x + "px; top: " + f_form_y + "px}\n"
		 + '.st_bs {background-image: url("'+f_resources_path+'s3.gif")}\n'
		 + '.st_pc {font-size: 9; width: '+(5*f_skin_w)+'}\n';

    h += '</style>\n';


	//Write Sound-Resources <embeds>
	soundfound=false;
	for(var i=0; i<f_resources_n; i++)
	{
		t=f_resources_type[i];
		if(t==2||t==3||t==4)
		{
			//Pre-loads
			//q_PreLoadSound(i);
			soundfound=true;
		}		
	}
	//Object for playing Sound in IE
	if(soundfound) h += '<bgsound id=q_snd_noloop loop=1><bgsound id=q_snd_loop loop=infinite>\n';

	//Write Form for sending data back
	h += '<form name="q_data" method="post"><input type="hidden" name="data" value=0><input type="hidden" name="id" value=0><input type="hidden" name="lookup" value=0><input type="hidden" name="session" value=""></form>\n';
	
	
	//Write Skin layer
	if(f_skin)
	{
		//Skin
		h+= '<div id=s_d class=st_d>'
		+	'<table cellspacing=0 cellpadding=0 border=0 width='+(f_page_w+2*f_skin_w)+'>'
		+		'<tr><td colspan=3 width='+(f_page_w+2*f_skin_w)+' height='+f_skin_h+'><img src="'+f_resources_path+'s0.gif" width='+(f_page_w+2*f_skin_w)+' height='+f_skin_h+'></td></tr>'
		+	'<tr><td width='+f_skin_w+' height='+f_page_h+'><img src="'+f_resources_path+'s1.gif" width='+f_skin_w+' height='+f_page_h+'></td>'
		+			'<td width='+f_page_w+' height='+f_page_h+'><img src="'+f_resources_path+'0.gif" width='+f_page_w+' height='+f_page_h+' galleryimg=no></td>'
		+			'<td width='+f_skin_w+' height='+f_page_h+'><img src="'+f_resources_path+'s2.gif" width='+f_skin_w+' height='+f_page_h+'></td>'
		+	'</tr>'
		+	'<tr><td colspan=3 width='+(f_page_w+2*f_skin_w)+' height='+(f_skin_btns!=4?3:5)*f_skin_h+' valign=center class=st_bs>\n'
		
		+		'<table cellspacing=0 cellpadding=0 border=0 width='+(f_page_w+2*f_skin_w)+'>'
		+			'<form name="f_s_d" method="post">'
		+			'<tr width='+(f_page_w+2*f_skin_w)+'>'
		+				'<td class=st_nb width='+f_skin_w+'><img src="'+f_resources[0].src+'" width='+f_skin_w+' height='+f_skin_h+'></td>';
		
		if(f_unbranded) h += '<td class=st_nb width='+f_skin_w+' valign=top><img src="'+f_resources[0].src+'" width='+f_skin_w+' height='+f_skin_h+'></td>';
		else h += '<td class=st_nb width='+f_skin_w+' valign=top><img src="'+f_skinlogo+'" name=sb_9 width='+f_skin_w+' height='+f_skin_h+' class=st_p></td>';

		h += '<td class=st_nb width='+(f_page_w-f_skin_w)+' align=right>\n';

			
		if(f_skin_btns==0)
		{
			h += "&nbsp;";
		}
		else
		{
			//Write Skin Buttons
			h +=	'<table cellspacing=0 cellpadding=0 border=0>'
				+	'<tr><td align=right class=st_nb>';
			
			//Send & Reset Buttons
			if(f_skin_btns==1||f_skin_btns>=3)
			{
				h +='<table cellspacing=0 cellpadding=0 border=0><tr>'
				 +	'<td><img src="'+f_resources_path+'s5.gif" name=sb_0 width='+3*f_skin_w+' height='+f_skin_h+' class=st_p></td>'
				 +	'<td><img src="'+f_resources_path+'s7.gif" name=sb_1 width='+3*f_skin_w+' height='+f_skin_h+' class=st_p></td>'
				 +	'<td><img src="'+f_resources_path+'s9.gif" name=sb_2 width='+3*f_skin_w+' height='+f_skin_h+' class=st_p></td>'
				 +	'</tr></table>\n';
			}
			
			if(f_skin_btns!=4)
				//On 1 line
				h += '</td><td class=st_nb>';
			else	
				//On 2 lines
				h += '</td></tr><tr><td class=st_nb><img src="'+f_resources[0].src+'" width='+f_skin_w+' height='+f_skin_h+'></td></tr><tr><td class=st_nb align=right>';
			
			//Page Navi Buttons
			if(f_skin_btns>=2)
			{
				h +='<table cellspacing=0 cellpadding=0 border=0><tr>'
				 +		'<td><img src="'+f_resources_path+'s11.gif" name=sb_3 width='+2*f_skin_w+' height='+f_skin_h+' class=st_p></td>'
				 +		'<td><select name="p_cb" onchange="q_SkinPageComboChanged();" class=st_pc>';

				if(f_confirmationmode<0)
				{
					for(var i=0; i<f_pages_n; i++) h += "<option value="+f_page_order[i]+">" + f_pages[f_page_order[i]].name;
				}

				h +=	'</select><br></td>'
				 +		'<td><img src="'+f_resources_path+'s13.gif" name=sb_4 width='+2*f_skin_w+' height='+f_skin_h+' class=st_p></td>'
				 +	'</tr></table>';
			}
			
			//End of buttons
			h += '</tr></table>\n';
		}
		
		//End of Skin
		h += 	'</td>'
		 +	'<td class=st_nb width='+f_skin_w+'><img src="'+f_resources[0].src+'" width='+f_skin_w+' height='+f_skin_h+'></td>'
		 +	'</tr></form></table>'
		 + '</td></tr></table></div>\n';
	}

	//Write page background
	h+=	'<div id="p_d" class="st_d">'
	 +	'<table cellspacing=0 cellpadding=0 border=0 width='+f_page_w+'>'
	 +	'<tr><td width='+f_page_w+' height='+f_page_h+'><img src="'+f_resources[0].src+'" width='+f_page_w+' height='+f_page_h+' galleryimg=no></td></tr>'
	 +	'</table></div>\n';
		    
	//Write it all out
	document.write(h);


	if(f_confirmationmode<0) 	//Don't write these if confirmation screen only
	{
		//Write Trial Version layer
		if(f_trialversion)
			document.write('<div id=p_qtv class=st_d>'+q_GetMsgBoxHTML(q_Texts[5]+'<br><br><a href="#" onmousedown="q_Start2();" class=st_ql>'+q_Texts[14]+'</a>') + '</div>');

		//Write Hour Glass layer
		if(f_hourglass>=0)
			document.write('<div id=p_hrg class=st_d><img src="' + f_resources[f_hourglass].src + '" width=31 height=31></div>');
	}
			

	//Write "Powered by Quask" Logo layer, either
	//-Preview Mode
	//-Sending Data....
	//-Data Successfully Sent
	//-Already filled in
	
	var msg = q_Texts[0];						//"Sending..."
	if(f_emailembedded) msg=q_Texts[16];		//"Sending... Confirmation will be displayed in new window."
	if(f_preview) msg=q_Texts[1];				//"Preview Mode"
	if(f_confirmationmode==0) msg=q_Texts[2] //"Sending failed."
		+ '<br><br><a href="javascript:q_ShowError();" class=st_ql><font size=1>'+q_Texts[15]+'</font></a>'; //"Details..."
	if(f_confirmationmode==1) msg=q_Texts[3];	//"Data Successfully Sent"
	if(f_confirmationmode==2) msg=q_Texts[4];	//"This form can only be filled in once."
	

	//After send behaviour
	if(f_confirmationmode==0 ||f_confirmationmode==1)
	{
		if(f_querystring["fcAfterSend"]=="1")
		{
			var l = "" + self.location;
			l = l.substring(0, l.lastIndexOf("?"));
			msg += '<br><br><a href="'+l+'" class=st_ql>'+q_Texts[13]+'</a>';
		}
		if(f_querystring["fcAfterSend"]=="2")
			msg += '<br><br><a href="javascript:window.close();" class=st_ql>'+q_Texts[12]+'</a>';
	}
	
	document.write('<div id=p_ql class=st_d>'+q_GetMsgBoxHTML(msg)+'</div>');
	
	
	//--- Trap OnLoad and OnUnload events ---

	//Add "OnLoad" event. 
	if(!(q_bMac && navigator.appVersion.indexOf("MSIE 4.")!=-1) && window.onload)	
		f_previous_onload = window.onload;	//Remember if there is already one
	window.onload = q_Start;				//Replace it with ours

	//Add "OnUnLoad" event. 
	window.onunload = q_Unload;				//Replace it with ours

}


//--- Start Form (After page has loaded) ---

function q_Start() 	//Must be called after q_WriteHTML() !!!
{
	//Is there another Event to run OnLoad, if yes execute it?
	if(f_previous_onload!=null) f_previous_onload();
		
	//If not absolut position, move it to right place
	if(!f_absolute_pos) q_RePositionForm();

	//Does form need to be reposition when the browser window changes?
	if(!f_absolute_pos) window.onresize = q_OnResize;

	//Show skin and page background
	if(f_skin) q_SetVisible("s_d", true);
	q_SetVisible("p_d", true);
	
	
	//Preload and ReadOnly (but not if in confirmation mode)
	if(f_confirmationmode<0)
	{
		//Preload
		if(f_allowpreload)
		{
			//Set status flag, to disable certain scripting functions
			f_preloading = true;
	
			//Pre-load from Encrypted Preload String
			for(var n in f_encrypted_preload) q_HandlePreloadData(f_encrypted_preload[n][0], f_encrypted_preload[n][1]);
	
			//Pre-load (and pre-populuate) data from JavaScript
			for(var n in window) q_HandlePreloadData(n, window[n]);
			
			//Pre-load data from QueryString
			for(var n in f_querystring) q_HandlePreloadData(n, f_querystring[n]);
						
			//Clear status flag
			f_preloading = false;
		}
		
		//Global ReadOnly?
		if(f_readonly)
			for(var i=0; i<f_controls_n; i++)
				f_controls[i].SetReadOnly(true);
	}
	
	//Remove Loading Pic
	if(document.images[f_loading_image_id])
		document.images[f_loading_image_id].src = f_resources[0].src;
	
	//Show Confirmation Only?
	if(f_confirmationmode>=0)
	{
		//Set Default-Background Color
		q_SetBackCol("p_d", f_skin_defaultcolor);

		//Show confirmation screen
		q_ShowMsgBox("p_ql");
		
		//That's it
		return;
	}
				
	//Start with Page 1 or show Trial Version screen
	if(f_trialversion)
	{
		//Show trial Screen
		
		//Set Default-Background Color
		q_SetBackCol("p_d", f_skin_defaultcolor);
		
		//Show Box
		q_ShowMsgBox("p_qtv");
		
		//Tiner just in case
		setTimeout("q_Start2();", 5000);
	}
	else q_Start2();
}

function q_Start2()
{
	//Avoid double start (from Tiral Version timer)
	if(f_current_page>=0) return;
		
	//Hide Trial Message
	if(f_trialversion) q_SetVisible("p_qtv", false);
	
	//Initialize browser event capturing
	q_InitEvents();

	//Trigger Scripts/control events
	//if(f_system["started"]==0)
	f_OnFormStart();
			
	//Show 1st page
	//if(f_splitpage && f_system["started"]!=0)
	//	f_GoToPage(f_page_start);
	//else
	if(f_current_page<0) //Only if a particular page is already being shown by OnFormStart event (GoToPage command)
	    f_GoToPage(f_page_order[f_page_start]);
	
	//Enable Skin Buttons
	f_disableskin = false;
			
	//Do Pop-Up Test (display message if pop-up blocker found)
	if(f_requirespopup && !f_preview && !f_readonly)    //f_system["started"]==0 && 
		setTimeout("q_PopUpTest();", 100);

    //Start Keep-Alive Timer
    if(f_keepalive_url!="") q_KeepAlive(false);
        		
	//Split-Page: Remember that this isn't the first time
	//f_system["started"] = 1;
}

//Helper (also called OnResize if form is right/center x-aligned)
function q_RePositionForm()
{
	
	// If relative positionning, update position of form
	if(!f_absolute_pos)
	{
		// Get position of Loading Image is
		var p = q_GetImagePagePos(f_loading_image_id);
		f_form_x = p[0];
		f_form_y = p[1];
	}

	//Re-position skin
	if(f_skin)
	{
		q_SetLeft("s_d", f_form_x);
		q_SetTop("s_d", f_form_y);
	}

	//Calculate page coordinates (not skin)
	f_page_x = f_form_x + f_skin_w;
	f_page_y = f_form_y + f_skin_h;

	//Re-position page background
	q_SetLeft("p_d", f_page_x);
	q_SetTop("p_d", f_page_y);
}

//Enterprise Only: Trigger URL when browser is closed
function q_Unload()
{
    //Notify Debug component
	if(f_debug_obj!=null)
         f_debug_obj.Quit();
    
	//Notify of window close (but only if data wasn't sent yet)
	if(f_unload_url!="" && !f_disableskin && f_confirmationmode<0)
	{
		//Try to create Ajax object
		var req = q_GetHTTPRequestObject();
		if(req) 
		{
			//Yes, do Ajax: Make the synchronous call!
			req.open("GET", f_unload_url, false);
    		req.send(null);
	    	var a = req.responseText; //Wait for, but ignore response
		}
		else
		    //Do pop-up
    		q_OpenWindow(f_unload_url, 200, 100);
	}
}

function q_PopUpTest()
{
	var w = q_OpenWindow(f_data_url, 100, 100);
	if(w==null) alert(q_Texts[20]);
	else w.close();
}



//---------------------------------------------------------
//--------------- Page Navigation Methods -----------------
//---------------------------------------------------------


function f_GoToPage(i, r)  //r=true if Reset button is pressed, this forces OnPageLoad trigger even if already on page 1 
{
	if(i>=0 && i<f_pages_n && (f_current_page!=i || r==true) && !f_preloading)
	{
		//Event Trigger: On Page Unload
		if(f_current_page>=0 && !(r==true) && !f_multipageprinting)
		    f_OnPageBlur(f_current_page); 

		//Add new page to history stack, but not same page twice in arow
		if(!f_multipageprinting && f_pagehistory[f_pagehistory.length-1]!=i)
		    f_pagehistory.push(i);
			
		f_current_page = i;

		//Show hour glass layer?
		//if(f_hourglass>=0 && q_RepositionCtrlsInBackground() && f_controls_repositioned<f_controls_n && !f_multipageprinting)
		//{
		//	//Yes
		//	q_ShowHourGlassLayer();
		//	setTimeout("q_GoToPage2();", 1);
		//}
		//else
		//{
		//	//No
			q_GoToPage2();
		//}
	}
}

function q_GoToPage2()
{	
	//Change cursor
	q_SetHourglass(true);
		
	//Hide Controls from previous page
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].showing && f_controls[i].page!=f_current_page)
			f_controls[i].Show(false);
	
	//Set Background Color
	q_SetBackCol("p_d", f_pages[f_current_page].color);
	
	//Show Controls from current page
	for(var i=0; i<f_controls_n; i++)
	{
		if(f_controls[i].page==f_current_page && !f_controls[i].showing)
			f_controls[i].Show(true);
	}
			
	//Make sure it's in view (but not the 1st time)
	if(f_first_time_page)
		f_first_time_page = false;
	else
		q_ScrollIn(f_page_x, f_page_y, f_page_w, f_page_h);
	
	//Set the right combox-item in skin's page selection
	if(f_skin_btns>=2) q_SetSelectedValue("s_d", "p_cb", q_GetIndex(f_page_order, f_current_page));

	//Change cursor
	q_SetHourglass(false);

	//Hide hour glass layer
	//if(f_hourglass>=0 && q_RepositionCtrlsInBackground())
	//		q_SetVisible("p_hrg", false);

	//Event Trigger
	if(!f_multipageprinting) f_OnPageFocus(f_current_page);
}

//Split-Pages: Show page a new URL
function q_GoToPageURL2(i)
{
	return q_PostToURL(f_self_url, false, escape(q_GetDataXML()), i);
}

function q_PrevPage()
{
	//Get order position of current page
	var o = q_GetIndex(f_page_order, f_current_page);
	
	if(o>0) f_GoToPage(f_page_order[o-1]);
}

function q_NextPage()
{
	//Get order position of current page
	var o = q_GetIndex(f_page_order, f_current_page);

	if(o<f_pages_n-1) f_GoToPage(f_page_order[o+1]);
}

function q_BackHistoryPage() //Goes to previously displayed page (like in Browser)
{
   	//Get from history stack and show it
    if(f_pagehistory.length>1)
    {
        //Remove current page
        f_pagehistory.pop();
        
        //Get previous page, but leave it on stack
	    f_GoToPage(f_pagehistory[f_pagehistory.length-1]);
	}
}

function q_GoToPageName(name)
{
	for(var i=0; i<f_pages_n; i++)
	{
		if(f_pages[i].name==name)
		{
			f_GoToPage(i);
			return;			
		}
	}
}

function q_GoToPageID(id) //Used by scripting
{
	for(var i=0; i<f_pages_n; i++)
	{
		if(f_pages[i].id==id)
		{
			f_GoToPage(i);
			return;			
		}
	}
}

function f_HidePage()	//Important: No OnPageFocus/Blur events are trigged here
{
	//Hide Controls
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].showing)
			f_controls[i].Show(false);
			
	//Set Default-Background Color
	q_SetBackCol("p_d", f_skin_defaultcolor);
}

function q_GoToControl(id, h) //h = highlight true/false
{
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].id==id)
		{
			var c = f_controls[i];
			
			//Move to page where this control is located
			f_GoToPage(c.page);
			
			//Make sure control is visible
			if(!c.GetVisible()) c.SetVisible(true);
				
			//Make sure it is in view
			q_ScrollIn(f_page_x + c.x, f_page_y + c.y, c.width, c.height);
			
			//Start highlighting "Flashing"
			if(h) c.StartFlashing(6);
			
			return;
		}
}

function q_ShowHourGlassLayer()
{
	var id="p_hrg";
	q_SetLeft(id, f_page_x+(f_page_w-31)/2);
	q_SetTop(id, f_page_y+(f_page_h-31)/2);
	q_SetZOrder(id, "99999");
	q_SetVisible(id, true);
}

function q_GetSelectedValue(id, eid)
{
	var i=document.forms["f_"+id].elements[eid].options.selectedIndex;
	if(i<0)return null;
	else return document.forms["f_"+id].elements[eid].options[i].value;
}
function q_SetSelectedValue(id, eid, i)	{document.forms["f_"+id].elements[eid].options[i].selected=true;}



//---------------------------------------------------------
//--------------- Data Send/Reset Methods -----------------
//---------------------------------------------------------


function q_SendData(p)
{
	//Don't send if ReadOnly
	if(f_readonly) return;

	//Change AfterSend mode?
	if(p*1==p) f_system["afterSend"] = ""+p;
	
	//Check Obligatory Stuff
	var ok = true;
	for(var i=0; i<f_controls_n; i++)
	{
		var c = f_controls[i];
		 
		if(c.CheckValid()!=null)
		{
			//Invalid field found!
			alert(c.CheckValid());
			ok = false;
		}

		if(!c.CheckObligatory())
		{
			//Unanswered obligatory field found!
			alert(q_Texts[6]);
			ok = false;
		}
		
		if(!ok)
		{	
			//Move to page where this control is located
			f_GoToPage(c.page);
			
			//Start "Flashing"
			c.StartFlashing(6);
						
			//Don't continue sending
			return;
		}	
	}
		
	//Event Trigger (Form OnSend) (if return value is true, abandon sending)
	if(f_events!=0 && q_RunScript(f_events[1])) return;

	//Is it demo mode?
	if(f_aftersend=="9")
	{
		window.close();
		return;
	}

	//Obligatory test passed: Get XML data, and send it
	
	//Show "Sending..." msg
	f_HidePage();	
	f_disableskin = true;		//Disable buttons from now on
	q_ShowMsgBox("p_ql");
	
	//Submit form to data url
	if(!f_preview)
	{
		var f = document.forms["q_data"];
		f.action= f_data_url;
		f.target = (f_emailembedded)?"_blank":"_self";

		//Get Data
		var d = q_GetDataXML();		
		if(f_encryption && q_Encrypt_Key) d = "#QFS#" + q_EncryptResponseData(d);	//Encryption
		else d = escape(d);															//No encryption
		f.elements["data"].value = d; 
		f.elements["session"].value = window["q_se"];


		if(f_sendformmanager)
		{
			//Send the FormManager way
			window.status = "_fm_";
		}
		else
		{	
			//Send by POST			
			
			//If Branded and custom follow-up URLs, delay so the Quask message shows
			if(f_unbranded || (f_system["successURL"]==self.location && f_system["failureURL"]==self.location))
				f.submit();
			else
				setTimeout("document.forms['q_data'].submit();", 2800);
		}
	}
}


function q_GetDataXML()
{
	var xml, na;
		
	//Compile <fields> tag with all field=data inside
	xml = '<fields';

	for(na in f_system) xml += ' ' + na + '="' + q_XMLEncode(f_system[na]) + '"';

	//Store Time Stamp
	var dt = new Date();
	xml += ' time="' + q_ForceDigits(dt.getUTCFullYear(), 4) + q_ForceDigits(dt.getUTCMonth()+1, 2)
			+ q_ForceDigits(dt.getUTCDate(), 2) + " " + q_ForceDigits(dt.getUTCHours(), 2) + ":"
			+ q_ForceDigits(dt.getUTCMinutes(), 2) + ":" + q_ForceDigits(dt.getUTCSeconds(), 2) + '">';
	
	//Add each control's data
	for(var i=0; i<f_controls_n; i++)
	{
		//Get Data
		var c = f_controls[i];
		var d = c.GetData();
		
		//Get <field> tags
		if(d!=null)
			for(var j=0; j<d.length; j++)
				xml += q_GetFieldXMLTag(d[j], c);
	}
		
	//Pass "fc"-variables from QueryString
	var fn;
	for(fn in f_querystring)
		if((fn+"xx").substring(0,2)=="fc")
				xml += '<field id="'+(fn+"").substring(2)+'">'+f_querystring[fn]+'</field>';
	
	//Add form state info
	if(1)
	{	
		//Form State
		xml += "<state><page>"+f_current_page+"</page><pagehistory>"+f_pagehistory+"</pagehistory><pageorder>"+f_page_order+"</pageorder>";
		var s="";
				
		//Controls State
		for(var i=0; i<f_controls_n; i++)
		{
			var c = f_controls[i];
			
			if(c.changed>0)
			{
				//Also send changed properties info
				s += '<object id="'+c.id+'"';					
				
				if(c.changed&1) s += ' x="' + c.x + '"';
				if(c.changed&2) s += ' y="' + c.y + '"';
				if(c.changed&4) s += ' zorder="' + c.zorder + '"';
				if(c.changed&8) s += ' backcol="' + c.backcol + '"';
				if(c.changed&16) s += ' enabled="' + (c.enabled?1:0) + '"';
				if(c.changed&32) s += ' readonly="' + (c.readonly?1:0) + '"';
				if(c.changed&64) s += ' shaded="' + (c.shaded?1:0) + '"';
				if(c.changed&128) s += ' visible="' + (c.visible?1:0) + '"';
				if(c.changed&256) s += ' tag="' + q_XMLEncode(c.tag) + '"';
				if(c.changed&512) s += ' transparency="' + c.transparency + '"';
				if(c.changed&2048) s += ' source="' + q_XMLEncode(c.source) + '"';
				if(c.changed&4096) s += ' caption="' + q_XMLEncode(c.caption) + '"';
				if(c.changed&8192) s += ' touched="' + (c.untouched?0:1) + '"';
				if(c.changed&16384) s += ' lastselected="' + c.lastselected + '"';
				if(c.changed&32768) s += ' flashing="' + c.flashing + '"';
				if(c.changed&1024)
				{
				    //Answers can be array, or string
				    if(q_IsArray(c.changedanswers))
	   			        for(var j in c.changedanswers)
	    			        s += ' answers_' + j + '="' + q_XMLEncode(c.changedanswers[j]) + '"'; 
				    else
				        s += ' answers="' + q_XMLEncode(c.changedanswers) + '"'; 
				}

				s += '/>';					
			}
		}
		
		xml += s+"</state>";
	}
		
	//Additional data and closing field tag
	xml += f_additional_data + '</fields>';
	
	//Add parent tags
	return q_GetParentXMLTag(xml);
}

//Data XML Helper: Put parent tags around <fields> tag
function q_GetParentXMLTag(f) //f=<fields> tag string
{
	// '<?xml version="1.0" encoding="ISO-8859-1" ?>'

	return 	'<quaskformdata xmlns="http://www.quask.com/quaskformserver/quaskformdata">'
		+	'<forms><form guid="'+f_guid+'"><data>'
		+	f
		+	'</data></form></forms></quaskformdata>';
}

//Data XML Helper: Return <field> tag
function q_GetFieldXMLTag(d, c) //d=data string, c=control
{
	//Default
	var xml = "";
	
	//Split from first |
	var s = d.indexOf("|"); 
	if(s>0)
	{
		xml += '<field id="'+d.substring(0, s)+'"';
		if(c!=null && ((""+c.tag).length>0 || (c.changed&256)>0)) xml += ' tag="' + q_XMLEncode(c.tag) + '"';
		xml += '>'+q_XMLEncode(d.substring(s+1))+'</field>';
	}
	
	return xml;
}

//Customization for Customer
function q_GetDataXMLAlt()
{
	//Default
	var xml = "";
	
	//Add each control's data
	for(var i=0; i<f_controls_n; i++)
	{
		//Get Data
		var c = f_controls[i];
		var d = c.GetData();
		
		//Get fields
		if(d!=null)
			for(var j=0; j<d.length; j++)
			{
	            //Split from first |
	            var s = d[j].indexOf("|"); 
	            if(s>0)
	            {
	                //Tag name
	                var n = "field_"+d[j].substring(0, s);
	                
	                //Add tag
		            xml += '<' + n;
		            if((""+c.tag).length>0 || (c.changed&256)>0) xml += ' tag="' + q_XMLEncode(c.tag) + '"';
		            xml += '>'+q_XMLEncode(d[j].substring(s+1))+'</'  + n + '>';
	            }
			}
	}
	
	//Add parent tags
	return q_GetParentXMLTag(xml);
}

function q_ResetData()
{
	//Don't send if ReadOnly
	if(f_readonly) return;

	//Ask first
	if(confirm(q_Texts[7])) //"Are you sure you want to reset each field in this form?"
	{
		//Event Trigger (Form OnReset)
    	if(f_events!=0)
	    	q_RunScript(f_events[2]);
		
		//Reset each control
		for(var i=0; i<f_controls_n; i++) f_controls[i].ResetData();
		
		//Go to first page
		f_GoToPage(0, true); //true = special event trigger mode
	}
}

//Flashing controls timer
function q_Flashing()
{
	if(f_flashing_controls!=null)
	{
		//Handle multiple items
		for(var j=0; j<f_flashing_controls.length; j++)
		{
			var c = f_flashing_controls[j];
			c.flashing = f_flashing_steps;	//Update state info
			c.Show(f_flashing_steps&1 && c.page==f_current_page);
		}
	
		//Count down	
		f_flashing_steps--;
		
		if(f_flashing_steps>0)
		{	
			//Keep flashing
			setTimeout("q_Flashing();", 300);
		}	
		else
		{
			//Stop flashing
			for(var j=0; j<f_flashing_controls.length; j++)
			{
				var c = f_flashing_controls[j];
				c.flashing = 0;				//Clear state info
				c.changed &= (-32769);		//Clear state info (hex FFF7FFF)
				c.Show(c.visible && c.page==f_current_page);
			}
			
			//Clear Array
			f_flashing_controls = null;
		}
	}
}



//---------------------------------------------------------
//-------------------- Preload Helpers ---------------------
//---------------------------------------------------------


//--- Preloading (form) properties (before form objects are created, q_Init) ---

function q_HandlePreloadPoperties(name, value)
{
	//Unload function?
	if(name=="q_ul") f_unload_url = value;

	//2nd part of name
	var e = name.substring(3);				

	switch(name.substring(0,3))
	{ 
	case "qs_":
		f_system[e] = value;
		return;

	case "qf_":
		 return q_SetFormProperty(e, value);
	}
}


//--- Preloading (object) data (after objects have been created, in q_Start) ---

function q_HandlePreloadData(name, value)
{
	//Object ID
	var e = name.substring(3);				
	
	switch(name.substring(0,3))
	{ 
	case "qa_":
		return q_SetAnswers(e, value);

	case "qd_":
		return q_SetData(e, value);
		
	case "qt_":
		return q_SetDataByTag(e, value);
		
	case "qo_":
		return q_SetStateProperties(e, value);
	}
}

function q_SetData(fieldname, value)
{
	//Check all controls if they "own" this fieldname
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].SetData(fieldname, value)) return true;
		
	//No control replied
	return false;
}


function q_SetDataByTag(tagname, value)
{
	//Check all controls if they "own" this tag name
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].tag.toLowerCase()==tagname.toLowerCase())
			return f_controls[i].SetValue(value);
		
	//No control found
	return false;
}


function q_SetStateProperties(id, p)
{
	//Form State
	switch(id)
	{
		case "pn":	//Current Page Number (Start page)
			f_page_start = parseInt(p);
			return;

		case "ph":	//Page History
			f_pagehistory = p.split(",");
			return;
	}
	
	//Object State
	var c = q_GetControlByID(id);
	if(c!=null)
	{
		var pr = p.split(";");
		for(var i=0; i<pr.length; i++)
		{
			var po = pr[i].split("=");
			if(po.length>1)
			{
				var a = po[1];
				switch(po[0])
				{
				case "x":
					c.SetX(parseInt(a));
					break;
					
				case "y":
					c.SetY(parseInt(a));
					break;

				case "zorder":
					c.SetZOrder(parseInt(a));
					break;

				case "backcol":
					c.SetBackCol(a);
					break;

				case "enabled":
					c.SetEnabled(a>0);
					break;

				case "readonly":
					c.SetReadOnly(a>0);
					break;

				case "shaded":
					c.SetShaded(a>0);
					break;

				case "visible":
					c.SetVisible(a>0);
					break;

				case "tag":
					c.SetTag(a);
					break;
					
				case "transparency":
					c.SetTransparency(parseInt(a));
					break;

				case "answers":
					c.SetAnswers(a);
					break;
					
				case "source":
					c.SetSource(a);
					break;
					
				case "caption":
					c.SetCaption(a);
					break;
					
				case "touched":
					c.SetUntouched(a==0);
					break;
					
				case "lastselected":
					c.lastselected = parseInt(a);
					break;
					
				case "flashing":
					c.StartFlashing(parseInt(a));
					break;

				case "downloadurl":
					c.SetDownloadURL(a);
					break;
					
				default:
					//Special case: Table object can have array of answers (e.g."answers_3")
					if(po[0].indexOf("answers_")==0)
						c.SetAnswers(a, parseInt(po[0].substring(8)));
				}
			}
		}
	}
}


function q_SetAnswers(ctrlid, answers)
{
	var c = q_GetControlByID(ctrlid);
	if(c!=null) c.SetAnswers(answers);
}



//---------------------------------------------------------
//-------------------- Misc Methods -----------------------
//---------------------------------------------------------


function q_Print()
{
	if(f_pages_n==1 || f_splitpage)
	{
		//Only one page to print
		window.print();
	}
	else
	{
		//More than one page to print
		if(q_SupportsMultipagePrinting())
		{
			if(confirm(q_Texts[9]))
						// "You will be presented with a Print dialog for each page in this form.\n\r\n\r"
						// "Press 'Print' on each dialog to print the complete form.\n\r\n\r"
						// "Alternatively, you can print single pages using your Browser's print function."
			{
				//Remember current page
				var p = f_current_page;
				
				//Print each page
				f_multipageprinting = true;		//Make sure hourglass is not shown etc...
				for(var i=0; i<f_pages_n; i++)
				{
					f_GoToPage(i);
					window.print();
				}
				
				//Go back to current page
				f_GoToPage(p);
				f_multipageprinting = false;	//Default
			}
		}
		else
		{
			if(confirm(q_Texts[10]))
					// "Your browser only supports printing one page at the time.\n\r\n\r"
					// "Only the current page will be printed.\n\r\n\r"
					// "Navigate to the other pages and press Print again after this page has finished printing."
			{
				//Print current page
				window.print();
			}
		
		}
	}
}

function q_ShowURL(u, b, x, y)	//u=URL, b=Minimal Style?, x,y = Size
{
	if(b)q_OpenWindow(u, x, y);
	else window.open(u);
}

function q_PostToURL(u, b, da, id, x, y)	//u = URL, b = open new Window?, da = Data-Param, id = ID-Param, x,y = Size of new window
{
    //Get form
    var f = document.forms["q_data"];

    //Open New Window ?
    if(b)
    {
        //New window
        var n = "wnd"+Math.floor(Math.random()*100000);
	    window.open("", n, "location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes"
	             + ((x>0)?(",width="+x):"")
	             + ((y>0)?(",height="+y):""));
        f.target = n;
    }
    else
    {
        //Same window as form
        f.target = "_self";
    }    

    f.action = u;
    f.elements["data"].value = da;			//Data Param
    f.elements["id"].value = id;			//Page Param (Split Page forms only) / Callback script ID
    f.submit();
    return;
}

function q_OpenWindow(url, x, y)
{
	return window.open(url, "_blank", "location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,width="+x+",height="+y);
}

function q_ShowMessage(text)
{
	alert(text);
}

function q_ShowError()
{
	q_ShowMessage(f_querystring["fcErr"]);
}

function q_ShowDialog(text)
{
	return confirm(text);
}

function f_PlaySound(i, loop)
{
	q_PlaySound(i, loop);
}

function q_CheckSingleResponse(id)
{
	var c = (document.cookie+"").split("; ");
	for (var i=0; i<c.length; i++)
	{
		var s = c[i].split("=");
		if(s.length>1 && s[0]==id && s[1]=="1") return true;
	}
	return false;
}

function q_Randomize(arr, ib, ie) //array, begin-index, end-index
{
	for(var i=0; i<(ie-ib); i++)
	{
		var s0 = ib+Math.floor(Math.random()*(ie-ib));
		var s1 = ib+Math.floor(Math.random()*(ie-ib));
	
		//Swap indexes
		var o = arr[s0];
		arr[s0] = arr[s1];
		arr[s1] = o;
	}
}

function q_KeepAlive(b)
{
	//Try to create Ajax object
	var req = q_GetHTTPRequestObject();
    if(req)
    {
        if(b)
        {
            //Make call to server
		    req.onreadystatechange = 		
		    function()
		    {
		        //Don't do anything really, ignore response
			    if (req.readyState==4 && req.status == 200)
				    a=0;
		    };
			
		    req.open("GET", f_keepalive_url, true);
			req.send(null);
	    }
        
        //Set timer for next one
 		setTimeout("q_KeepAlive(true);", f_keepalive_mins*60000);
 	}
}


//---------------------------------------------------------
//-------------- Message Box Methods ----------------------
//---------------------------------------------------------


function q_ShowMsgBox(id)
{
	var x = f_page_x+(f_page_w-f_msgbox_w)/2-2;
	var y = f_page_y+(f_page_h-f_msgbox_h)/2;
	if(y<f_page_y+2) y=f_page_y+2;
	
	q_SetLeft(id, x);
	q_SetTop(id, y);
	q_SetBackCol(id, "ffffff");
	q_SetBorder(id, 2, "000000");
	q_SetVisible(id, true);
	
	q_ScrollIn(x, y, f_msgbox_w, f_msgbox_h);
}

function q_GetMsgBoxHTML(msg)
{
	var c = '<br>';
	if(f_page_h<100)c='';
	
	c = '<table cellspacing=0 cellpadding=0 border=0 width='+f_msgbox_w+'>'
	+	'<tr><td colspan=2 align=center valign=center bgcolor=#ffffff><table cellspacing=0 cellpadding=10 border=0><tr><td class=st_ql><center>'+c+msg+'<br>'+c+'</td></tr></table></td></tr>'
	+	'<tr><td colspan=2 bgcolor=#000000><img src="'+f_resources[0].src+'" width=1 height=1></td></tr>';

	if(!f_unbranded)
		c +=	'<tr><td bgcolor=#F3F3F3 class=st_ql2 align=right valign=center width='+(f_msgbox_w-25)+'>&nbsp;&nbsp;'+q_Texts[11]+'</td>'
			+	'<td bgcolor=#F3F3F3 width=25><a href="http://'+q_GetQuask()+'" target=_blank>'
			+   '<img src="'+f_resources[1].src+'" width=10 height=25 border=0>'
			+   '<img src="'+f_resources[2].src+'" width=2 height=25 border=0>'
			+   '<img src="'+f_resources[3].src+'" width=2 height=25 border=0>'
			+   '<img src="'+f_resources[4].src+'" width=2 height=25 border=0>'
			+   '<img src="'+f_resources[5].src+'" width=9 height=25 border=0>'
			+	'</a></td></tr>';
			
	c += '</table>';
	
	return c;
}



//---------------------------------------------------------
//---------------- Scripting Methods ----------------------
//---------------------------------------------------------


function q_RunScript(id, p, e) //p=Params e=Event Source
{
	//Don't do any scripts if no-script property or disabled
	//Don't do any scripts during Pre-Loading if in SplitMode and follow-up page
	if(id=="" || f_noscripts || f_scripts_disabled || f_preloading) return; //|| (f_splitpage && f_preloading && f_system["started"]>0)

	//Avoid endless loops, part 1
	if(arguments.length>2)
	{
		//Only if eventsource is specified
		if(f_currenteventsource==e) return null;
		f_currenteventsource = e;
	}
	
	//Get current page / control
	var r, current_page_id = "", current_control_id = "";
	if(f_current_page>=0) current_page_id = f_pages[f_current_page].id;
	if(f_current_control>=0) current_control_id = f_controls[f_current_control].id;

	//Avoid repeat endless loops, by checking stack
	for(i in f_scripts_stack)
		if(f_scripts_stack[i]==id)
			return null;

    //Maintain call stack
    f_scripts_stack.push(id);

	//Run the script
	r = q_RunScript2(id, current_control_id, current_page_id, p);
	
    //Maintain call stack
    f_scripts_stack.pop();
	
	//Avoid endless loops, part 2. Only if eventsource is specified
	if(arguments.length>2)
		f_currenteventsource = null;
	
	return r;
}

function q_RegisterFocus(i) //Called by each control when it gains focus (i=index)
{
	//Notify previous control that his has lost its focus
	if(f_current_control>=0 && f_current_control!=i && f_controls[f_current_control].OnFocusLost!=null)
		f_controls[f_current_control].OnFocusLost();
		
	//Remember new control
	f_current_control = i;
}

function q_CallScript() //Sub-function call from witin other script, felxible argument length
{
	var p = new Array();
	for(var i=0; i<arguments.length-1; i++) p[i]=arguments[i+1];
	return q_RunScript(arguments[0], p);
}

function q_Quit(b) //Used by scripting only
{
	f_HidePage();
	f_disableskin = true;		//Disable buttons from now on
	if(b==1)
	{
		//Hide Skin and Page Background
		if(f_skin)q_SetVisible("s_d", false);
		q_SetVisible("p_d", false);
	}
	if(b==2)window.close();
}

function q_SetFormProperty(n, v)
{
	//Override Form Properties
	switch(n)
	{
		case "readonly":
			f_readonly = q_IsTrue(v);
			break;
			
		case "forcefocus":
			f_forcefocus = q_IsTrue(v);
			break;
	}
}

function q_Debug(a, b, c)
{
    //Create object 1st time round
    if(f_debug_obj==null)
    {
		try
		{
    		if(window.ActiveXObject) 
				f_debug_obj = new ActiveXObject("FAVSDebug.JSDebugger");
		}
		catch(e)
		{
			f_debug_obj = null;
		}
	}

	//Make the call	
	if(f_debug_obj!=null)
         f_debug_obj.DebugCommand(a, b, q_GetDataXML(), c);
}

function q_IsTrue(v)
{
	v=(v+"").toLowerCase();
	return (v=="1"||v=="true");
}

function q_SetSystemProperty(n, v)
{
	f_system[n] = v;
}

function q_GetSystemProperty(n)
{
	return f_system[n];
}

function q_DateDiff(d1, d2, u, wd)
{
    d = (d2.getTime()-d1.getTime())/1000;
    
    switch(u)
    {            
        case 'y':
            d /= 365;
            
        case 'd':
            d /= 24;
        
        case 'h':
            d /= 60;

        case 'n':
            d /= 60;
            break;

        case 'w':
            d /= 604800;
            break;

        case 'm':
            d /= 2592000;
            break;
    }
    
    return Math.floor(d);
}

function q_DateAdd(d, n, u, wd)
{
    var r = new Date;
    r.setTime(d.getTime());
    switch(u)
    {
        case 's':
            r.setSeconds(r.getSeconds()+n);
            break;
            
        case 'n':
            r.setMinutes(r.getMinutes()+n);
            break;

        case 'h':
            r.setHours(r.getHours()+n);
            break;
            
        case 'd':
            r.setDate(r.getDate()+n);
            break;
            
        case 'w':
            r.setDate(r.getDate()+7*n);
            break;

        case 'm':
            r.setMonth(r.getMonth()+n);
            break;
            
        case 'y':
            r.setFullYear(r.getFullYear()+n);
            break;
    }
    
    return r;
}

function q_FormatDate(d, s)
{
    //Constants
    var m = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
	var w = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");

    //Day
    s = q_Replace(s, "%j", d.getDate()); //Day of month
    s = q_Replace(s, "%d", q_ForceDigits(d.getDate(), 2)); //Day of month (with leading 0)
    s = q_Replace(s, "%D", w[d.getDay()].substring(0, 3)); //Weekday (3 letters)
    s = q_Replace(s, "%l", w[d.getDay()]); //Weekday (full name)
    
    //Month
    s = q_Replace(s, "%F", m[d.getMonth()]); //Month (full name)
    s = q_Replace(s, "%m", q_ForceDigits(d.getMonth()+1, 2)); //Month (number with leading 0)
    s = q_Replace(s, "%M", m[d.getMonth()].substring(0, 3)); //Month (3 letters)
    s = q_Replace(s, "%n", d.getMonth()+1); //Month (number)
    
    //Year
    s = q_Replace(s, "%y", d.getYear()); //Year (2 digits)
    s = q_Replace(s, "%Y", d.getFullYear()); //Year (4 digits)
    
    //Time
    s = q_Replace(s, "%g", (d.getHours()%12==0)?12:(d.getHours()%12)); //Hours (1-12)
    s = q_Replace(s, "%G", d.getHours()); //Hours (0-23)
    s = q_Replace(s, "%h", q_ForceDigits((d.getHours()%12==0)?12:(d.getHours()%12), 2)); //Hours (01-12, 2 digits)
    s = q_Replace(s, "%H", q_ForceDigits(d.getHours(), 2)); //Hours (00-23, 2 digits)
    s = q_Replace(s, "%i", q_ForceDigits(d.getMinutes(), 2)); //Minutes (2 digits)
    s = q_Replace(s, "%s", q_ForceDigits(d.getSeconds(), 2)); //Seconds (2 digits)
    s = q_Replace(s, "%a", (d.getHours()>11)?"pm":"am"); //am or pm
    s = q_Replace(s, "%A", (d.getHours()>11)?"PM":"AM"); //AM or PM
    
    return s;
}

function q_DatabaseLookup(t, url, id, dx, fn) 
{
	//t=Type, url=URL, id=Callback Script, dx=Lookup Definition, fn=Fieldnames
	
	
	//--- Get fields data XML ---
	
	var f = "";
	if(fn!=null)
	{
		//Check each control's data
		for(var i=0; i<f_controls_n; i++)
		{
			//Get Data
			var d = f_controls[i].GetData();
			
			//Check each field
			if(d!=null)
				for(var j=0; j<d.length; j++)
				{
					//Check if it's one of the ones we need.
					for(var k=0; k<fn.length; k++)
						if(d[j].indexOf(fn[k]+"|")==0)
						{
							//Found match. Add it			
							f += q_GetFieldXMLTag(d[j], null);
							break;
						}
				}
		}
	}
	f = q_GetParentXMLTag("<fields>"+f+"</fields>");

	//Send it 
	if(t==0)
	{
		//Background
		var d = new Array(3);
		d[0] = Array("id", id);
		d[1] = Array("lookup", dx);
		d[2] = Array("data", f);
		q_GetURL(url, null, id, d);
	}
	else
	{
		//Pop-Up
		var w = q_OpenWindow("", 600, 500);
		if (w!=null && w!="")
		{
			w.document.write('<html><body><form action="'+url+'" method=POST>'
						+	q_GetHiddenInputHTML("id", id)
						+	q_GetHiddenInputHTML("lookup", dx)
						+	q_GetHiddenInputHTML("data", f)
						+	'</form></body></html>');
			w.document.forms[0].submit();
		}
	}
}

//SQLServerLookup Helper 
function q_GetHiddenInputHTML(n, v) //Name and Value
{
	//Value: Replace ' with escape characters
	n = q_Replace(n, "'", "\\x27");
	v = q_Replace(v, "'", "\\x27");

	return "<input type=hidden name='"+n+"' value='"+q_XMLEncode(v)+"'>";
}


function q_GetURL(url, p, id, d)	//p=QueryString param, id = Callback Script, d=POST data (as Array)
{
	if(!f_preview)
	{
		//Handle additional URL parameter
		if(p!=null && p.length>0)
			url = q_AddParamChar(url) + "param=" + q_Escape(p);

		//Try to create Ajax object
		var req = q_GetHTTPRequestObject();
		
		//If object exists, do Ajax, otherwise Pop-up method
		if(req) 
		{
			//Yes, do Ajax
			
			//Define callback function
			req.onreadystatechange = 		
			function()
			{
				if (req.readyState==4 && req.status == 200)
					q_Callback(id, req.responseText);
			};
			
			//Compile POST variables
			var pv = "";
			if(d && d.length)
				for(var i=0; i<d.length; i++)
				{
					if(pv!="") pv += "&";
					pv += q_Escape(d[i][0]) + "=" + q_Escape(d[i][1]);
				}
				
			//Make the call
			req.open("POST", url, true);
			req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			req.send(pv);
		}
		else
		{
			//Open pop-up window
			q_OpenWindow(q_AddParamChar(f_servercomm_url)+"url="+q_Escape(url)+"&id="+q_Escape(id), 300, 100);
		}
	}
}

//General Callback (e.g. from SQLServerLookup)
function q_Callback(id, v)
{
	var p = new Array();
	p[0] = q_Unescape(v);
	q_RunScript(""+id, p)
}

//GetURL Callback (should be replaced by above, for back-campatibility)
function q_GetURL2(id, v)
{
	q_Callback(id, v);
}

function q_GetControlByID(id)
{
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].id==id) return f_controls[i];
		
	//Not found
	return null;
}

function q_GetControlByTag(t)
{
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].tag==t) return f_controls[i];
		
	//Not found
	return null;
}

function q_GetPageByID(id)
{
	//Try ids first
	for(var i=0; i<f_pages_n; i++)
		if(f_pages[i].id==id) return f_pages[i];
		
	//Also try name
	for(var i=0; i<f_pages_n; i++)
		if(f_pages[i].name==id) return f_pages[i];

	//Not found
	return null;
}

function q_OnResize()
{
	//If relative positionned form, move skin and page background to new position
	if(!f_absolute_pos)
		q_RePositionForm();
}

//WorkFlow function (type, param_names, params), e.g. q_WorkFlow("notify", "who,person,action,param,login", "me", ...)
function q_WorkFlow()
{
	var n = arguments[1].toString().split(",");
	f_additional_data += '<workflow type="' + arguments[0] + '"';
	for(var i=2; i<arguments.length; i++) f_additional_data += ' '+n[i-2]+'="'+q_XMLEncode(arguments[i])+'"';
	f_additional_data += ' />';
}

//String Validation
function q_IsValidEmail(s)
{
	var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(s);
}

function q_IsValidURL(s)
{
	var re = /^((http|https|ftp)\:\/\/)?[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._~\\\/\?\,\'+&%\$#\=~])*$/;
    return re.test(s);
}

function q_IsAlpha(s)
{
	var re = /^[\sa-zA-Z]*$/;
    return re.test(s);
}

function q_IsAlphaNumeric(s)
{
	var re = /^[\sa-zA-Z0-9]*$/;
    return re.test(s);
}

function q_IsUpper(s)
{
	s=""+s;
	return (s.toUpperCase()==s);
}

function q_IsLower(s)
{
	s=""+s;
	return (s.toLowerCase()==s);
}


//---------------------------------------------------------
//----------------------- Helpers -------------------------
//---------------------------------------------------------


function q_GetQuask() //Returns the Q-logo click link (without http://)
{
	var rr = "ask";
	var r = "";
	for(var i=0; i<3; i++)r+="w";
	r+=".qu"+rr;
	r=r+".co";
	return r+"m/form";
}

function q_XMLEncode(s)
{
	s = "" + s;
	
	s = q_Replace(s, "&", "@amp;");
	s = q_Replace(s, "@amp;", "&amp;");
	s = q_Replace(s, "<", "&lt;");
	s = q_Replace(s, ">", "&gt;");
	s = q_Replace(s, "+", "&#43;");
	s = q_Replace(s, "'", "&#39;");
	s = q_Replace(s, '"', "&quot;");
	
	var sout = "";
	for(var i=0; i<s.length; i++)
	{
		var v=s.charCodeAt(i);
		if(v>0)
		{
		    if(v<32||v>127)
			    sout += "&#" + v + ";";
		    else
			    sout += s.charAt(i);
	    }
	}
	
	return sout;
}

function q_Unescape(s)
{
	s=unescape(s);
	s=q_Replace(s, "+", " ");
	return s;
}

function q_Escape(s)
{
	s=escape(s);
	s=q_Replace(s, " ", "+");
	return s;
}

function q_Replace(s, a, b)
{
	while(s.indexOf(a)>=0) s=s.replace(a, b);
	return s;
}

function q_StupidDecode(s)
{
	var o = "";
	s=s+"";
	var l = s.length;
	
	//Char by char (in revers)
	for(var i=0; i<l; i++)
	{
		var c = s.charCodeAt(l-1-i);
		if(c>=32 && c<=126) c = 158-c;
		o += String.fromCharCode(c);
	}

	return o;
}

function q_QueryStringDecode(s, seed)
{
	var out="";
	for(var i=0; i<(s.length/2); i++)
	{
		var char1 = s.charCodeAt(i*2) - 97;
		var char2 = s.charCodeAt(i*2+1) - 97;
		
		var ch = (char1*16 + char2 - seed - i) & 255;
		
		out = out + String.fromCharCode(ch);
	}
	
	if(out.charAt(out.length-1)!='q') return "";
	else return out.substring(0, out.length-1);
}

function q_GetIndex(arr, v)
{
	for(var i=0; i<arr.length; i++)
		if(arr[i]==v) return i;
		
	//Not found
	return -1;
}

function q_IsArray(o)
{
    return (o.constructor.toString().indexOf("Array")!=-1);
}

function q_AddParamChar(u) //Adds ? or & to end of url
{
	if(u.indexOf("?")<0) u+="?";
	if(u.charAt(u.length-1)!="?" && u.charAt(u.length-1)!="&") u+="&";
	return u;
}

function q_Trim(s)
{
	//Remove leading spaces
	while(s.charAt(0)==' ') s=s.substring(1);
	
	//Remove ending spaces
	if(s.length==0) return s;
	while(s.charAt(s.length-1)==' ') s=s.substring(0, s.length-1);
	
	return s;
}

function q_HandleNumeric(v) //Takes a string and returns either a string or numeric type of the same
{	
	if(v==null || v=="") return v;
	
	//If startes with 0 but not followed by decimal, treat as string (e.g. zip "09232")
	if(v.charAt(0)=='0' && v.length>1 && v.charAt(1)!='.' && v.charAt(1)!=',') 
		return v;
	
	//Avoid "1E02=100" bug
	if(v.indexOf('e')>=0 || v.indexOf('E')>=0)
		return v;
		
	//If numeric, return as numeric type
	if(!isNaN(1*v)) return parseFloat(v);
	else return v;
}

function q_ForceDigits(s, l)
{
	while((s+"").length<l) s = "0" + s;
	return s;
}

function q_GetHTTPRequestObject()
{
	if(window.XMLHttpRequest) 
		return new XMLHttpRequest();
		
	if(window.ActiveXObject) 
		return new ActiveXObject("Microsoft.XMLHTTP");
				
    //None of the above works
    return null;
}


//--- CSS Helpers -----

function q_GetFontCSS(f)
{
	var s=f_fonts[parseInt(f)].split("|");
	var css="font-size: "+s[0]+"; font-family: "+s[1]+";";
	if(s[2]&1) css=css+" font-weight: bold;";
	if(s[2]&2) css=css+" font-style: italic;";
	if(s[2]&4) css=css+" text-decoration: underline;";
	return css;
}

function q_GetDisabledAttribute(b)
{
    return b?'':' disabled="disabled"';
}

//Get valign= and align= html
function q_GetAlignHTML(a)
{
	var c;
	
	switch(a & 3)
	{
	case 1:		c = "align=left ";		break;
	case 2:		c = "align=right ";		break;
	default:	c = "align=center ";	break;
	}
		
	switch((a >> 2) & 3)
	{
	case 1:		return c + "valign=top ";
	case 2:		return c + "valign=bottom ";
	default:	return c + "valign=center ";
	}
}

//Netscape 4.x doesn't support pixel width/height in <input text> and <textarea>
//It uses size (in chars) instead, this estimates a corresponding charwidth
function q_GetCharSize(f, w)	{return w/parseInt((s=f_fonts[parseInt(f)].split("|"))[0])*1.2;}

//Returns position (x,y) of an image (<img id="xxx" >) within the whole HTML page
function q_GetImagePagePos(id)
{
	// Defaults
	var x=0, y=0;

	var o;
	if(q_bDOM2) o = document.getElementById(id);
	if(q_bIE) o = document.all[id];
	while(o && o.tagName != "BODY" && o.tagName != "HTML") 
	{	
		x += o.offsetLeft;
		y += o.offsetTop;
		o = o.offsetParent;
	}
	
	//Fine tuning
	if(q_bIE && navigator.userAgent.indexOf("Opera")<0) {x++;y++};
	if(q_bDOM2 && navigator.userAgent.indexOf("Firebird")<0) {x+=2;y+=2};
	
	//Return
	return  Array(x,y);
} 



//---------------------------------------------------------
//------------------- Event Switchboard  ------------------
//---------------------------------------------------------


function q_InitEvents()
{
	q_CaptureEvents();
	document.onmousedown = q_OnMouseDown;
	document.onmousemove = null;
	document.onmouseup = null;
}

function q_OnMouseDown(e)
{
	//Get Name/ID of element that raised event
	var n = "";
	var t = q_GetEventTarget(e);
	if(t.name!=null) n=t.name;		//Check name if image
	else if(t.id!=null) n=t.id;		//Check id if other element
	
	//--- Is it from a Control? -> Dispatch Event to right control
	if (n.indexOf("i_")==0)
	{
		//Get index
		j = parseInt(n.substring(2));
		
		//Register focus
		q_RegisterFocus(j);
		
		//Dispatch Event
		if(f_controls[j].OnMouseDown!=null)
			return f_controls[j].OnMouseDown(q_GetEventX(e)-f_page_x, q_GetEventY(e)-f_page_y, n);
	}
	
	//--- Is it from a skin button ? ---	
	if (n.indexOf("sb_")==0) return f_SkinButtonMouseDown(q_GetEventX(e), q_GetEventY(e), parseInt(n.substring(3)));
	
	return true;
}

function q_OnMouseMove(e)
{
	//Dispatch Event to control that has captured the mouse event
	if(f_capturing_control>=0) return f_controls[f_capturing_control].OnMouseMove(q_GetEventX(e)-f_page_x, q_GetEventY(e)-f_page_y);
	else if(f_capturing_control==-9) return f_SkinButtonMouseMove(q_GetEventX(e), q_GetEventY(e));
	else return true;
}

function q_OnMouseUp(e)
{
	//Dispatch Event to control that has captured the mouse event
	if(f_capturing_control>=0) return f_controls[f_capturing_control].OnMouseUp(q_GetEventX(e)-f_page_x, q_GetEventY(e)-f_page_y);
	else if(f_capturing_control==-9) return f_SkinButtonMouseUp(q_GetEventX(e), q_GetEventY(e));
	else return true;
}

function q_CaptureMouse(index)
{
	//Send "LoseMouse" event to previous "capturor"
	if(f_capturing_control>=0 && f_controls[f_capturing_control].OnLoseMouse!=null)
			f_controls[f_capturing_control].OnLoseMouse();

	//Set new capturing control
	f_capturing_control=index; //Special case: -9 = Skin Button
	
	document.onmousemove = q_OnMouseMove;
	document.onmouseup = q_OnMouseUp;
}

function q_ReleaseMouse()
{
	f_capturing_control=-1;
	
	document.onmousemove = null;
	document.onmouseup = null;
}

function q_OnKeyPress(e, index)	//This is must be called by "onkeypress='q_OnKeyPress(event, 123);'" attribute
{
	if(f_controls[index].OnKeyPress!=null)
		return f_controls[index].OnKeyPress(q_GetEventKey(e), q_GetEventTarget(e));
}

function q_OnKeyRelease(e, index)	//This is must be called by "onkeyup='q_OnKeyRelease(event, 123);'" attribute
{
	if(f_controls[index].OnKeyRelease!=null)
		return f_controls[index].OnKeyRelease(q_GetEventKey(e), q_GetEventTarget(e));
}

function q_OnChange(e, index)	//This is must be called by "onchange='return q_OnChange(event, 123);'" attribute
{
	if(f_controls[index].OnChange!=null)
		return f_controls[index].OnChange(q_GetEventTarget(e));
}

function q_OnTimer(index)		//This must be called by "setTimeout("q_OnTimer(index, 1000);")"
{
	if(f_controls[index].OnTimer!=null)
		return f_controls[index].OnTimer();
}

function q_OnEffectTimer(index)		//This must be called by "setTimeout("q_OnEffectTimer(index, 1000);")"
{
	return f_controls[index].OnEffectTimer();
}

function q_OnMouseDownEx(e, index)	//This is must be called by "onmousedown='q_OnMouseDown(event, 123);'" attribute
{
	q_RegisterFocus(index);

	if(f_controls[index].OnMouseDown!=null)
		return f_controls[index].OnMouseDown(q_GetEventX(e), q_GetEventY(e));
}

function q_OnMouseOver(e, index)	//This is must be called by "onmouseover='q_OnMouseOver(event, 123);'" attribute
{
	if(f_controls[index].OnMouseOver!=null)
		return f_controls[index].OnMouseOver(q_GetEventX(e), q_GetEventY(e), q_GetEventTarget(e));
}

function q_OnMouseOut(e, index)	//This is must be called by "onmouseout='q_OnMouseOut(event, 123);'" attribute
{
	if(f_controls[index].OnMouseOut!=null)
		return f_controls[index].OnMouseOut(q_GetEventX(e), q_GetEventY(e), q_GetEventTarget(e));
}

function q_OnFocus(e, index)	//This is must be called by "onfocus='q_OnFocus(event, 123);'" attribute
{
	q_RegisterFocus(index);
	
	if(f_controls[index].OnFocus!=null)
		return f_controls[index].OnFocus(q_GetEventX(e), q_GetEventY(e), q_GetEventTarget(e));
}

function q_OnBlur(e, index)	//This is must be called by "onBlur='q_OnBlur(event, 123);'" attribute
{
	if(f_controls[index].OnBlur!=null)
		return f_controls[index].OnBlur();
}

function q_OnUpload(id, filename)	//This is must be called by outside window
{
	if(q_GetControlByID(id).OnUpload!=null)
		return q_GetControlByID(id).OnUpload(filename);
}


//--- Form Event Triggers ---

function f_OnFormStart()
{
	//Event Trigger (Form OnLoad)
	if(f_events!=0)
    	q_RunScript(f_events[0]);

	//Check each control if it wants to handle this
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].OnFormStart!=null)
			f_controls[i].OnFormStart();			
}

function f_OnPageFocus(pageindex)
{
	//Scripting Triggers
	if(f_pages[pageindex].events!=0)
    	q_RunScript(f_pages[pageindex].events[0]);
	
	//Check each control in this page if it wants to handle this
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].page==pageindex && f_controls[i].OnPageFocus!=null)
			f_controls[i].OnPageFocus();
}

function f_OnPageBlur(pageindex)
{
	//Scripting Triggers
	if(f_pages[pageindex].events!=0)
    	q_RunScript(f_pages[pageindex].events[1]);
	
	//Check each control in this page if it wants to handle this
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].page==pageindex && f_controls[i].OnPageBlur!=null)
			f_controls[i].OnPageBlur();
}



//---------------------------------------------------------
//---------------- Control Panel (Skin)  ------------------
//---------------------------------------------------------


function f_SkinButtonMouseDown(eX, eY, id)
{	
	//Is it Logo?
	if(id==9)
	{
		q_ShowURL("http://"+q_GetQuask());
		return false;
	}
	
	//Dont do it after send was pressed
	if(f_disableskin) return false;
	
	//Remember button and pos
	f_pressed_skinbutton = id;
	f_pressed_skinbutton_x = eX;
	f_pressed_skinbutton_y = eY;
	
	//Graphical "Pressed" Effect
	q_GetImage("s_d", "sb_"+id).src = f_skin_but_p[id].src;

	q_CaptureMouse(-9);		
	return false;
}


function f_SkinButtonMouseMove(eX, eY)
{
	//If moved outside, change pic to "Normal", if inside, change pic to "Pressed"
	if(Math.abs(eX-f_pressed_skinbutton_x)<f_skin_w && Math.abs(eY-f_pressed_skinbutton_y)<f_skin_h/2)
		q_GetImage("s_d", "sb_"+f_pressed_skinbutton).src = f_skin_but_p[f_pressed_skinbutton].src;
	else
		q_GetImage("s_d", "sb_"+f_pressed_skinbutton).src = f_skin_but_n[f_pressed_skinbutton].src;
	
	return false;
}


function f_SkinButtonMouseUp(eX, eY)
{
	//Change pic to "Normal"
	q_GetImage("s_d", "sb_"+f_pressed_skinbutton).src = f_skin_but_n[f_pressed_skinbutton].src;
	q_ReleaseMouse();
	
	//If not moved outside button, do action
	if(Math.abs(eX-f_pressed_skinbutton_x)<f_skin_w && Math.abs(eY-f_pressed_skinbutton_y)<f_skin_h/2)
	{
		//Do Action
		switch(f_pressed_skinbutton)
		{
		case 0:		q_SendData();	break;	//Send
		case 1:		q_ResetData();	break;	//Reset
		case 2:		q_Print();		break;	//Print
		case 3:		q_PrevPage();	break;	//Page Back
		case 4: 	q_NextPage();	break;	//Page Forward
		}
	}
	
	return false;
}

function q_SkinPageComboChanged()
{
	//Dont do it after send was pressed
	if(f_disableskin) return false;
	
	f_GoToPage(parseInt(q_GetSelectedValue("s_d", "p_cb")));
}




//=========================================================
//=================== PAGE OBJECT =========================
//=========================================================


//--- Constructor ---

function q_page(i, p)
{
	this.index = i;
	this.color = p[0];	    	//Background-color of page
	this.name = p[1];		    //Name of page
	this.id = p[2];		    	//ID of page
	this.randomize = (p[3]>0);	//Randomize? true/false
	this.events = p[4];		    //Event triggers (Array)

	this.enabled = true;
	this.readonly = false;
	
	this.SetBackCol = q_page_SetBackCol;
	this.GetBackCol = q_page_GetBackCol;
	
	this.SetEnabled = q_page_SetEnabled;
	this.GetEnabled = q_page_GetEnabled;
	
	this.SetReadOnly = q_page_SetReadOnly;
	this.GetReadOnly = q_page_GetReadOnly;
	
	this.GoTo = q_page_GoTo;
}

function q_page_SetEnabled(e, b)
{
	this.enabled = e;
	
	//Set it on all controls in this page
	for(var i=0; i<f_controls_n; i++)
	{
		if(f_controls[i].page == this.index && ((b==true) || f_controls[i].type!=12))
			f_controls[i].SetEnabled(e);			
	}
}

function q_page_GetEnabled()
{
	return this.enabled;
}

function q_page_SetReadOnly(r)
{
	this.readonly = r;
	
	//Set it on all controls in this page
	for(var i=0; i<f_controls_n; i++)
		if(f_controls[i].page == this.index) f_controls[i].SetReadOnly(r);
}

function q_page_GetReadOnly()
{
	return this.readonly;
}

function q_page_SetBackCol(c)
{
	//Store
	this.color = c;
	
	//If this page is currently showing, update color on screen
	if(f_current_page==this.index)
		q_SetBackCol("p_d", this.color);
}

function q_page_GetBackCol()
{
	return this.color;
}

function q_page_GoTo()
{
	f_GoToPage(this.index);
}



//=========================================================
//================= CONTROLS OBJECTS ======================
//=========================================================


//--- Constructor Dispatcher ---

function q_ctrl(index, args)
{
	switch(args[0]) //First field contains type of control
	{
	case 1:		return new q_la(index, args);	//Text Label
	case 2:		return new q_tx(index, args);	//Text Input
	case 3:		return new q_nu(index, args);	//Numeric Input
	case 5:		return new q_li(index, args);	//List Selection
	case 6:		return new q_pi(index, args);	//Picture Label
	case 7:		return new q_ch(index, args);	//Checkboxes
	case 9:		return new q_dd(index, args);	//Drop-Down Selection
	case 10: 	return new q_dt(index, args);	//Date/Time
	case 11:	return new q_ma(index, args);	//Matrix
	case 12: 	return new q_bu(index, args);	//Button
	case 13: 	return new q_em(index, args);	//Emoticon
	case 14: 	return new q_so(index, args);	//Sound
	case 15: 	return new q_ra(index, args);	//Ranking
	case 16: 	return new q_ti(index, args);	//Timer
	case 17: 	return new q_up(index, args);	//Upload
	case 18: 	return new q_ta(index, args);	//Table Input
	case 98: 	return new q_gh(index, args);	//Ghost Object (Split Page forms only)
	case 99: 	return new q_pg(index, args);	//Picture Grid
	default:	return null;
	}
}



//---------------------------------------------------------
//---------------- Control "Base class"  ------------------
//---------------------------------------------------------


//--- Constructor ---

function q_bc_Constr(o, index, args)
{
	//Store base properties
	o.index = index;		    //HTML internal numbering (Ctrls[index])
	o.type = args[0];		    //Type of control
	o.id = args[1];		    	//ID
	o.tag = args[2];		    //Tag for data
	o.required = (args[3]>0);	//Is this control obligatory?
	o.page = args[4];		    //Page number
	o.tab = args[5];		    //Tab order
	
	//Ghost doesn't have to following properties
	if(o.type!=98)
	{
		o.x = args[6];			//Initial position of object (relative to Skin)
		o.y = args[7];			//Initial position of object (relative to Skin)
		o.width = args[8];		//Width of object
		o.height = args[9];		//Height of object
		o.frame = args[10];		//Size of frame
		o.framepic = args[11];	//Picture representing the frame
		o.padding = args[12];	//Size of padding
		o.backcol = args[13];	//Initial background color of object
		o.forecol = args[14];	//Foreground color of object
		o.zorder = args[15];	//Z-order
		o.font = args[16];		//Index of first font
	}
	else
	{
		//Ghost all 0's
		o.x = o.y = o.width = o.height = o.frame = o.framepic = o.padding = o.zorder = o.font = 0;
		o.backcol = o.forecol = "000000";
	}

	//Derived properties
	o.cwidth = o.width-2*o.padding-2*o.frame;	//Size of "client" area of control
	o.cheight = o.height-2*o.padding-2*o.frame;	//Size of "client" area of control
	
	//Default properties
	o.created = false;       //Is set to true once .Create() method is called
	o.visible = true;		//Is control visible in form (actual visibility depends on whether this page is shown)
	o.showing = false;		//Initially not showing (shows only when page is displayed)
	o.enabled = true;		//Enabled/Disable (showing but cannot be used)
	o.readonly = false;		//Is shown but cannot be changed
	o.shaded = false;		//Shaded/Normal
	o.effect = -1;			//1==Fade In, 2==Fade Out, 3...
	o.effectstep = 0;		//Counter in effect timer
	o.effectdirection = 0;	//Moving in ...
	o.effectend_x = 0;		//End postion if moving
	o.effectend_y = 0;		//End postion if moving
	o.flashing = 0;			//Flashing Steps to countdown (for state info only)
	o.transparency = 100;   //100% (default)
	
	//Property Changes log
	o.changed = 0;			//Keeps track of any changes of properties. Bitfield:
	//1=XPos, 2=YPos; 4=ZOrder; 8=BackCol; 16=Enabled; 32=ReadOnly; 64=Shaded; 128=Visible
	//256=Tag; 512=Transparency; 1024=Answers; 2048=Source (Pic obj.); 4096=Caption (Label obj.)
	//8192=Untouched, 16384=Last Selected, 32768=Flashing
	
	//Baseclass Methods

	o.Create = null;					    //Write HTML (Must always be overridden)
	o.Show = q_bc_Show;					    //Show (when page is shown)

    o.CreateMainDiv = q_bc_CreateMainDiv;
    o.CreateDiv = q_bc_CreateDiv;

	o.GetX = q_bc_GetX;	
	o.SetX = q_bc_SetX;
	o.GetY = q_bc_GetY;
	o.SetY = q_bc_SetY;
	o.GetZOrder = q_bc_GetZOrder;
	o.SetZOrder = q_bc_SetZOrder;

	o.SetBackCol = q_bc_SetBackCol;
	o.GetBackCol = q_bc_GetBackCol;
		
	o.GetEnabled = q_bc_GetEnabled;
	o.SetEnabled = q_bc_SetEnabled;
	o.GetReadOnly = q_bc_GetReadOnly;
	o.SetReadOnly = q_bc_SetReadOnly;
	o.GetShaded = q_bc_GetShaded;
	o.SetShaded = q_bc_SetShaded;
	o.GetShadedColor = q_bc_GetShadedColor;     //Helper for SetShaded/SetBackground
	o.GetVisible = q_bc_GetVisible;
	o.SetVisible = q_bc_SetVisible;
	o.GetTag = q_bc_GetTag;
	o.SetTag = q_bc_SetTag;
	o.SetTransparency = q_bc_SetTransparency;
	o.SetMode = q_bc_SetMode;

	o.CheckObligatory = q_bc_CheckObligatory;
	o.CheckValid = q_bc_DoNothing;				//Used by Text Input only
	o.GetData = q_bc_GetData;
	o.SetData = q_bc_SetData;
	o.ResetData = q_bc_ResetProperties;			//(Shortcut)
	o.ResetProperties = q_bc_ResetProperties;	//Called from within <obj>_ResetData
	o.CopyData = q_bc_CopyData;					//Table Input Only
	o.TriggerEvent = q_bc_TriggerEvent;
	
	o.GetValue = q_bc_GetScriptingValue;		//Used by Scripting only
	o.SetValue = q_bc_SetScriptingValue;		//Used by Scripting only
	o.GetState = q_bc_DoNothing;				//Used by Scripting only
	o.SetState = q_bc_DoNothing;				//Used by Scripting only
	o.GetValueCaption = q_bc_DoNothing;			//Used by Scripting only
	o.SetAnswers = q_bc_DoNothing;				//Drop-Downn & List only
	o.SetSource = q_bc_DoNothing;				//Picture Only
	o.SetUntouched = q_bc_DoNothing;			//Ghost Only
	o.GetSum = q_bc_DoNothing;					//Table Input Only
	o.SetDownloadURL = q_bc_DoNothing;			//Upload only

	o.GoTo = q_bc_GoTo;							//Go to this object
	o.StartFlashing = q_bc_StartFlashing;		//Flashing objects
	o.ApplyEffect = q_bc_ApplyEffect;			//Fade In etc...
	o.OnEffectTimer = q_bc_OnEffectTimer;		//Fade In etc...
	o.StartTimer = null;						//Only implemented by Timer object
	o.SetCaption = null;						//Only implemented by Label object

	//Methods to access/manipultate HTML elements in object's MainDiv
	o.GetHTMLForm = q_bc_GetHTMLForm;
	o.GetHTMLElement = q_bc_GetHTMLElement;
	o.GetHTMLElementValue = q_bc_GetHTMLElementValue;
	o.SetHTMLElementValue = q_bc_SetHTMLElementValue;
	o.GetHTMLElementSelectedIndex = q_bc_GetHTMLElementSelectedIndex;
	o.SetHTMLElementSelectedIndex = q_bc_SetHTMLElementSelectedIndex;
	o.GetHTMLElementSelectedValue = q_bc_GetHTMLElementSelectedValue;
	o.SetHTMLElementSelectedValue = q_bc_SetHTMLElementSelectedValue;
	o.GetHTMLElementOptions = q_bc_GetHTMLElementOptions;
	o.SetHTMLMainDivBackCol = q_bc_SetHTMLMainDivBackCol;
	o.SetHTMLElementBackCol = q_bc_SetHTMLElementBackCol;
	o.GetHTMLImage = q_bc_GetHTMLImage;
	o.GetHTMLElementCaretPos = q_bc_GetHTMLElementCaretPos;
	o.SetHTMLElementCaretPos = q_bc_SetHTMLElementCaretPos;

	//Event handling methods
	o.OnMouseDown=null;			//Doesn't need to be implemented
	o.OnMouseMove=null;
	o.OnMouseUp=null;
	o.OnKeyPress=null;			//Text & Numeric Input
	o.OnKeyRelease=null;		//Only used by Numeric
	o.OnChange=null;
	o.OnTimer=null;				//Only implemented by Timer object
	o.OnPageFocus=null;			//Only implemented by Timer and Sound objects
	o.OnPageBlur=null;			//Only implemented by Timer object
	o.OnFormStart=null;			//Only implemented by Timer object
	o.OnMouseOver=null;			//Only implemented by Labels, Sound and Picture Grid object
	o.OnMouseOut=null;			// "
	o.OnLoseMouse=null;			//Only implemented by Picture Grid
	o.OnFocus=null;				//Implemented by Text, Combo etc. for Scripting
	o.OnFocusLost=null;			//Only implemented by Date/Time
	o.OnUpload=null;			//Implemented by Upload only
	
	return (o.type==98)?6:17;	//Returns number of baseclass properties (Ghost has only 6)
}


//---- Base class Methods (can be overridden by each control ----



//--- Create HTML of object

function q_bc_CreateMainDiv(c, f) //c=Contents, f=Do Form?
{
    var h = "";
    
    //-- Add additional HTML around it ---
    
	//Does it require a <form> ?
	if(f)
	    h += '<form name="f_i_' + this.index + '_d" style="margin: 0px; padding 0px" method="post" onsubmit="return false;">';

    //Put it into <table> (for alignment)
	h += '<table cellspacing=0 cellpadding=0 border=0 width=' + this.width + ' height=' + this.height + '>';
	
    //Put it all into a <td>, centered
	h +=	'<tr><td width='+this.width+' height='+this.height+' align="center" valign="center"';

    //Handle frame style
	if(this.frame>0 && this.framepic>=0)
	    h += ' style="background-image: url(' + f_resources[this.framepic].src + '); background-repeat: no-repeat"';
	
	h +=	'>'	+ c + '</td></tr>';
	
    //End table
    h += '</table>';
    
   	//End form
	if(f)
	    h += '</form>';


    //--- Create Div layer --

    var n = document.createElement('div');
    var s = n.style;
    s.position = 'absolute';
    s.visibility = 'hidden';
    s.left = this.x + 'px';
    s.top = this.y + 'px';
    s.width = this.width + 'px';
    //s.height = this.height + 'px';
    s.zIndex = 10 + (this.zorder*10);
    if(this.GetShadedColor(this.backcol) != "") s.backgroundColor = "#" + this.GetShadedColor(this.backcol);
    n.setAttribute('id', 'i_' + this.index + '_d');
    n.innerHTML = h;

    //Add it to "Page" layer
    document.getElementById('p_d').appendChild(n);
    
    //Set Created Flag
    this.created = true;
}

function q_bc_CreateDiv(id, x, y, z, c, bg, b, w, h) //x,y,z=Position, c=Contents, bg=Background Color, b=Border, w=Width, h=Height
{
    //--- Create Div layer --

    var n = document.createElement('div');
    var s = n.style;
    s.position = 'absolute';
    s.visibility = 'hidden';
    s.left = x + 'px';
    s.top = y + 'px';
    s.zIndex = z;
    if(bg && bg!="") s.backgroundColor = "#" + bg;
    if(b && b!="") s.border = b;
    if(w) s.width = w;
    if(h && h>0) { s.overflow = 'hidden'; s.height = h; };
    n.setAttribute('id', id);
    n.innerHTML = c;

    //Add it to "Page" layer
    document.getElementById('p_d').appendChild(n);
}

//--- X/Y/Z Postion Methods

function q_bc_GetX()
{
	return this.x;
}

function q_bc_GetY()
{
	return this.y;
}

function q_bc_SetX(x)
{
	if(x>=0 && x<=f_page_w-this.width)
	{
		this.x = x;
		if(this.created)
    		q_SetLeft("i_"+this.index+"_d", x);

		this.changed |= 1;
	}
}

function q_bc_SetY(y)
{
	if(y>=0 && y<=f_page_h-this.height)
	{
		this.y = y;
		if(this.created)
    		q_SetTop("i_"+this.index+"_d", y);

		this.changed |= 2;
	}
}

function q_bc_GetZOrder()
{
	return this.zorder;
}

function q_bc_SetZOrder(z)
{
	if(z>=0 && z<3276)
	{
		this.zorder = z;
		
		if(this.created)
    		q_SetZOrder("i_"+this.index+"_d", 10+z*10);

        //Log
		this.changed |= 4;
	}
}

function q_bc_SetBackCol(c)
{
	this.backcol = c;
	
	if(this.created)
    	this.SetHTMLMainDivBackCol(this.GetShadedColor(c));
	
    //Log
	this.changed |= 8;
}

function q_bc_GetBackCol()
{
	return this.backcol;
}

function q_bc_StartFlashing(n) //TO DO Created?
{
	//Is there already flashing going on?
	if(f_flashing_controls==null)
	{
		//No. Start a new flash
		f_flashing_controls = new Array(1);
		f_flashing_controls[0] = this;
		
		//Get timer going...
		setTimeout("q_Flashing();", 300);		
	}
	else
	{
		//Yes. Simply add this control to it
		f_flashing_controls[f_flashing_controls.length] = this;		
	}

	//Set/Reset Steps
	f_flashing_steps = n;

	//State Info
	this.changed |= 32768;
	this.flashing = n;	
}

function q_bc_ApplyEffect(id, param1, param2) //TO DO: Created
{
	//If previous is still going, end it
	if(this.effect>0)
	{
		this.SetX(this.effectend_x);
		this.SetY(this.effectend_y);
	}
	
	//Start
	this.effect = id;
	this.effectstep = 0;
	this.effectend_x = this.GetX();
	this.effectend_y = this.GetY();
	this.effectmaxstep = param1*10;
	this.effectdirection = param2;

	//Start with transparent
	if(id==1) this.SetTransparency(0);
	
	//Make sure it is visible
	this.SetVisible(true);
	
	//Set Transparency only
	if(id==5) this.SetTransparency(param1);
	
	//Start Timer
	else this.OnEffectTimer();
}

function q_bc_OnEffectTimer()
{
	if(this.effect>0)
	{
		this.effectstep++;
		if(this.effectstep>this.effectmaxstep)
		{
			//End Reached
			
			//Clean Up
			switch(this.effect)
			{
			case 2: //Fade Out
				this.SetVisible(false);
				//No break..
				
			case 1: //Fade In
				this.SetTransparency(100);
				break;
				
			case 4: //Move Out
				this.SetVisible(false);
				//No break..

			case 3: //Move In
				this.SetTransparency(100);
				this.SetX(this.effectend_x);
				this.SetY(this.effectend_y);
				break;
			}
			
			//Default
			this.effect = -1;
		}
		else
		{
			//Next Step
			
			var r = this.effectstep/this.effectmaxstep;
			
			switch(this.effect)
			{
			case 2: //Fade Out
				r = 1-r;
				//No break...
				
			case 1: //Fade In
				this.SetTransparency(100*r);
				break;
				
			case 4: //Move Out
				r = 1-r;
				//No break...
			
			case 3: //Move In
				this.SetTransparency(100*r);
				if(this.effectdirection==0) //Top
					this.SetY(this.effectend_y*r);
				if(this.effectdirection==1) //Right
					this.SetX(f_page_w-this.width-(f_page_w-this.effectend_x-this.width)*r);
				if(this.effectdirection==2) //Bottom
					this.SetY(f_page_h-this.height-(f_page_h-this.effectend_y-this.height)*r);
				if(this.effectdirection==3) //Left
					this.SetX(this.effectend_x*r);
				break;
			}
			
			setTimeout("q_OnEffectTimer("+this.index+")", 100);
		}
	}
}

//--- Visibility Methods

function q_bc_Show(s)
{
	this.showing = s;
	
	//Make sure it's created, the 1st time we show it
	if(!this.created && s) this.Create();
	
	//Update visiblity
	if(this.created)
    	q_SetVisible("i_"+this.index+"_d", s & this.visible);
}

function q_bc_SetVisible(v)
{
	this.visible = v;
	
	if(this.created && this.showing)
    	q_SetVisible("i_"+this.index+"_d", v & this.showing);

	this.changed |= 128;
}

function q_bc_GetVisible()
{
	return this.visible;
}

function q_bc_SetTag(t)
{
	this.tag = t;
	this.changed |= 256;
}

function q_bc_GetTag()
{
	return this.tag;
}

function q_bc_SetEnabled(e)
{
	this.enabled = e;
	this.changed |= 16;
}

function q_bc_GetEnabled()
{
	return this.enabled;
}

function q_bc_SetReadOnly(r)
{
	this.readonly = r;
	this.changed |= 32;
}

function q_bc_GetReadOnly()
{
	return this.readonly;
}

function q_bc_SetShaded(s) //TO DO Created
{
	this.shaded = s;

    if(this.created)
    	this.SetHTMLMainDivBackCol(this.GetShadedColor(this.backcol));

	this.changed |= 64;
}

function q_bc_GetShaded()
{
	return this.shaded;
}

//Helper
function q_bc_GetShadedColor(c)
{
    if(this.shaded)
        return "ff0000";
    else
        return c;
}

function q_bc_SetTransparency(t) //0-100% //TO DO Created
{
	this.transparency = t;

    if(this.created)
	    q_SetTransparency("i_"+this.index+"_d", t); //0 to 100

	//Log
	this.changed |= 512;
}

//Shortcut function for scripting to set Visible/Enabled/ReadOnly
function q_bc_SetMode(v)
{
    if(v&256)
    {
        //New Style: Visibility (0=Unchaged, 1=Visible, 2=Hidden)
        var s = (v>>4)&15;
        if(s>0)
            this.SetVisible(s==1);
        
        //New Style: State (0=Unchanged, 1=Editable, 2=Flashing, 3=Shaded, 4=ReadOnly, 5=Disabled)
        s = v&15;
        if(s>0)
        {
            this.SetShaded(s==3);
            this.SetReadOnly(s==4);
	        this.SetEnabled(s!=5);
	        if(s==2) this.StartFlashing(6);
        }
    }
    else
    {
        //Old style
        this.SetVisible((v&1)>0);        
    	this.SetReadOnly((v&2)>0);
	    this.SetEnabled((v&4)>0);
	    this.SetShaded((v&8)>0);
	    if(v&16) this.StartFlashing(6);
    }
}


//--- Data Handling Methods

function q_bc_CheckObligatory()
{
	return true; //true=Everything is fine
}

function q_bc_GetData()
{
	return null;
}

function q_bc_SetData(fieldname, value)
{
	return false;
}

function q_bc_CopyData(id)
{
	//Works only with single-fields, all others must be overwritten

	//Get Source controls
	var c = q_GetControlByID(id);
	
	//Must exists and also be of same type
	if(c!=null && c.type==this.type)
		this.SetData(this.id, c.GetValue());
}

function q_bc_ResetProperties()
{
	this.SetVisible(true);
	this.SetEnabled(true);
	this.SetReadOnly(f_readonly);
	this.SetShaded(false);
	this.changed = 0;
}

//-- Scripting Methods

function q_bc_TriggerEvent(i, params)
{
    if(this.events!=0 && this.events[i]!="")
    	q_RunScript(this.events[i], params, this.id + "__" + i);
}

function q_bc_GetScriptingValue()
{
	//This is baseclass works for single-field objects only
	//Multiple fields object must override this
	var d = this.GetData();
	if(d!=null)
	{
		var s = d[0].indexOf("|");
		if(s>0) return q_HandleNumeric(d[0].substring(s+1));
	}
	
	//Else, no data or error
	return null;
}

function q_bc_SetScriptingValue(v)
{
    //Only works with single-fields, all others must overwrite
	this.SetData(this.id, v);
}


function q_bc_DoNothing()
{
	return null;
}


//--- HTML Form Helpers (to access the HTML form in ojbect's MainDiv)

function q_bc_GetHTMLForm()
{
	return document.forms["f_i_"+this.index+"_d"];
}

function q_bc_GetHTMLElement(e)
{
	return this.GetHTMLForm().elements[e];
}
	
function q_bc_GetHTMLElementValue(e)
{
	return this.GetHTMLForm().elements[e].value;
}

function q_bc_SetHTMLElementValue(e, v)
{
	this.GetHTMLForm().elements[e].value = v;
}

function q_bc_GetHTMLElementSelectedIndex(e)
{
	return this.GetHTMLForm().elements[e].options.selectedIndex;
}

function q_bc_SetHTMLElementSelectedIndex(e, i)
{
	this.GetHTMLForm().elements[e].options.selectedIndex = i;
}

function q_bc_GetHTMLElementSelectedValue(e)
{
	var i = this.GetHTMLForm().elements[e].options.selectedIndex;
	if(i<0)
		return null;
	else
		return this.GetHTMLForm().elements[e].options[i].value;
}

function q_bc_SetHTMLElementSelectedValue(e, v)
{
    var o = this.GetHTMLForm().elements[e].options;    

    if(v==null)
    {
        //Deselect all
    	o.selectedIndex = -1;
    }
    else
    {
        for(var i=0; i<o.length; i++)
        {
            if(o[i].value==v)
            {
                o[i].selected = true;
                return;
            }
        }
    }
}

function q_bc_GetHTMLElementOptions(e)
{
	return this.GetHTMLForm().elements[e].options;
}

function q_bc_SetHTMLMainDivBackCol(c)
{
	q_SetBackCol("i_"+this.index+"_d", c);
}

function q_bc_SetHTMLElementBackCol(e, c)
{
	q_SetElementBackCol(this.GetHTMLForm().elements[e],  c);
}

function q_bc_GetHTMLImage(e)
{
 	return q_GetImage("i_"+this.index+"_d", e);
}	

function q_bc_GetHTMLElementCaretPos(e)
{
	return q_GetCaretPos(this.GetHTMLElement(e));
}

function q_bc_SetHTMLElementCaretPos(e, p)
{
	q_SetCaretPos(this.GetHTMLElement(e), p);
}


//--- Other Methods

function q_bc_GoTo(f)
{			
	q_GoToControl(this.id, f);
}
//---------------------------------------------------------
//---------------------- Text Label  ----------------------
//---------------------------------------------------------


//--- Constructor ---

//Bass class: index, id, page, x, y, width, height, frame, framepic, padding, backcol, forecol, tab, zorder, required, fonts
//Ctrl specific: text, alignment

function q_la(index, a)
{
	//Store baseclass properties
	var n = q_bc_Constr(this, index, a);
	
	//Store control specific properties
	this.text = f_strings[a[n]];	//Text to be displayed
	this.align = a[n+1];			//Alignment 1=Left, 2=Right, 3=Center + >>2 1=Top, 2=Bottom, 3=Center 
	this.events = a[n+2];			//Event triggers ([0]=Cicked, [1]=Over, [2]=Out)	
	
	//Handle Text Tokens
	this.caption = q_Replace(q_Replace(q_Replace(q_Replace(this.text, "%%", "~%~"), "%p", this.page+1), "%t", f_pages_n), "~%~", "%");
	 
	//Methods (Overwrites)
	this.Create = q_la_Create;	
	this.SetData = q_la_SetData;
	this.SetCaption = q_la_SetCaption;
	
	if(this.events!=0)
	{
	    if(this.events[0]!="") this.OnMouseDown = q_la_OnMouseDown;
	    if(this.events[1]!="") this.OnMouseOver = q_la_OnMouseOver;
	    if(this.events[2]!="") this.OnMouseOut = q_la_OnMouseOut;
    }
}


//--- HTML Writer ---

function q_la_Create()
{
	//HTML
	var c = '<span id=i_'+this.index+'_ltx style="color: #' + this.forecol + '; ' + q_GetFontCSS(this.font) + '"';
	
	//Event triggers (MouseDown, MouseOver & MouseOut)
	if(this.events!=0)
	{
		c += ' onmouseover="q_OnMouseOver(event, '+this.index+');" onmouseout="q_OnMouseOut(event, '+this.index+');"' +
			 ' onclick="q_OnMouseDownEx(event, '+this.index+');"';
			 
        //Show mouse pointer, on hover?
		if(this.events[0]!="") c += ' class=st_p';
	}
	
	c += '><span>' + this.caption + '</span></span>';

	//Put it into table
	c =  '<table cellspacing=0 cellpadding=0 border=0 width=' + this.cwidth + ' height=' + this.cheight + '>'
		+	'<tr><td width=' + this.cwidth + ' height=' + this.cheight + ' ' + q_GetAlignHTML(this.align) + ' class="st_nb">' + c + '</td>'
		+	'</tr></table>';
	
    //Create it
	this.CreateMainDiv(c, false);
}


//--- Scripting API ---

function q_la_SetData(fn, v)	//Undocumented, only for Peter
{
	if(fn!=this.id) return false;
	else
	{
		this.SetCaption(v);
		return true;
	}
}

function q_la_SetCaption(t)
{
    if(this.created)
        q_SetHTML("i_"+this.index+"_ltx", t);
	
	//Log
	this.caption = t;
	this.changed |= 4096;
}


//--- Event Handling Stuff ---

function q_la_OnMouseDown()
{
	this.TriggerEvent(0); //On Click
}

function q_la_OnMouseOver()
{
	this.TriggerEvent(1); //On Mouse Over
}

function q_la_OnMouseOut()
{
	this.TriggerEvent(2); //On Mouse Out
}
//---------------------------------------------------------
//---------------------- Text Input  ----------------------
//---------------------------------------------------------


//--- Constructor ---

//Bass class: index, id, page, x, y, width, height, frame, framepic, padding, backcol, forecol, tab, zorder, required, fonts
//Ctrl specific: multiline, maxchars, initialtext, events

function q_tx(index, a)
{
	//Store baseclass properties
	var n = q_bc_Constr(this, index, a);
	
	//Store control specific properties
	this.multiline = (a[n]>0);				//Is it single line or multiline?
	this.maxchars = a[n+1];					//Maximum number of chars
	this.format = a[n+2];					//Format: 0=Normal, 1=Password, 2=Alpha, 3=AlphaNumeric, 4=Email, 5=URL, 6=Mask
	this.mask = f_strings[a[n+3]];			//Mask (if Format is 6)
	this.initialtext = f_strings[a[n+4]];	//Text to be displayed
	this.events = a[n+5];					//Event triggers ([0]=Focus, [1]=Change)
	
	//Working Properties
	this.data = this.initialtext;
	
	//Methods (Overwrites)
	this.Create = q_tx_Create;
	this.SetBackCol = q_tx_SetBackCol;
	this.SetReadOnly = q_tx_SetReadOnly;
	this.SetShaded = q_tx_SetShaded;
	this.SetEnabled = q_tx_SetEnabled;
	
	this.CheckValid = q_tx_CheckValid;
	this.CheckObligatory = q_tx_CheckObligatory;
	this.GetData = q_tx_GetData;
	this.GetDataHelper = q_tx_GetDataHelper;
	this.SetData = q_tx_SetData;
	this.ResetData = q_tx_ResetData;
		
	//Event handling methods (Overwrites)
	this.OnKeyPress = q_tx_OnKeyPress;
	this.OnKeyRelease = q_tx_OnKeyRelease;
	this.OnFocus = q_tx_OnFocus;
	this.OnChange = q_tx_OnChange;

	//Rules: "9"=0-9, "a"= A-Z, "b"=A-Z,Accents, "c"=A-Z,0-9, "d"=A-Z,0-9,Accents, "*"=Anything	
	this.maskrules = {"9":/[0-9]/, "c":/[A-Z0-9]/i, "d":/[A-Z0-9\xC1-\xFF]/i, "b":/[A-Z\xC1-\xFF]/i, "a":/[A-Z]/i, "*": /./};

	//Mask Helpers
	this.AddChar = q_tx_AddChar;
	this.ValidateMask = q_tx_ValidateMask;
}


//--- HTML Writer ---

function q_tx_Create()
{
	var h, s;

    //Style
	s = 'style="width: ' + q_GetControlWidth(this.cwidth) + 'px; height: ' + q_GetControlHeight(this.cheight) + 'px; background-color: #' + this.GetShadedColor(this.backcol) + '; color: #' + this.forecol + '; ' + q_GetFontCSS(this.font) + '"';

    //HTML
	if(this.multiline)
	{
	    //Multiline
		h = '<textarea ' + s + ' wrap="soft" tabindex=' + this.tab + ' cols=' + (this.cwidth/10) + ' rows=' + (this.cheight/22) + ' maxlength=' + this.maxchars + q_GetDisabledAttribute(this.enabled) + ' onkeypress="return q_OnKeyPress(event, '+this.index+');" onfocus="q_OnFocus(event, '+this.index+');" onchange="q_OnChange(event, '+this.index+');" onkeyup="return q_OnKeyRelease(event, '+this.index+')";>' + this.data + '</textarea>';
	}
	else	
	{
	    //Single line
		var mc = '';
		if(this.maxchars>0) mc = 'maxlength=' + this.maxchars;		

		h = '<input ' + s + ' size='+q_GetCharSize(this.font, this.cwidth)+' tabindex='+this.tab+' type="' +(this.format==1?'password':'text') + '" value="' + this.data + '" ' + mc + q_GetDisabledAttribute(this.enabled) + ' onkeypress="return q_OnKeyPress(event, '+this.index+');" onfocus="q_OnFocus(event, '+this.index+');" onchange="q_OnChange(event, '+this.index+');" onkeyup="return q_OnKeyRelease(event, '+this.index+')";>';
	}
	
	//Create it
	this.CreateMainDiv(h, true);
}


//--- Property Handling Methods ---

function q_tx_SetBackCol(c)
{
	this.backcol = c;
	
	if(this.created)
	{
	    this.SetHTMLMainDivBackCol(this.GetShadedColor(c));
	    this.SetHTMLElementBackCol(0, this.GetShadedColor(c));
    }

    //Log
	this.changed |= 8;
}

function q_tx_SetReadOnly(r)
{
	//Remember the current value, in case the user deletes it
	if(r) this.data = this.GetDataHelper();

	//Change status
	this.readonly = r;
	
	if(this.created)
    	this.GetHTMLElement(0).readonly = r;

    //Log
	this.changed |= 32;
}

function q_tx_SetShaded(r)
{
	this.shaded = r;
	
	if(this.created)
	{
	    this.SetHTMLMainDivBackCol(this.GetShadedColor(this.backcol));
	    this.SetHTMLElementBackCol(0, this.GetShadedColor(this.backcol));
    }
    
    //Log
	this.changed |= 64;
}

function q_tx_SetEnabled(r)
{
	this.enabled = r;

	if(this.created)
 	    this.GetHTMLElement(0).disabled = !r;

    //Log
	this.changed |= 16;
}


//--- Data Handling Methods ---

function q_tx_CheckValid()
{
	var v = this.GetDataHelper();
	if(this.format==4 && v!="" && !q_IsValidEmail(v)) return q_Texts[17];
	if(this.format==5 && v!="" && !q_IsValidURL(v)) return q_Texts[18];
	return null;
}

function q_tx_CheckObligatory()
{
	return !(this.required && this.enabled && (this.GetDataHelper() == ""));
}

function q_tx_GetData()
{
	var d = new Array(1);
	d[0] = this.id + "|" + this.GetDataHelper();
	return d;
}

function q_tx_GetDataHelper()
{
	//To avoid readonly deletes
	if(!this.created || this.readonly)
		return q_Trim(this.data);
	else
		return "" + q_Trim(this.GetHTMLElementValue(0));
}

function q_tx_SetData(fn, v)
{
	if(fn!=this.id) return false;
	else
	{
		//Validate Value
		v=""+v;
		if(this.maxchars>0 && v.length>=this.maxchars) v=v.substring(0, this.maxchars);
		
		//Set it
		this.data = v;
    	if(this.created)
		    this.SetHTMLElementValue(0, v);

		//Event trigger
		this.TriggerEvent(1); //On Change
		
		return true;
	}
}

function q_tx_ResetData()
{
	this.ResetProperties();
	
	this.data = this.initialtext;
	if(this.created)
	    this.SetHTMLElementValue(0, this.initialtext);
}


//--- Event Handlers ---

function q_tx_OnKeyPress(k, t)
{
	//If Read-Only don't allow any changes
	if(this.readonly || !this.enabled || !this.created) return false;
	
	//Backspace and cursors are always ok
	if(k!=8 && k!=0 && (k<33 || k>40))
	{
		//New character entered
		var c = String.fromCharCode(k);

		//Suppress "ENTER" key to submit
		if(!this.multiline && k==13) return false;
		
		//Suppress Non-Alpha if Format = 2
		if(this.format==2 && (k<97 || k>122) && (k<65 || k>90) && k!=32) return false;

		//Suppress Non-AlphaNumeric if Format = 3
		if(this.format==3 && (k<97 || k>122) && (k<65 || k>90) && (k<48 || k>57) && k!=32) return false;

		//Enforce maximum allowed chars
		if(this.maxchars>0 &&
			(""+this.GetHTMLElementValue(0)).length >= this.maxchars) return false;
		
		//Enforce mask
		if(this.format==6)
		{	
			//Get current entered value and length
			var v = ""+this.GetHTMLElementValue(0),
				vl = v.length,
				ml = this.mask.length,
				p, m;
			
			//Get Caret Position
			p = this.GetHTMLElementCaretPos(0);
			if(p<0 || p>vl) p=vl; //If not valid, assume it's at the end

			//Cannot add at end if full
			if(vl>=ml && p>=vl) return false;

			//Check character with mask
			m = this.mask.charAt(p);
			if(this.maskrules[m.toLowerCase()])
			{
				//It's must be a special character: Test it
				if(this.maskrules[m.toLowerCase()].test(c))
				{
					//It's ok, add or overwrite, and move to next caret pos
					v = this.AddChar(v, c, p++, ml);
				}
				else
				{
					//It's not ok, abandon
					return false;
				}
			}
			else
			{
				//It's a fixed literal. Is it the one that's typed?
				if(c==m)
				{
					//Yes, correct literal is typed, add or overwrite, and move to next caret pos
					v = this.AddChar(v, c, p++, ml);
				}
				else
				{		
					//No, incorrect literal is typed, write all literals until next mask position
					while(true)
					{
						//Add literal character
						v = this.AddChar(v, m, p++, ml);
						
						//End of mask reached?
						if(p>=ml) break;
						 
						//Otherwise, look at next character
						m = this.mask.charAt(p);
						
						//Is it a special character?
						if(this.maskrules[m.toLowerCase()])
						{
							//Yes, special character: If it matches add it, otherwise ignore
							if(this.maskrules[m.toLowerCase()].test(c))
								v = this.AddChar(v, c, p++, ml);
							
							//Stop loop
							break;
						}
						//Else: Literal: Keep adding (while-loop)
					}
				}
			}
			
			//Make sure mask is intact (and apply Uppercase masks)
			v = this.ValidateMask(v);
			
			//Update Display, and suppress key
			this.SetHTMLElementValue(0, v);
			
			//Put Caret
			if(p>v.length) p=v.length;
			this.SetHTMLElementCaretPos(0, p);
			
			//Suppress automatic insert
			return false;
		}
	}
	
	//Not handled
	return true;
}

function q_tx_OnKeyRelease(k)
{
	if(this.format==6)
	{
		//Make sure mask is intact
		var v = this.GetHTMLElementValue(0),
			w = this.ValidateMask(v),
			p;
		
		//Has it changed?
		if(w!=v)
		{
			//Remember Caret Pos
			p = this.GetHTMLElementCaretPos(0);

			//Update Text
			this.SetHTMLElementValue(0, w);
			
			//Put Caret at same pos
			if(p<w.length && p>=0) this.SetHTMLElementCaretPos(0, p);
		}
	}
	
	this.TriggerEvent(2); //On Key Change
}

function q_tx_OnFocus()
{
	this.TriggerEvent(0); //On Focus
}

function q_tx_OnChange()
{
	this.TriggerEvent(1); //On Change
}


//Mask Helpers
function q_tx_ValidateMask(v)
{
	var i=0, j=0, m, c, w="", vl = v.length, ml = this.mask.length;
	while(i<vl && j<ml)
	{
		c = v.charAt(i);
		m = this.mask.charAt(j);
		if((this.maskrules[m.toLowerCase()] && this.maskrules[m.toLowerCase()].test(c)) || (m==c))
		{
			//It's perfect match, move to next one
			
			//Handle uppercase mask
			if(m.toLowerCase()!=m)
				w += c.toUpperCase();
			else
				w += c;
				
			i++;
			j++;
		}
		else
		{
			//No match
			if(this.maskrules[m.toLowerCase()])
			{
				//It a special character, skip to next source character, maybe that one will fit
				i++;
			}
			else
			{
				//It must a literal: Use it, and move to next mask character
				w += m;
				j++;
			}
		}
	}
	
	return w;
}

function q_tx_AddChar(s, c, p, m)	//s=String, c=Char to add, p=Position wher to add, m=Max length of string
{
	var l = s.length;
	
	//Append at end?
	if(p==l && l<m) return s+c;
	
	//Add in middle
	if(p>=0 && p<l)
	{
		//Insert or overwrite?
		if(l<m)
			//Insert
			return s.substring(0,p)+c+s.substring(p,l);
		else
			//Overwrite
			return s.substring(0,p)+c+s.substring(p+1,l);			
	}
	
	//None of above, return unchanged
	return s;
}
//---------------------------------------------------------
//-------------------- Static Picture  --------------------
//---------------------------------------------------------


//--- Constructor ---

//Bass class: index, id, page, x, y, width, height, frame, framepic, padding, backcol, forecol, tab, zorder, required, fonts
//Ctrl specific: pic, picwidth, picheight

function q_pi(index, a)
{
	//Store baseclass properties
	var n = q_bc_Constr(this, index, a);
	
	//Store control specific properties
	this.pic = a[n];			//Number of emoticon pictures
	this.picwidth = a[n+1];
	this.picheight = a[n+2];
	this.events = a[n+3];		//Event triggers ([0]=Cicked, [1]=Over, [2]=Out)

	//Default Poroperties
	this.source = f_resources[this.pic].src;
 	
	//Methods (Overwrites)
	this.Create = q_pi_Create;
	if(this.events!=0)
	{
	    if(this.events[0]!="") this.OnMouseDown = q_pi_OnMouseDown;
	    if(this.events[1]!="") this.OnMouseOver = q_pi_OnMouseOver;
	    if(this.events[2]!="") this.OnMouseOut = q_pi_OnMouseOut;
    }
    	
	//Scripting Method
	this.SetSource = q_pi_SetSource;
}


//--- HTML Writer ---

function q_pi_Create()
{
	//Write Main-Div containing Pic
	var c = '<img src="' + this.source + '" width=' + this.picwidth + ' height=' + this.picheight + ' name="i_'+this.index+'_pc" galleryimg="no" ';
	if(this.events!=0 && this.events[0]!="")
	    c += 'class=st_p '; //If click event, have hand-pointer

	//Event triggers (MouseOver & MouseOut)
	if(this.events!=0 && (this.events[1]!="" || this.events[2]!=""))
		c += 'onmouseover="q_OnMouseOver(event, '+this.index+');" onmouseout="q_OnMouseOut(event, '+this.index+');" ';

    //Close tag	
	c += '>';
	
	//Create it
	this.CreateMainDiv(c, false);
}

function q_pi_OnMouseDown()
{
	this.TriggerEvent(0); //On Click
}

function q_pi_OnMouseOver()
{
	this.TriggerEvent(1); //On Mouse Over
}

function q_pi_OnMouseOut()
{
	this.TriggerEvent(2); //On Mouse Out
}

//Scripting Methods
function q_pi_SetSource(s)
{
    if(this.created)
    	this.GetImage("i_"+this.index+"_pc").src = s;

	//Log
	this.source = s;
	this.changed |= 2048;
}
//---------------------------------------------------------
//----------------------- Checkboxes  ---------------------
//---------------------------------------------------------


//--- Constructor ---

//Bass class: index, id, page, x, y, width, height, frame, framepic, padding, backcol, forecol, tab, zorder, required, fonts
//Ctrl specific: answertype, minanswers, maxanswers, buttonsize, buttonpic, captiononright, align, answers, events
//Answers: x, y, w, h, text, value, checked

function q_ch(index, a)
{
	//Store baseclass properties
	var n = q_bc_Constr(this, index, a);
	
	//Store control specific properties
	this.answertype = a[n];			//0..Single, 1..Multi, 2..User Defined
	this.minanswers = a[n+1];		//If answertype=2: Minimum answers needed
	this.maxanswers = a[n+2];		//If answertype=2: Maximum answers allowed
	this.buttonsize = a[n+3];		//Width and height of checkbox button
	this.buttonpic = a[n+4];		//Picture index of checkbox pic, must be followed by "ticked" pic
	this.captiononright = (a[n+5]>0);//Are captions on right, not left?
	this.align = a[n+6];			//Aligment of caption
	this.randomize = (a[n+7]>0);	//Randomize
	var aa = a[n+8];				//Array of answers
	this.events = a[n+9];			//Event triggers ([0]=Focus, [1]=Change)

	//Treat answers
	var an = aa.length;
	this.answers_n = an;			//Number of answers

	this.answers = new Array(an);
	for(var i=0; i<an; i++)
	{
		this.answers[i] = new Object();
		this.answers[i].x = aa[i][0];
		this.answers[i].y = aa[i][1];
		this.answers[i].width = aa[i][2];
		this.answers[i].height = aa[i][3];
		this.answers[i].caption = f_strings[aa[i][4]];
		this.answers[i].value = f_strings[aa[i][5]];
		this.answers[i].initialchecked = (aa[i][6]>0);
		this.answers[i].checked = (aa[i][6]>0);
	}
	
	//Randomization
	if(this.randomize)
	{
		//Simply shuffle x/y positions
		for(var i=0; i<an; i++)
		{
			var s0 = Math.floor(Math.random()*an);
			var s1 = Math.floor(Math.random()*an);
		
			//Swap indexes
			var ox = this.answers[s0].x;
			var oy = this.answers[s0].y;
			this.answers[s0].x = this.answers[s1].x;
			this.answers[s0].y = this.answers[s1].y;
			this.answers[s1].x = ox;
			this.answers[s1].y = oy;
		}
	}

	//Constants
	this.gap = 5;					//Width of gap between checkbox and caption

	//Working variables
	this.currentlypressedcheckbox = -1;	//Index of checkbox that has been pressed down (remember it for Mouse Up)
	this.mousedownx = - 1;
	this.mousedowny = - 1;
	this.lastselected = null;			//Scripting/Multi-answer only: Index of check box that was selected last (null if none de-selected)
	
	//Methods (Overwrites)
	this.Create = q_ch_Create;
	this.Show = q_ch_Show;
	
	//Proprerty handling methods (Overwrites)
	this.SetX = q_ch_SetX;
	this.SetY = q_ch_SetY;
	this.SetVisible = q_ch_SetVisible;
	this.SetZOrder = q_ch_SetZOrder;
	this.SetEnabled = q_ch_SetEnabled;
	this.SetTransparency = q_ch_SetTransparency;
	
	this.CheckObligatory = q_ch_CheckObligatory;
	this.GetData = q_ch_GetData;
	this.SetData = q_ch_SetData;
	this.ResetData = q_ch_ResetData;
	this.CopyData = q_ch_CopyData;
	
	//Scripting methods
	this.GetState = q_ch_GetState;
	this.SetState = q_ch_SetState;
	this.SetValue = q_ch_SetValue;
	this.GetValue = q_ch_GetValue;
	this.GetValueCaption = q_ch_GetValueCaption;

	//Event handling methods (Overwrites)
	this.OnMouseDown = q_ch_OnMouseDown;
	this.OnMouseMove = q_ch_OnMouseMove;
	this.OnMouseUp = q_ch_OnMouseUp;
}


//--- HTML Writer ---

function q_ch_Create()
{
	//Create empty main div
	this.CreateMainDiv("&nbsp;", false);
	
	//Write Div for each answer
	for(var i=0; i<this.answers_n; i++)
	{
		var h =	'<table cellspacing=0 cellpadding=0 border=0 width='+this.answers[i].width+' height='+this.answers[i].height+'><tr>';
		
		var checktd, captd, gaptd;
		checktd = '<td width='+this.buttonsize+' '+q_GetAlignHTML(this.align)+'><img src="'+f_resources[parseInt(this.buttonpic)+parseInt((this.answers[i].checked?1:0)+(this.enabled?0:2))].src+'" width='+this.buttonsize+' height='+this.buttonsize+' name="i_'+this.index+'_ich'+i+'" class="st_p"></td>';
		gaptd =	'<td width='+this.gap+'><img src="'+f_resources[0].src+'" width='+this.gap+' height=2></td>'; 
		captd = '<td width='+(this.answers[i].width-this.buttonsize-this.gap)+' style="color: #' + this.forecol + '; ' + q_GetFontCSS(this.font) + '" '+q_GetAlignHTML(this.align)+'>'+this.answers[i].caption+'</td>';

		if(this.captiononright) h += checktd + gaptd + captd;
		else h += captd + gaptd + checktd;
				
		h += '</tr></table>';

        this.CreateDiv('i_'+this.index+'_ch'+i,
                        this.x + this.answers[i].x,
                        this.y + this.answers[i].y,
                        this.zorder*10+11,
                        h, false, false, this.answers[i].width);
	}
}


//--- Event Handlers ---

function q_ch_OnMouseDown(eX, eY, id)
{
	//Don't do anything if disabled or read-only
	if(this.readonly || !this.enabled) return true;

	//Register Focus and to OnFocus Event
	q_RegisterFocus(this.index);
	this.TriggerEvent(0); //On Focus
	
	//Check if clicked on checkbox pic
	if(id.indexOf("i_"+this.index+"_ich")==0)
	{
		//Get index of answer clicked
		var i = parseInt(id.substring(("i_"+this.index+"_ich").length));

		if(i>=0 && i<this.answers_n)
		{
			//Remember stuff for Mouse Up
			this.currentlypressedcheckbox = i;
			this.mousedownx = eX;
			this.mousedowny = eY;
			
			//Draw temporary gray button
			q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
				f_resources[this.buttonpic+parseInt(this.answers[this.currentlypressedcheckbox].checked?1:0)+2].src;
						
			//Capture Mouse
			q_CaptureMouse(this.index);
			return false;
		}				
	}
	
	return true;
}

function q_ch_OnMouseMove(eX, eY)
{
	var pic = parseInt(this.answers[this.currentlypressedcheckbox].checked?1:0);
	
	//Move away?
	if(Math.abs(eX-this.mousedownx)<this.buttonsize && Math.abs(eY-this.mousedowny)<this.buttonsize)
	{
		//No, draw temporary gray button
		pic += 2;
	}
	//else, draw normal image
	
	//Update picture
	q_GetImage("i_"+this.index+"_ch"+this.currentlypressedcheckbox, "i_"+this.index+"_ich"+this.currentlypressedcheckbox).src =
		f_resources[this.buttonpic+pic].src;
		
	return false;
}

function q_ch_OnMouseUp(eX, eY)
{
	var i = this.currentlypressedcheckbox;
	
	//Only if mouse hasn't move away too far
	if(Math.abs(eX-this.mousedownx)<this.buttonsize && Math.abs(eY-this.mousedowny)<this.buttonsize)
	{
		//Checkbox was clicked!	
		if(this.answertype==0)
		{
			//Single Answer
			this.answers[i].checked = !this.answers[i].checked;

			//If this is check uncheck all others
			if(this.answers[i].checked)
			{
				//Uncheck all others
				for(var j=0; j<this.answers_n; j++)
					if(j!=i && this.answers[j].checked)
					{
						//Uncheck it
						this.answers[j].checked = false;
						
						//Change Image
						q_GetImage("i_"+this.index+"_ch"+j, "i_"+this.index+"_ich"+j).src =
							f_resources[parseInt(this.buttonpic)].src;
					}
			}
		}
		else
		{
			//Multiple Answers
			
			if(this.answertype==2)
			{
				//User Defined (Min, Max)
				var count=0;
				for(var j=0; j<this.answers_n; j++) if(this.answers[j].checked) count++;

				//Is Max Answers already reached?
				if(this.answers[i].checked || count<this.maxanswers)
				{
					this.answers[i].checked = !this.answers[i].checked;
				}
			}
			else
			{
				//Simply change status of clicked checkbox
				this.answers[i].checked = !this.answers[i].checked;
			}
				
			//Remember this one as last checked
			if(this.answers[i].checked)
			{
				this.lastselected = i;
				this.changed |= 16384;
			}
		}
		
		//Event Trigger
		this.TriggerEvent(1); //On Change
	}
		
	//Change Image
	q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
		f_resources[parseInt(this.buttonpic)+parseInt(this.answers[i].checked?1:0)].src;
		
	//Release Mouse
	q_ReleaseMouse(this.index);
}


//--- Visibility Methods ---

function q_ch_Show(s)
{
	this.showing = s;

	//Make sure it's created, the 1st time we show it
	if(!this.created && s) this.Create();
	
	//Update visiblity
	if(this.created)
	{
	    q_SetVisible("i_"+this.index+"_d", s & this.visible);
    	
	    for(var i=0; i<this.answers_n; i++)
		    q_SetVisible("i_"+this.index+"_ch"+i, s & this.visible);
    }
}

function q_ch_SetVisible(v)
{
	this.visible = v;
	
	if(this.created && this.showing)
    {
        //Background main div
	    q_SetVisible("i_"+this.index+"_d", v & this.showing);
	
	    //Each answer div
	    for(var i=0; i<this.answers_n; i++)
		    q_SetVisible("i_"+this.index+"_ch"+i, v & this.showing);
    }
    
	this.changed |= 128;
}

function q_ch_SetTransparency(t) //TO DO in HTML!
{
	this.transparency = t;

	if(this.created)
	{
	    q_SetTransparency("i_"+this.index+"_d", t);
    	
	    for(var i=0; i<this.answers_n; i++)
		    q_SetTransparency("i_"+this.index+"_ch"+i, t);
	}

	//Log
	this.changed |= 512;
}


//--- Data Handling Methods ---

function q_ch_CheckObligatory() //TO DO
{
	//How many checked
	var count=0;
	for(var j=0; j<this.answers_n; j++) if(this.answers[j].checked) count++;

	//Nothing checked and obligatory? Or User-defined and Min answers not reached?
	return !(this.enabled && ((count==0 && this.required) || (this.answertype==2 && count<this.minanswers)));
}

function q_ch_GetData()
{
	if(this.answertype==0)
	{
		//Single Answer
		var d = new Array(1);
		for(var i=0; i<this.answers_n; i++)
			if(this.answers[i].checked)
			{
				d[0] = this.id + "|" + this.answers[i].value;
				return d;
			}
				
		//Nothing checked
		d[0] = this.id + "|"; //Return empty value
		return d;
	}
	else
	{
		//Multiple Answers
		var answersfound = 0;
		var d = new Array();
		for(var i=0; i<this.answers_n; i++)
			if(this.answers[i].checked || this.answers[i].initialchecked)
				d[answersfound++] = this.id + "_" + (i+1) + "|" + parseInt(this.answers[i].checked?1:0);
				
		if(answersfound>0) return d;
		//Nothing checked
		else return null;
	}
}

function q_ch_SetData(fn, v)
{
	if(this.answertype==0)
	{
		//Single Answer
		if(fn!=this.id) return false;
		else
		{
			for(var i=0; i<this.answers_n; i++)
			{
				this.answers[i].checked = (v==this.answers[i].value);
				
				//Update Image
				if(this.created)
				    q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
					    f_resources[parseInt(this.buttonpic)+parseInt(this.answers[i].checked?1:0)].src;
			}
			
			//Event trigger
			this.TriggerEvent(1); //On Change
			
			return true;
		}
	}
	else
	{
		//Multiple Answers
		for(var i=0; i<this.answers_n; i++)
		{
			if((this.id+"_"+(i+1))==fn)
			{
				this.answers[i].checked = (v=="1");
				
				//Update Image
				if(this.created)
				    q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
					    f_resources[parseInt(this.buttonpic)+parseInt(this.answers[i].checked?1:0)].src;

				//Remember last checked
				if(this.answers[i].checked && !f_preloading)
				{
					this.lastselected = i;
					this.changed |= 16384;
				}
				
				//Event trigger
				this.TriggerEvent(1); //On Change
				
				return true;
			}
		}
		return false;
	}
}

function q_ch_ResetData()
{
	this.ResetProperties();

	for(var i=0; i<this.answers_n; i++)
	{
		this.answers[i].checked = this.answers[i].initialchecked;
		
		//Update Image
    	if(this.created)
	    	q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
		    	f_resources[parseInt(this.buttonpic)+parseInt(this.answers[i].checked?1:0)].src;
	}
	this.lastselected = null;
}

function q_ch_CopyData(id)
{
	//Find object from ID
	var c = q_GetControlByID(id);
	
	//Must exists and also be a table
	if(c!=null && c.type==this.type)
	{
		//Clear all
		for(var i=0; i<this.answers_n; i++)
			this.answers[i].checked = false;
			
		//Find all checked ones in source
		for(var i=0; i<c.answers_n; i++)
			if(c.answers[i].checked)
			{
				//Found, now look for matching value
				for(var j=0; j<this.answers_n; j++)
					if(c.answers[i].value==this.answers[j].value)
					{
						//Match found. Check it
						this.answers[j].checked  = true;
						break;
					}
			}
			
		//Update images
    	if(this.created)
    		for(var i=0; i<this.answers_n; i++)
	    		q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
		    		f_resources[parseInt(this.buttonpic)+parseInt(this.answers[i].checked?1:0)].src;
	}
}


//--- Scripting Methods ---

function q_ch_GetState(i)
{
	//Validate
	if(i<1 || i>this.answers_n) return null;

	return this.answers[i-1].checked;
}

function q_ch_SetState(i, b)
{
	//Validate
	if(i<1 || i>this.answers_n) return;
	
	//Do it
	i--;
	
	if(this.answertype==0 && b)
	{
		//Single Answer Checked
		for(var j=0; j<this.answers_n; j++)
		{
			this.answers[j].checked = (i==j);
			
			//Update image
    	    if(this.created)
			    q_GetImage("i_"+this.index+"_ch"+j, "i_"+this.index+"_ich"+j).src =
				    f_resources[parseInt(this.buttonpic)+parseInt(this.answers[j].checked?1:0)].src;
		}		
	}
	else
	{
		//Multi Answer checked/unchecked, or Single Answer unchecked

		this.answers[i].checked = b;

		//Update image
	    if(this.created)
    		q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
	    		f_resources[parseInt(this.buttonpic)+parseInt(this.answers[i].checked?1:0)].src;
			
		//Remember last checked
		if(b)
		{
			this.lastselected = i;		
			this.changed |= 16384;
		}
	}
	
	//Event trigger
	this.TriggerEvent(1); //On Change
}

function q_ch_SetValue(v)
{
	if(this.answertype==0)
	{
		//Single Response
		return this.SetData(this.id, v);
	}
	else
	{
		//Multiresponse
		if(v==null || v=="")
		{
			//Clear all
			for(var i=0; i<this.answers_n; i++)
			{
				this.answers[i].checked = false;
				
				//Update Image
        	    if(this.created)
	    			q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
		   				f_resources[parseInt(this.buttonpic)].src;
			}
			
			//Event trigger
			this.TriggerEvent(1); //On Change
		}
		else
		{
			//Select one
			for(var i=0; i<this.answers_n; i++)
			{
				if(this.answers[i].value == v)
				{
					this.answers[i].checked = true;
					
				    //Update Image
        	        if(this.created)
					    q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
						    f_resources[parseInt(this.buttonpic)+1].src;
						
					this.lastselected = i;
					this.changed |= 16384;
					
					//Event trigger
					this.TriggerEvent(1); //On Change
				}
			}
		}
	}
}

function q_ch_GetValue()
{
	if(this.answertype==0)
	{
		//Single Response
		for(var i=0; i<this.answers_n; i++)
			if(this.answers[i].checked)
				return q_HandleNumeric(this.answers[i].value);
		
		//Else
		return null;
	}
	else
	{
		//Multiresponse
		
		//Anything checked at all (in case last answer got unchecked)?
		for(var i=0; i<this.answers_n; i++)
		{
			if(this.answers[i].checked)
			{
				//Yes, at least one answer is still checked
				if(this.lastselected!=null && this.answers[this.lastselected].checked)
					return q_HandleNumeric(this.answers[this.lastselected].value);
				else
					return q_HandleNumeric(this.answers[i].value);
			}
		}
		//No, nothing checked
		return null;		
	}
}

function q_ch_GetValueCaption()
{
	if(this.answertype==0)
	{
		//Single Response
		for(var i=0; i<this.answers_n; i++)
			if(this.answers[i].checked) return this.answers[i].caption;
			
		//Nothing checked
		return null;
	}
	else
	{
		//Anything checked at all (in case last answer got unchecked)?
		for(var i=0; i<this.answers_n; i++)
		{
			if(this.answers[i].checked)
			{
				//Yes, at least one answer is still checked
				if(this.lastselected!=null && this.answers[this.lastselected].checked)
					return this.answers[this.lastselected].caption;
				else
					return this.answers[i].caption;
			}
		}
		//No, nothing checked
		return null;
	}
}


//--- X/Y Postion Methods ---

function q_ch_SetX(x)
{
	if(x>=0 && x<=f_page_w-this.width)
	{
		this.x = x;
		
		if(this.created)
    	{
		    q_SetLeft("i_"+this.index+"_d", x);
		
		    for(var i=0; i<this.answers_n; i++)
			    q_SetLeft("i_"+this.index+"_ch"+i, x + this.answers[i].x);
        }
        
		this.changed |= 1;
	}
}

function q_ch_SetY(y)
{
	if(y>=0 && y<=f_page_h-this.height)
	{
		this.y = y;
		
		if(this.created)
    	{
		    q_SetTop("i_"+this.index+"_d", y);
		
		    for(var i=0; i<this.answers_n; i++)
			    q_SetTop("i_"+this.index+"_ch"+i, y + this.answers[i].y);
        }
        
		this.changed |= 2;
	}
}

function q_ch_SetZOrder(z)
{
	if(z>=0 && z<3276)
	{
		this.zorder = z;
		
		if(this.created)
    	{
		    q_SetZOrder("i_"+this.index+"_d", z*10+10);
    		
		    for(var i=0; i<this.answers_n; i++)
			    q_SetZOrder("i_"+this.index+"_ch"+i, z*10+11);
        }
        
		this.changed |= 4;
	}
}

function q_ch_SetEnabled(e)
{
	this.enabled = e;
	
	if(this.created)
   	{
	    //Gray out images
	    var g = e?0:2;
	    for(var i=0; i<this.answers_n; i++)
	    {
		    q_GetImage("i_"+this.index+"_ch"+i, "i_"+this.index+"_ich"+i).src =
			    f_resources[parseInt(this.buttonpic)+parseInt(this.answers[i].checked?1:0)+g].src;
	    }
    }
    
	this.changed |= 16;
}
//---------------------------------------------------------
//------------------ Drop-Down Selection  -----------------
//---------------------------------------------------------


//--- Constructor ---

//Bass class: index, id, page, x, y, width, height, frame, framepic, padding, backcol, forecol, tab, zorder, required, fonts
//Ctrl specific: answers[], values[], selected, events

function q_dd(index, a)
{
	//Store baseclass properties
	n = q_bc_Constr(this, index, a);
	
	//Store control specific properties
	this.answers = a[n];			//Array that contains all the answer labels
	this.values = a[n+1];			//Array that contains all the answer values
	this.initialselected = a[n+2];	//Initially selected answer (-1 if none)
	this.randomize = (a[n+3]>0);	//Randomize
	this.events = a[n+4];			//Event triggers ([0]=Focus, [1]=Change)
	
	//Defaults
	this.data = this.initialselected;	//Used for read-only functionality, etc...
	this.changedanswers = null;		    //Stores string if SetAnswers ist used (for state info)

	//Order / Randomization / Get String Values
	this.order = new Array();
	for(var i=0; i<this.answers.length; i++)
	{
		this.order[i] = i;
		this.answers[i] = f_strings[this.answers[i]];
		this.values[i] = f_strings[this.values[i]];
	}
	if(this.randomize) q_Randomize(this.order, 0, this.answers.length);

	//Methods (Overwrites)
	this.Create = q_dd_Create;
	this.SetBackCol = q_dd_SetBackCol;
	this.SetReadOnly = q_dd_SetReadOnly;
	this.SetEnabled = q_dd_SetEnabled;
	this.SetShaded = q_dd_SetShaded;
	
	this.GetData = q_dd_GetData;
	this.GetDataHelper = q_dd_GetDataHelper;
	this.SetData = q_dd_SetData;
	this.ResetData = q_dd_ResetData;
	this.CopyData = q_dd_CopyData;
	this.CheckObligatory = q_dd_CheckObligatory;
	
	//Scripting methods
	this.GetValueCaption = q_dd_GetValueCaption;
	this.GetState = q_dd_GetState;
	this.SetState = q_dd_SetState;
	this.SetAnswers = q_dd_SetAnswers;

	//Event handling	
	this.OnChange = q_dd_OnChange;
	this.OnFocus = q_dd_OnFocus;
}


//--- HTML Writer ---

function q_dd_Create()
{
	var h = '<select tabindex=' + this.tab + ' width=' + q_GetControlWidth(this.width) + ' size=1 style="width: ' + q_GetControlWidth(this.cwidth) + 'px; height: ' + q_GetComboBoxHeight(this.cheight) + 'px; background-color: #' + this.GetShadedColor(this.backcol) + '; color: #' + this.forecol + '; ' + q_GetFontCSS(this.font) + '"' + q_GetDisabledAttribute(this.enabled) + ' onchange="return q_OnChange(event, ' + this.index + ');" onfocus="q_OnFocus(event, ' + this.index + ');">';
	
	//Nothing selected by default?
	if(this.initialselected<0)
	{
		h += '<option value="-1"';
		if(this.data<0) h += ' selected';
		h += '>&nbsp;</option>';
	}
	
	//Add each answer as <option/>
	for(var i=0; i<this.answers.length; i++)
	{
		h += '<option value="'+this.order[i]+'"';
		if(this.order[i]==this.data) h += ' selected';
		h += '>'+this.answers[this.order[i]]+'</option>';
	}
	
	h += '</select>';
	
	//Create it
	this.CreateMainDiv(h, true);
}


//--- Property Handling Methods ---

function q_dd_SetBackCol(c)
{
	this.backcol = c;

	if(this.created)
  	{
	    this.SetHTMLMainDivBackCol(this.GetShadedColor(c));
	    this.SetHTMLElementBackCol(0, this.GetShadedColor(c));
    }

    //Log    
	this.changed |= 8;
}

function q_dd_SetReadOnly(r)
{
    //Remember ReadOnly value
   	this.data = this.GetDataHelper();

	this.readonly = r;
	
    //Log    
	this.changed |= 32;
}

function q_dd_SetEnabled(r)
{
	this.enabled = r;
	
	if(this.created)
    	this.GetHTMLElement(0).disabled = !r;
	
	//Log
	this.changed |= 16;
}

function q_dd_SetShaded(r)
{
	this.shaded = r;

	if(this.created)
	{	
	    this.SetHTMLMainDivBackCol(this.GetShadedColor(this.backcol));
	    this.SetHTMLElementBackCol(0, this.GetShadedColor(this.backcol));
    }

    //Log    
	this.changed |= 64;
}


//--- Data Handling Methods ---

function q_dd_CheckObligatory()
{
	return !(this.required && this.enabled && this.GetDataHelper()<0);
}

function q_dd_GetData()
{
	//Is "nothing" selected?
	if(this.GetDataHelper()<0)
	{
	    //Nothing selected
	    return null;
	}
	else
	{
	    //Something is selected
	    var d = new Array(1);
	    d[0] = this.id + "|" + this.values[this.GetDataHelper()];
	    return d;
	}
}

function q_dd_GetDataHelper()
{
	if(!this.created || this.readonly)
		return this.data;
	else
		return this.GetHTMLElementSelectedValue(0);
}

function q_dd_SetData(fn, v)
{
	if(fn!=this.id) return false;
	else
	{
		for(var i=0; i<this.answers.length; i++)
		{
		    //Find matching value
			if(v==this.values[i])
			{
				//Store it
				this.data = i;

                //Display it
                if(this.created)            
    				this.SetHTMLElementSelectedValue(0,	i);
								
				//Event trigger
				this.TriggerEvent(1); //On Change
				
				return true;
			}
		}
		return false;
	}
}

function q_dd_ResetData()
{
	this.ResetProperties();

	this.data = this.initialselected;
	
	if(this.created)
    	this.SetHTMLElementSelectedValue(0, this.data);
}

function q_dd_CopyData(id)
{
	//Find object from ID
	var c = q_GetControlByID(id);
	
	//Must exists and also be a drop-down
	if(c!=null && c.type==this.type)
	{
		//Select empty by default
		if(this.initialselected<0)
		    this.data = -1;

        //Select same value (look for it, if it exists)
		var v = c.GetValue();
	    for(var i=0; i<this.answers.length; i++)
	        if(v==this.values[i])
	        {
	            //Matching value found
	            this.data = i;
	            break;
	        }

        //Update display
    	if(this.created)
        	this.SetHTMLElementSelectedValue(0,	this.data);
	}
}


//---- Scripting methods ---

function q_dd_GetValueCaption()
{
	//Disabled or "nothing" selected?
	if(!this.enabled || this.GetDataHelper()<0) return null;

	//Return Caption
	return this.answers[this.GetDataHelper()];
}

function q_dd_GetState(i)
{
	//Validate
	if(i<1 || i>this.values.length) return null;

	return (parseInt(this.GetDataHelper()) == i-1);
}

function q_dd_SetState(i, b)
{
	//Validate
	if(i<1 || i>this.values.length) return;
	
    //Set/Unset
	if(b)
    	this.data = i-1;
	else
    	this.data = this.initialselected;
	
	if(this.created)
    	this.SetHTMLElementSelectedValue(0,	this.data);
	
	//Event trigger
	this.TriggerEvent(1); //On Change
}

function q_dd_SetAnswers(aa)
{
	//Validate
	var a = (aa+"").split("|");
	var n = a.length;
	if(n<2 || (n&1)==1) return; //Illegal argument
	n/=2;
	
	//Update Properties
	this.answers = new Array();			//Array that contains all the answer labels
	this.values = new Array();			//Array that contains all the answer values
	this.order = new Array();
	for(var i=0; i<n; i++)
	{
		this.answers[i] = a[i*2]; 
		this.values[i] = a[i*2+1];
		this.order[i] = i;
	}
	this.initialselected = -1;          //Nothing selected initially

	//Randomization
	if(this.randomize) q_Randomize(this.order, 0, n);
	
	//Update Control
	if(this.created)
	{
	    var c = this.GetHTMLElement(0);
	    c.length = 0;
	    c.options[0] = new Option(" ", "-1"); //Empty 1st one
	    for(var i=0; i<n; i++) c.options[i+1] = new Option(this.answers[this.order[i]], this.order[i]);
    }
    
	//Log
	this.changedanswers = aa;
	this.changed |= 1024;
}


//---- Event handling methods ---

function q_dd_OnChange()
{
	if(this.readonly || !this.enabled)
	{
		//Restore previous value
		this.SetHTMLElementSelectedValue(0, this.data);
	}
	else
	{
		//Event Trigger
		this.TriggerEvent(1); //On Change
	}
}

function q_dd_OnFocus()
{
	this.TriggerEvent(0); //On Focus
}
//---------------------------------------------------------
//------------------------ Button  ------------------------
//---------------------------------------------------------


//--- Constructor ---

//Bass class: index, id, page, x, y, width, height, frame, framepic, padding, backcol, forecol, tab, zorder, required, fonts
//Ctrl specific: dispaly as pic, caption/picture index, action, param

function q_bu(index, a)
{
	//Store baseclass properties
	var n = q_bc_Constr(this, index, a);
	
	//Store control specific properties
	this.displaypic = (a[n]>0);									//true/false display as picture
	this.caption = (this.displaypic)?a[n+1]:f_strings[a[n+1]];	//Caption on button / Or picture index
	this.action = a[n+2];										//Action (0=Send, 1= )
	this.param = a[n+3];										//Additional paramater for action
	this.events = a[n+4];										//Event triggers ([0]=Focus, [1]=Change)
		
	//Methods (Overwrites)
	this.Create = q_bu_Create;
	this.SetBackCol = q_bu_SetBackCol;
	this.SetShaded = q_bu_SetShaded;
	this.SetEnabled = q_bu_SetEnabled;
	
	//Event handling methods (Overwrites)
	this.OnFocus = q_bu_OnFocus;
	if(this.displaypic)
		this.OnMouseDown = q_bu_OnChange;
	else
		this.OnChange = q_bu_OnChange;
}


//--- HTML Writer ---

function q_bu_Create()
{
	var h;
	
	//Pic or button?
	if(this.displaypic)
		h = '<img src="' + f_resources[this.caption].src + '" width=' + this.cwidth + ' height=' + this.cheight + ' name="i_' + this.index + '_pc" galleryimg=no class=st_p>';
	else
		h = '<input type="button" tabindex=' + this.tab + ' width=' + q_GetButtonWidth(this.cwidth) + ' height=' + q_GetButtonHeight(this.cheight) + ' value="' + this.caption + '"' + q_GetDisabledAttribute(this.enabled) + ' style="width: ' + q_GetButtonWidth(this.cwidth) + 'px; height: ' + q_GetButtonHeight(this.cheight) + 'px; background-color: #' + this.GetShadedColor(this.backcol) + '; color: #' + this.forecol + '; ' + q_GetFontCSS(this.font) + '" onclick="return q_OnChange(event, ' + this.index + ');" onfocus="q_OnFocus(event, ' + this.index + ');">';
	
	//Create it
	this.CreateMainDiv(h, true);
}


//--- Property Handling Methods ---

function q_bu_SetBackCol(c)
{
	this.backcol = c;

	if(this.created)
	{
	    this.SetHTMLMainDivBackCol(this.GetShadedColor(c));
	    if(!this.displaypic) this.SetHTMLElementBackCol(0, this.GetShadedColor(c));
    }
    
    //Log
	this.changed |= 8;
}

function q_bu_SetShaded(r)
{
	this.shaded = r;
	
	if(this.created)
	{
	    this.SetHTMLMainDivBackCol(this.GetShadedColor(this.GetShadedColor(this.backcol)));
	    if(!this.displaypic) this.SetHTMLElementBackCol(0, this.GetShadedColor(this.backcol));
    }
    
    //Log
	this.changed |= 64;
}

function q_bu_SetEnabled(r)
{
	this.enabled = r;

	if(this.created && !this.displaypic)
	    this.GetHTMLElement(0).disabled = !r;

    //Log	
	this.changed |= 16;
}


//--- Event Handling Methods ---

function q_bu_OnChange(t)
{
	//Don't do anything if disabled.
	if(!this.enabled) return;
	
	//Event triggger
	this.TriggerEvent(1); //On Change

	//Do it
	switch(this.action)
	{
	case 1:
		if(!this.readonly) q_SendData();
		break;	
		
	case 2:
		if(!this.readonly) q_ResetData();
		break;	

	case 3:		q_ShowURL(this.param); break;	
	case 4:
		if(this.param=="") q_NextPage();
		else q_GoToPageName(this.param);
		break;
	case 5:		q_BackHistoryPage(); break;
	case 7:		q_Print(); break;
	case 8:		q_NextPage(); break;	
	case 9:		q_PrevPage(); break;	
	}
	return true;
}

function q_bu_OnFocus()
{
	this.TriggerEvent(0); //On Focus
}
//=========================================================
//================ WRITE OUT CSS/HTML =====================
//=========================================================


q_WriteHTML();


//=========================================================
//========================= END ===========================
//=========================================================
