
/* ================================================================================================================================================== CONTROL BASE ====
*/
		function ControlBase(options)
			{
			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			ControlBase.prototype.attach			= function($ctrl, $ctrlVal)
																						{
																						this.$control = $ctrl;

																						if ($ctrlVal)
																							{
																							this.$ctrlVal = $ctrlVal;
																							this.value = $ctrlVal.val();
																							}

																						if (this.title)	{ this.$control.attr('title', this.title); }

																						if (this.onClick)
																							{
																							this.$control.bind('click', { ctrl: this }, function(ev) { ev.data.ctrl.callEvent('onClick', ev); });
																							}

																						if (this.cssHover)
																							{
																							this.$control.bind('mouseenter mouseleave', { cssHover: this.cssHover }, function(ev)
																								{
																								$(this)[((ev.type == 'mouseenter') ? 'add': 'remove') + 'Class'](ev.data.cssHover);
																								});
																							}

																						return this;
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			ControlBase.prototype.callEvent		= function(eventName, ev)
																						{
																						if ((eventName in this) && !this.disabled) { this[eventName].act.call(this, this[eventName].data, ev); }
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			ControlBase.prototype.destroy			= function()
																						{
																						this.$control.remove();
																						delete this.$control;
																						delete this.$ctrlVal;
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			ControlBase.prototype.disable			= function(disable)
																						{
																						if (disable && this.cssHover) { this.$control.removeClass(this.cssHover); }

																						this.disabled = disable;
																						this.$control.attr('disabled', disable);

																						if ('title' in this) { this.$control.attr('title', (disable) ? '' : this.title); }
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			ControlBase.prototype.setAttr			= function(name, value)
																						{
																						this[name] = value;
																						if (this.$control) { this.$control.attr(name, value); }
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			ControlBase.prototype.setEvents		= function(eventNames, opts)
																						{
																						var evNames = eventNames.split(',');

																						for (var e in evNames)
																							{
																							if (evNames[e] in opts) { this[evNames[e]] = { act: opts[evNames[e]].act, data: opts[evNames[e]].data }; }
																							}
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			ControlBase.prototype.setOptions	= function(options)
																						{
																						var opts = options || {};

																						this.setEvents('onChange,onClick,onSelect', opts);

																						if ('caption' in opts) { this.caption = opts.caption; }
																						if ('content' in opts) { this.content = opts.content; }
																						if ('title'		in opts) { this.title		= opts.title;		}
																						if ('value'		in opts) { this.value		= opts.value;		}
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			ControlBase.prototype.setValue		= function(value, eventName, ev)
																						{
																						if (this.$ctrlVal) { this.$ctrlVal.val(value); }

																						this.value = value;
																						this.callEvent(eventName, ev);

																						return this.value;
																						};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== ICON CONTROL ====
*/
		function IconControl(options)
			{
			this.cssName  = 'ctrl-icon ';
			this.cssHover = 'icon-hover';

			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			IconControl.prototype = new ControlBase();
			IconControl.prototype.constructor = IconControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			IconControl.prototype.create 			= function()
																						{
																						this.attach( $('<div/>').addClass(this.cssName + this.cssIcon).html(this.content || '') );

																						return this.$control;
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			IconControl.prototype.setCssIcon	= function(cssIcon)
																						{
																						if (this.cssIcon && this.$control) { this.$control.removeClass(this.cssIcon); }
																						this.cssIcon = cssIcon;
																						if (this.cssIcon && this.$control) { this.$control.addClass(this.cssIcon); }

																						return this;
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			IconControl.prototype.setOptions	= function(options)
																						{
																						var opts = options || {};

																						this.cssIcon = opts.cssIcon;

																						ControlBase.prototype.setOptions.call(this, opts);
																						};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== TEXT AREA CONTROL ====
*/
		function TextAreaControl(options)
			{
			this.cssName = 'ctrl-textbox';

			this.isRequired = false;
			this.readOnly		= false;
			this.cols				= 50;
			this.rows				=  5;

			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			TextAreaControl.prototype = new ControlBase();
			TextAreaControl.prototype.constructor = TextAreaControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextAreaControl.prototype.attach			= function($ctrl, $ctrlVal)
																								{
																								ControlBase.prototype.attach.call(this, $ctrl, $ctrlVal || $ctrl);

																								if (this.readOnly)	 { this.$control.attr({ readonly: -1, tabindex: -1 }); }
																								if (this.isRequired) { this.$control.addClass('required'); }

																								return this;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextAreaControl.prototype.create 			= function()
																								{
																								return this.attach($('<textarea/>').addClass(this.cssName).
																																										html(this.value).
																																										attr( { name: this.name,
																																														cols: this.cols,
																																														rows: this.rows } ) ).$control;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextAreaControl.prototype.setOptions	= function(options)
																								{
																								var opts = options || {};

																								if ('isRequired' in opts) { this.isRequired = opts.isRequired; }
																								if ('readOnly'   in opts) { this.readOnly		= opts.readOnly;   }
																								if ('cols'       in opts) { this.cols				= opts.cols;       }
																								if ('rows'       in opts) { this.rows				= opts.rows;       }

																								ControlBase.prototype.setOptions.call(this, opts);
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextAreaControl.prototype.setRequired = function(isReqd)
																								{
																								if (typeof isReqd != 'undefined') { this.isRequired = isReqd; }

																								this.$control[((this.isRequired) ? 'add' : 'remove') + 'Class']('required');

																								return this;
																								};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== TEXT BOX CONTROL ====
*/
		function TextboxControl(options)
			{
			this.cssName = 'ctrl-textbox';

			this.isRequired = false;
			this.readOnly		= false;
			this.size				= 50;

			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			TextboxControl.charSizes	= { date			: 12,
																		datetime	: 18,
																		datetimes	: 24,
																		period		: 23,
																		time			:  7,
																		times			: 13
																		};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxControl.maxChars		= { date			: 10,
																		datetime	: 16,
																		datetimes	: 22,
																		time			:  5,
																		times			: 11
																		};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxControl.prototype = new ControlBase();
			TextboxControl.prototype.constructor = TextboxControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxControl.prototype.attach				= function($ctrl, $ctrlVal)
																								{
																								if (this.onClick) { this.cssHover = 'block-hover'; }

																								ControlBase.prototype.attach.call(this, $ctrl, $ctrlVal || $ctrl);

																								if (this.readOnly)
																									{
																									this.$control.attr({ readonly: -1, tabindex: -1 });
																									}
																								else
																									{
																									switch (this.dataType)
																										{
																										case 'int'			: this.$control.numeric();
																																			break;

																										case 'currency'	: this.$control.numeric({ allow: '-.' }).
																																										bind('focus', function()
																																											{
																																											var vl = $(this).val().substr(1);
																																											$(this).val( (vl === '0.00') ? '' : vl );
																																											}).
																																										bind('blur' , { ctrl: this }, function(ev)
																																											{
																																											var vl = $(this).val();
																																											if ((vl == '') && ev.data.ctrl.isRequired) { vl = 0; }
																																											if (vl !== '') { $(this).val( '£' + parseFloat(vl).toFixed(2) ); }
																																											}).
																																										trigger('blur');
																																			break;

																										default					: if (this.numAllow) { this.$control.numeric({ allow: this.numAllow }); }
																										}

																									this.$control.bind('change keypress', { ctrl: this }, function(ev)
																										{
																										if (ev.type == 'change' || ev.which == 13) { ev.data.ctrl.setValue(this.value, 'onChange', ev); }
																										});
																									}

																								if (this.dataType != 'str') { this.$control.addClass(this.dataType); }
																								if (this.isRequired) 				{ this.$control.addClass('required'); }

																								return this;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxControl.prototype.create 			= function()
																								{
																								return this.attach( $('<input>').addClass(this.cssName).
																																					attr( { name			: this.name,
																																									type			: 'text',
																																									value			: this.value,
																																									size			: this.size,
																																									maxlength	: this.maxlength } ) ).$control;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxControl.prototype.setOptions		= function(options)
																								{
																								var opts = options || {};

																								this.dataType	= opts.dataType || 'str';

																								if ('isRequired' in opts) { this.isRequired = opts.isRequired; }
																								if ('maxlength'  in opts) { this.maxlength 	= opts.maxlength;  }
																								if ('numAllow'   in opts) { this.numAllow 	= opts.numAllow;   }
																								if ('readOnly'   in opts) { this.readOnly		= opts.readOnly;   }
																								if ('size'       in opts) { this.size				= opts.size;       }

																								ControlBase.prototype.setOptions.call(this, opts);
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxControl.prototype.setRequired 	= function(isReqd)
																								{
																								if (typeof isReqd != 'undefined') { this.isRequired = isReqd; }

																								this.$control[((this.isRequired) ? 'add' : 'remove') + 'Class']('required');

																								return this;
																								};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== TEXT BOX + ICON CONTROL ====
*/
		function TextboxIconControl(textboxOpts, iconOpts)
			{
			this.setOptions(textboxOpts, iconOpts);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			TextboxIconControl.prototype = new TextboxControl();
			TextboxIconControl.prototype.constructor = TextboxIconControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxIconControl.prototype.attach			= function($ctrl, $ctrlVal)
																									{
																									TextboxControl.prototype.attach.call(this, $ctrl, $ctrlVal);

																									if (this.iconControl)
																										{
																										this.iconControl.create();

																										if ($ctrl.parent()) { $ctrl.parent().append(this.iconControl.$control); }
																										}

																									return this;
																									};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxIconControl.prototype.create			= function()
																									{
																									TextboxControl.prototype.create.call(this);

																									if (this.iconControl) { return $([this.$control.get(0), this.iconControl.$control.get(0)]); }
																																	else	{ return this.$control; }
																									};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxIconControl.prototype.destroy		= function()
																									{
																									if (this.iconControl) { this.iconControl.destroy(); }

																									ControlBase.prototype.destroy.call(this);
																									};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxIconControl.prototype.disable		= function(state)
																									{
																									ControlBase.prototype.disable.call(this, state);

																									if (this.iconControl) { this.iconControl.disable(state); }

																									return this;
																									};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TextboxIconControl.prototype.setOptions	= function(textboxOpts, iconOpts)
																									{
																									TextboxControl.prototype.setOptions.call(this, textboxOpts);

																									if (iconOpts) { this.iconControl = new IconControl(iconOpts); }
																									};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== DATE/TIMES BOX CONTROL ====
*/
		function DatetimesboxControl(options)
			{
			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			DatetimesboxControl.prototype = new TextboxIconControl();
			DatetimesboxControl.prototype.constructor = DatetimesboxControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			DatetimesboxControl.prototype.attach			= function($ctrl)
																										{
																										TextboxIconControl.prototype.attach.call(this, $ctrl);
																										this.valDTs.toString(this.value);

																										return this;
																										};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			DatetimesboxControl.prototype.setOptions	= function(options)
																										{
																										var opts = options || {}, iconOpts;

																										this.valDTs = new Datetimes({ dataType: opts.dataType, value: opts.value });

																										opts.numAllow	 = this.valDTs.pattern;
																										opts.maxlength = TextboxControl.maxChars[opts.dataType];
																										opts.size			 = TextboxControl.charSizes[opts.dataType];

																										if ('popupDefault' in opts)
																											{
																											this.popupDefault = opts.popupDefault;
																											iconOpts =
																												{
																												cssIcon	: 'icon-date',
																												title		: 'Click to edit this ' + this.valDTs.dataText,
																												onClick	:
																													{
																													act	: function(data, ev)
																																	{
																																	new DatetimesPopup(
																																				{
																																				headText	: ((data.caption) ? 'Set the ' + data.caption : 'Select') + ' ' + data.valDTs.dataText,
																																				dataType	: data.valDTs.dataType,
																																				defaultVal: data.popupDefault,
																																				value			: data.value,
																																				target		: data.iconControl.$control,
																																				onConfirm	:
																																					{
																																					act	: function(data, ev) { data.setValue(this.content.value, 'onChange', ev); },
																																					data: data
																																					}
																																				} ).show( );
																																	},
																													data: this
																													}
																												};
																											}

																										TextboxIconControl.prototype.setOptions.call(this, opts, iconOpts);
																										};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			DatetimesboxControl.prototype.setValue		= function(value, eventName, ev)
																										{
																										return ControlBase.prototype.setValue.call(this, (value) ? this.valDTs.toString(value) : '', eventName, ev);
																										};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== DROP BOX CONTROL ====
*/
		function DropboxControl(options)
			{
			this.readOnly = true;

			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			DropboxControl.prototype = new TextboxIconControl();
			DropboxControl.prototype.constructor = DropboxControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			DropboxControl.prototype.attach			= function($ctrlTxt, $ctrlVal)
																							{
																							TextboxIconControl.prototype.attach.call(this, $ctrlTxt, $ctrlVal);
																							makeDroppable({ dropOn: this.$control, dropFrom: this.dropFrom, bindObj: this });

																							return this;
																							};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			DropboxControl.prototype.droppedOn	= function(opts) { this.setValue(opts.dropValue, opts.dropText); };
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			DropboxControl.prototype.setOptions	= function(options)
																							{
																							var opts = options || {}, iconOpts;

																							this.dropFrom = opts.dropFrom;

																							opts.title = 'Drag a ' + opts.dropFrom.toLowerCase().replace(',', ' or ') + ' onto this box';

																							if ('listName' in opts)
																								{
																								this.listName = opts.listName;
																								iconOpts =
																									{
																									cssIcon	: 'icon-list',
																									title		: 'Click to show the ' + this.listName + ' list',
																									onClick	: { act	: function(data) { dialogsManager.show(data); },
																															data: this.listName }
																									};
																								}

																							TextboxIconControl.prototype.setOptions.call(this, opts, iconOpts);
																							};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			DropboxControl.prototype.setValue		= function(value, txt, eventName, ev)
																							{
																							this.$control.val(txt);

																							return ControlBase.prototype.setValue.call(this, value, eventName, ev);
																							};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== PERIOD BOX CONTROL ====
*/
		function PeriodboxControl(options)
			{
			this.dataType	= 'period';
			this.readOnly = true;
			this.size			= TextboxControl.charSizes['period'];

			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			PeriodboxControl.prototype = new TextboxIconControl();
			PeriodboxControl.prototype.constructor = PeriodboxControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PeriodboxControl.prototype.attach			= function($ctrlTxt, $ctrlDate, $ctrlPeriod, $ctrlUnits)
																								{
																								if ($ctrlDate)
																									{
																									this.$ctrlDate   = $ctrlDate;
																									this.$ctrlPeriod = $ctrlPeriod;
																									this.$ctrlUnits  = $ctrlUnits;

																									this.valCP.setRange({ firstDate	: (new Date()).setShort($ctrlDate.val()),
																																				interval	: parseInt($ctrlPeriod.val(), 10),
																																				units			: $ctrlUnits.val() });
																									}

																								if ($ctrlTxt) { TextboxIconControl.prototype.attach.call(this, $ctrlTxt.val(this.valCP.toString())); }
																												 else { ControlBase.prototype.setValue.call(this, this.valCP.toString()); }

																								return this;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PeriodboxControl.prototype.destroy		= function()
																								{
																								delete this.$ctrlDate;
																								delete this.$ctrlPeriod;
																								delete this.$ctrlUnits;

																								ControlBase.prototype.destroy.call(this);
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PeriodboxControl.prototype.moveRange	= function(dir)
																								{
																								this.valCP.moveRange(dir);
																								this.setValue(null, 'onChange');
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PeriodboxControl.prototype.setOptions	= function(options)
																								{
																								var opts = options || {}, iconOpts;

																								this.valCP = new CalendarPeriod(opts.value);
																								opts.value = this.valCP.toString();

																								if (opts.usePopup)
																									{
																									var onClick	=
																										{
																										act	: function(data)
																														{
																														new PeriodPopup(
																																	{
																																	headText	: 'Select the period',
																																	value			: data.valCP,
																																	target		: data.$control,
																																	targetPos	: opts.targetPos  || 0,
																																	elementPos: opts.elementPos || 0,
																																	onConfirm	: { act	: function(data, ev) { data.setValue(this.content.value, 'onChange', ev); },
																																								data: data }
																																	}).show( );
																														},
																										data: this
																										};

																									if (opts.usePopupIcon)
																										{
																										iconOpts  = { cssIcon	: 'icon-date',
																																	title		: 'Click to select the ' + opts.caption,
																																	onClick	: onClick };
																										}
																									else { opts.onClick	= onClick; }
																									}

																								TextboxIconControl.prototype.setOptions.call(this, opts, iconOpts);
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PeriodboxControl.prototype.setValue		= function(value, eventName, ev)
																								{
																								if (value) { this.valCP.setRange(value); }

																								if (this.$ctrlDate)
																									{
																									this.$ctrlDate.val(  this.valCP.firstDate.toShort());
																									this.$ctrlPeriod.val(this.valCP.interval);
																									this.$ctrlUnits.val( this.valCP.units);
																									}

																								return ControlBase.prototype.setValue.call(this, this.valCP.toString(), eventName, ev);
																								};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== POPUP CONTROL ====
*/
		function PopupControl(options)
			{
			this.cssName		= 'ctrl-popup';
			this.autoCancel = true;

			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			PopupControl.prototype = new ControlBase();
			PopupControl.prototype.constructor = PopupControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PopupControl.prototype.close			= function(eventName, ev)
																						{
																						this.callEvent(eventName, ev);
																						this.callEvent('onClose', ev);
																						this.destroy();
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PopupControl.prototype.create			= function()
																						{
																						var $ctrl = $('<div/>').addClass(this.cssName);

																						if (this.headText)
																							{
																							var $head = $('<div/>').addClass('popup-head').
																																			append( $('<span/>').html(this.headText) ).
																																			append( this.iconCancel.create() );

																							if (this.iconConfirm) { $head.append(	this.iconConfirm.create() ); }

																							$ctrl.append($head);
																							}

																						this.$body = $('<div/>').addClass('popup-body').append(this.content.create());

																						this.$control = $('<div/>').addClass('popup-holder').
																																				append( $('<div/>').addClass('event-block')		 ,
																																								$('<div/>').addClass('popup-shadow-r') ,
																																								$('<div/>').addClass('popup-shadow-b') ,
																																								$('<div/>').addClass('popup-shadow-rs'),
																																								$('<div/>').addClass('popup-shadow-bs'), $ctrl.append(this.$body) );

																						return this;
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PopupControl.prototype.destroy		= function()
																						{
																						this.content.destroy();
																						this.$control.remove();
																						this.$control = this.$body = undefined;

																						if (this.autoCancel) { $(document).unbind('mousedown.' + this.eventID); }
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PopupControl.prototype.setOptions	= function(options)
																						{
																						var opts = options || {};

																						this.eventID = 'p' + parseInt(10000 * Math.random(), 10);

																						this.setEvents('preConfirm,onConfirm,onCancel,onClose,onOpen', opts);

																						if ('cssName'		 in opts) { this.cssName		= opts.cssName; 	}
																						if ('autoCancel' in opts) { this.autoCancel	= opts.autoCancel; 	}

																						if ('target'     in opts) { this.target			= opts.target;		}
																						if ('targetPos'  in opts) { this.targetPos	= opts.targetPos; }
																						if ('elementPos' in opts) { this.elementPos	= opts.elementPos; }

																						if ('headText'   in opts)
																							{
																							this.headText		= opts.headText;
																							this.iconCancel	= new IconControl({ title		: 'Click to cancel this action',
																																									cssIcon	: 'icon-cancel',
																																									content	: '&ucirc;',
																																									onClick	: { act	: function(data, ev) { data.close('onCancel', ev); },
																																															data: this }
																																									});
																							if (opts.showConfirm)
																								{
																								this.iconConfirm = new IconControl( { title		: 'Click to submit your input',
																																											cssIcon	: 'icon-confirm',
																																											content	: '&uuml;',
																																											onClick	: { act	: function(data, ev)
																																																					{
																																																					data.callEvent('preConfirm', ev);
																																																					data.close('onConfirm', ev);
																																																					},
																																																	data: this }
																																											} );
																								}
																							}

																						ControlBase.prototype.setOptions.call(this, opts);
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			PopupControl.prototype.show				= function(ev)
																						{
																						var pos = { targetPos: this.targetPos || 0, elementPos: this.elementPos || 0 };

																						if (this.target) { pos.target = this.target; }
																						else
																							{
																							pos.target = 'body';
																							pos.offX = ev.pageX;
																							pos.offY = ev.pageY;
																							}

																						if (!this.$control) { this.create(); }

																						this.$control.appendTo('body').
																													bind('contextmenu mousedown', function() { return false; }).
																													positionBy(pos).
																													show();

																						if (this.autoCancel)
																							{
																							$(document).bind('mousedown.' + this.eventID, { ctrl: this }, function(ev) { ev.data.ctrl.close('onCancel', ev); });
																							}

																						this.callEvent('onOpen', ev);

																						return this.$control;
																						};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== TABLE CELL CONTROL ====
*/
		function TableCellControl(options)
			{
			var opts = options || {};

			this.content = opts.content;
			this.cssName = opts.cssName;
			this.colSpan = opts.colSpan;
			this.rowSpan = opts.rowSpan;

			this.disabled = opts.disabled || false;
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			TableCellControl.prototype.cellIndex	= function() { return this.$control.get(0).cellIndex; };
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableCellControl.prototype.create			= function()
																								{
																								this.$control = $('<td/>').html(this.content);

																								if (this.cssName)		{ this.$control.addClass(this.cssName); }
																								if (this.colSpan)		{ this.$control.attr('colSpan', this.colSpan); }
																								if (this.rowSpan)		{ this.$control.attr('rowSpan', this.rowSpan); }
																								if (this.disabled)	{ this.$control.attr('denied' , true); }

																								return this.$control;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableCellControl.prototype.disable		= function(state)
																								{
																								this.disabled = state;
																								this.$control.attr('denied', state);

																								return this;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableCellControl.prototype.markClass	= function(mode, cssName)
																								{
																								var mark = Boolean(!this.disabled && !this.parentCell && this.$control);

																								if (mark)
																									{
																									this.$control[mode + 'Class'](cssName);

																									if (this.childCells)
																										{
																										for (var i = 0; i < this.childCells.length; i++) { this.childCells[i].$control[mode + 'Class'](cssName); }
																										}
																									}

																								return mark;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableCellControl.prototype.rowIndex		= function() { return this.$control.parent().get(0).rowIndex; };
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableCellControl.prototype.setContent	= function(content)
																								{
																								this.content = content;
																								if (this.$control) { this.$control.html(this.content); }

																								return this;
																								};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== TABLE ROW CONTROL ====
*/
		function TableRowControl(options)
			{
			var opts = options || {};

			this.cells	 = opts.cells || [];
			this.cssName = opts.cssName;
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			TableRowControl.prototype.appendCell	= function(cellOpts) { return this.cells.appendItem(new TableCellControl(cellOpts)); };
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableRowControl.prototype.appendCells	= function(cellOpts)
																								{
																								for (var i = 0; i < cellOpts.length; i++) { this.cells.push(new TableCellControl(cellOpts[i])); }
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableRowControl.prototype.create			= function()
																								{
																								var $row = $('<tr/>');

																								if (this.cssName)	{ $row.addClass(this.cssName); }

																								for (var i = 0; i < this.cells.length; i++) { $row.append(this.cells[i].create()); }

																								return $row;
																								};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableRowControl.prototype.markRange		= function(mode, cssName, firstCellI, finalCellI)
																								{
																								var marked = 0;

																								for (var c = firstCellI; c <= finalCellI; c++) { marked += this.cells[c].markClass(mode, cssName); }

																								return marked;
																								};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== TABLE BODY CONTROL ====
*/
		function TableBodyControl(options)
			{
			var opts = options || {};

			this.rows	= opts.rows || [];
			this.type = opts.type || 'body';

			this.cssCelHover = opts.cssCelHover || 'block-hover';

			this.setEvents('onClick,onHover,onMouseDown,onMouseUp', opts);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			TableBodyControl.prototype = new ControlBase();
			TableBodyControl.prototype.constructor = TableBodyControl;
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableBodyControl.prototype.appendRow	= function(rowOpts) { return this.rows.appendItem(new TableRowControl(rowOpts)); };
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableBodyControl.prototype.create			= function()
																								{
																								this.attach( $('<t' + this.type + '/>') );

																								for (var i = 0; i < this.rows.length; i++) { this.$control.append(this.rows[i].create()); }

																								if (this.cssCelHover)
																									{
																									this.$control.
																										bind('mousemove mousedown', { ctrl: this }, function(ev)
																											{
																											var ctrl = ev.data.ctrl,
																													cel  = ev.target,
																													celI = cel.cellIndex,
																													rowI = cel.parentNode.rowIndex,
																													overCell = ctrl.rows[rowI].cells[celI];

																											if (overCell.parentCell) { overCell = overCell.parentCell; }

																											if (overCell !== ctrl.overCell)
																												{
																												if (!ctrl.mouseDown)
																													{
																													ctrl.overCell && ctrl.overCell.markClass('remove', ctrl.cssCelHover);
																													overCell.markClass('add', ctrl.cssCelHover);
																													}

																												ctrl.overCell = overCell;
																												ctrl.disabled = overCell.disabled;

																												ctrl.callEvent('onHover', ev);
																												}

																											if (ev.type == 'mousedown')
																												{
																												$(document).one('mouseup', { ctrl: ctrl }, function(ev)
																													{
																													var ctrl = ev.data.ctrl;

																													ctrl.mouseDown = false;
																													ctrl.callEvent('onMouseUp', ev);
																													});

																												ctrl.mouseDown = true;
																												ctrl.overCell.markClass('remove', ctrl.cssCelHover);
																												ctrl.callEvent('onMouseDown', ev);
																												}
																											}).
																										bind('mouseleave', { ctrl: this }, function(ev)
																											{
																											var ctrl = ev.data.ctrl;

																											ctrl.overCell.markClass('remove', ctrl.cssCelHover);
																											ctrl.overCell = undefined;
																											});
																									}

																								return this.$control;
																								};
	// ________________________________________________________________________________________________________________________________________________


/* ================================================================================================================================================== TABLE CONTROL ====
*/
		function TableControl(options)
			{
			this.setOptions(options);
			}

	// ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
			TableControl.prototype.create			= function()
																						{
																						this.$control = $('<table/>').attr('title', '').append(this.body.create());

																						return this.$control;
																						};
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableControl.prototype.destroy		= function() { this.$control.remove(); this.$control = undefined; };
	// ------------------------------------------------------------------------------------------------------------------------------------------------
			TableControl.prototype.setOptions	= function(options)
																						{
																						var opts = options || {};

																						this.body	= new TableBodyControl(opts);
																						};
	// ________________________________________________________________________________________________________________________________________________


