/*****************************************************

  Copyright:	(c) 2006  SeaDesign Web Studio
        Web:	www.seadesign.ru
      Email: 	seadesign@gmail.com
  
*****************************************************/

/***********************************************************
*
* Prevents clearing of INPUTs and resetting FORMs after hitting ESC 
* for now this DOESN'T work in Firefox because Firefox process ESC hit BEFORE passing it to Javascript
*
***********************************************************/
function captureESC(e) 
{
	("undefined" == typeof(e)) ? the_key = event : the_key = e;
	if ("27" == the_key.keyCode) {
		the_key.returnValue = false;
		return false;
	}
	else {
		return true;
	}
}
document.onkeydown = captureESC;



if (!window.sea) {
	window.sea = new Object();
}

var 
	ftString		= 0,
	ftRaw			= 1,
	ftInteger	= 2,
	ftTime		= 3,
	ftFloat		= 4,
	ftDict      = 6;
	
	
//DON'T SET name ATTRIBUTES FOR CONTROLS (such as <input name=...) !!!!

window.sea.controls = new Array;


/***********************************************************
*
* Control base class
*
***********************************************************/
sea.Control = function() { this.name = ''; this.nullAvail = 1; }
sea.Control.prototype.create = function(name,val,nullAvail,readonly)
{
	this.name = name;
	window[this.name] = this;
	window.sea.controls.push(this);
	this.nullAvail = nullAvail;
	this.readonly = readonly;
	
	var obTbl = document.createElement('TABLE');
	obTbl.cellPadding = obTbl.cellSpacing = 0;
	obTbl.border = 0;
	obTbl.width = '100%';
	var row = obTbl.insertRow(0);
	var cell0 = row.insertCell(0);

	this.obParent = row.insertCell(1);
	this.obParent.width = '100%';
	return obTbl;
}

sea.Control.prototype.type = function()
{
	alert('Function type() is not defined in sea.Control');
}

sea.Control.prototype.value = function()		//return '' if isNull()==true
{
	return null;
}

sea.Control.prototype.isNull = function()
{
	return true;
}

sea.Control.prototype.isUserInputValid = function()
{
	return false;
}

sea.Control.prototype.setFocus = function()
{
}


/***********************************************************

	String Control
	
***********************************************************/
sea.StrControl = function(size) 
{ 
	this.ob = null; 
	this.size = size;
}
sea.StrControl.prototype = new sea.Control;

sea.StrControl.prototype.create = function(name,val,nullAvail,readonly)
{
	this.super_create = this.constructor.prototype.create;
	var ob = this.super_create(name,val,nullAvail,readonly);
	
	this.ob = document.createElement('INPUT');
	this.ob.type = "text";
	this.ob.value = val;
	this.ob.maxLength = this.size;
	this.ob.style.width = '100%';
	if (readonly == 1) {
		this.ob.readOnly = true;
		this.ob.style.backgroundColor = 'LightGrey';
	}
	this.obParent.appendChild( this.ob );
	return ob;
}

sea.StrControl.prototype.type = function()
{
	return ftString;
}

sea.StrControl.prototype.value = function()
{
	return this.ob.value;
}

sea.StrControl.prototype.isNull = function()
{
	return this.value()=='';
}

sea.StrControl.prototype.isUserInputValid = function()
{
	return this.nullAvail ? true : (this.ob.value != '');
}

sea.StrControl.prototype.setFocus = function()
{
	this.ob.focus();
}



/***********************************************************

	Integer Control
	
***********************************************************/
sea.IntControl = function(size) 
{ 
	this.ob = null; 
	this.size = size; 
	this.val = null;
}
sea.IntControl.prototype = new sea.Control;

sea.IntControl.prototype.create = function(name,val,nullAvail,readonly)
{
	this.super_create = this.constructor.prototype.create;
	var ob = this.super_create(name,val,nullAvail,readonly);
	
	this.obParent.innerHTML = "<input onblur='this.obCtl.on_change()'/>";
	this.ob = this.obParent.childNodes[0];
	this.ob.obCtl = this;
	this.ob.maxLength = this.size;
	this.ob.style.width = '100%';
	if (readonly == 1) {
		this.ob.readOnly = true;
		this.ob.style.backgroundColor = 'LightGrey';
	}
	
	this.val = parseInt(val);
	if (isNaN(this.val) && !this.nullAvail) {
		this.val = parseInt(0);
	}
	this.ob.value = isNaN(this.val) ? '' : this.val.valueOf();
	
	return ob;
}

sea.IntControl.prototype.type = function()
{
	return ftInteger;
}

sea.IntControl.prototype.value = function()
{
	return this.isNull() ? '' : this.val.valueOf();
}

sea.IntControl.prototype.isNull = function()
{
	return isNaN(this.val);
}

sea.IntControl.prototype.isUserInputValid = function()
{
	if (!this.nullAvail) {
		return (this.ob.value != '') && !isNaN(this.ob.value);
	}
	return !isNaN(this.ob.value);
}

sea.IntControl.prototype.on_change = function()
{
	this.val = parseInt(this.ob.value);
	this.ob.value = isNaN(this.val) ? '' : this.val.valueOf();
}

sea.IntControl.prototype.setFocus = function()
{
	this.ob.focus();
}


/***********************************************************
* Float Control
***********************************************************/
sea.FloatControl = function(prec, scale) 
{ 
	this.ob = null; 
	this.prec = prec;
	this.scale = scale;
	this.val = ''; 
}

sea.FloatControl.prototype = new sea.Control;
sea.FloatControl.prototype.create = function(name,val,nullAvail,readonly)
{
	this.super_create = this.constructor.prototype.create;
	var ob = this.super_create(name,val,nullAvail,readonly);

	this.obParent.innerHTML = "<input onblur='this.obCtl.on_change()'/>";
	this.ob = this.obParent.childNodes[0];
	this.ob.obCtl = this;
	this.ob.style.width = '100%';
	if (readonly == 1) {
		this.ob.readOnly = true;
		this.ob.style.backgroundColor = 'LightGrey';
	}
	
	if (val != '' && !isNaN(val)) 
	{
		this.ob.value = 
			this.val = 
				(new Number(val)).toFixed(this.scale);
	}
	else if (!this.nullAvail) 
	{
		this.ob.value = 
			this.val = 
				(new Number(0)).toFixed(this.scale);
	}
	
	return ob;
}

sea.FloatControl.prototype.type = function()
{
	return ftFloat;
}

sea.FloatControl.prototype.value = function()
{
	return this.val;
}

sea.FloatControl.prototype.isNull = function()
{
	return this.val == '';
}

sea.FloatControl.prototype.isUserInputValid = function()
{
	if (!this.nullAvail) {
		return (this.ob.value != '') && !isNaN(this.ob.value);
	}
	return !isNaN(this.ob.value);
}

sea.FloatControl.prototype.on_change = function()
{
	with (this) 
	{
		val = ob.value;
		if (val == '' || isNaN(val))
			val = ob.value = '';
		else
			val = ob.value = (new Number(val)).toFixed(scale);
	}
}

sea.FloatControl.prototype.setFocus = function()
{
	this.ob.focus();
}


/***********************************************************
* Raw Control
***********************************************************/
sea.RawControl = function(size) 
{ 
	this.ob = null; 
	this.size = size; 
}
sea.RawControl.prototype = new sea.Control;

sea.RawControl.prototype.create = function(name,val,nullAvail,readonly)
{
	this.super_create = this.constructor.prototype.create;
	var ob = this.super_create(name,val,nullAvail,readonly);
	
	this.ob = document.createElement('TEXTAREA');
	this.ob.value = val;
	this.ob.rows = 3;
	this.ob.cols = 60;
	this.ob.className = 'edcRaw';
	if( readonly == 1 ) {
		this.ob.readOnly = true;
		this.ob.style.backgroundColor = 'LightGrey';
	}
	this.obParent.appendChild( this.ob );
	return ob;
}

sea.RawControl.prototype.type = function()
{
	return ftRaw;
}

sea.RawControl.prototype.value = function()
{
	return this.ob.value;
}

sea.RawControl.prototype.isNull = function()
{
	return this.value()=='';
}

sea.RawControl.prototype.isUserInputValid = function()
{
	return this.nullAvail ? true : (this.ob.value != '');
}

sea.RawControl.prototype.setFocus = function()
{
	this.ob.focus();
}



/*
Key Event 	key code 				char code 
-------------------------------------------------------------------------
KeyDown 	set 					0(ignored) 

KeyPress 	if char code is set, key code is 	set if the 
		not set so key code is only set 	key typed represents a character 
		for input that doesn't map to a 	determined by nsIsPrintable(), 
		character, like "home" key or 		otherwise 0(ignored) 
		for dead key actions 

KeyUp 		set 					0(ignored) 

*/



/***********************************************************
*
* Date Time Control
* val in create() = MM/DD/YYYY HH:MI:SS
*
* DateControl types 
* 0 - datetime
* 1 - date
* 2 - time
***********************************************************/
function parseDate(date, fmt) {
	var d = new Date;
	var year = null, month = null, day = null;
	var posYear = fmt.search('yyyy');
	if (posYear >= 0) {
		d.setYear( date.substr(posYear, 4) );
	}
	var posMonth = fmt.search('MM');
	if (posMonth >= 0) {
		d.setMonth( date.substr(posMonth, 2)-1 );
	}
	var posDay = fmt.search('dd');
	if (posDay >= 0) {
		d.setDate( date.substr(posDay, 2) );
	}
	
	var posHour = fmt.search('HH');
	if (posHour >= 0) {
		d.setHours( date.substr(posHour, 2) );
	}
	var posMin = fmt.search('mm');
	if (posMin >= 0) {
		d.setMinutes( date.substr(posMin, 2) );
	}
	var posSec = fmt.search('ss');
	if (posSec >= 0) {
		d.setSeconds( date.substr(posSec, 2) );
	}		
	
	return d;
}


var dct_datetime = 0;
var dct_date = 1;
var dct_time = 2;

sea.DateControl = function(type) 
{ 
	this.ob = null; 
	this.date = new Date(); 
	this.fmt = MYSQL_DATETIME_FORMAT; 		//'d/M/yyyy HH:mm:ss';
	this.type = type || dct_datetime;
}

sea.DateControl.prototype = new sea.Control;
sea.DateControl.prototype.create = function(name,val,nullAvail,readonly)
{
	this.super_create = this.constructor.prototype.create;
	var ob = this.super_create(name,val,nullAvail,readonly);
	
	this.val = val ? new Date( Date.parse(val) ) : new Date;
	
	this.ob = document.createElement('TABLE');
	this.ob.className = 'dtc';
	var row = this.ob.insertRow(0);
	var cells = 0;

	if (this.nullAvail) {
		var txt = "<input type=checkbox style='margin-right:0.5em'";
		if( val ) txt += "checked ";
		txt += "onclick='this.obCtl.on_change_null(!this.checked);if(this.checked) this.obCtl.update()'/>";
		row.insertCell(cells).innerHTML = txt;
		this.obNull = this.ob.childNodes[0].childNodes[0].childNodes[cells++].childNodes[0];
		this.obNull.obCtl = this;
	}
	
	this.obDate = this.obMonth = this.obYear = this.obHour = this.obMin = this.obSec = null;
	
	if (this.type == dct_datetime || this.type == dct_date) {
		// date
		row.insertCell(cells).innerHTML 	= "<input size=2 maxlength=2 style='width:2em' onfocus='this.select()' onblur='this.obCtl.on_change_date()' onkeypress='return this.obCtl.on_key_press(event)' title='Date'/>";
		this.obDate = this.ob.childNodes[0].childNodes[0].childNodes[cells++].childNodes[0];
		this.obDate.obCtl = this;
		
		// .month
		row.insertCell(cells++).innerHTML 	= "<input class=dtce_delimiter value='.' size=1 disabled />";
		row.insertCell(cells).innerHTML 	= "<input size=2 maxlength=2 style='width:2em' onfocus='this.select()' onblur='this.obCtl.on_change_month()' onkeypress='return this.obCtl.on_key_press(event)' title='Month'/>";
		this.obMonth = this.ob.childNodes[0].childNodes[0].childNodes[cells++].childNodes[0];
		this.obMonth.obCtl = this;
		
		// .year
		row.insertCell(cells++).innerHTML 	= "<input class=dtce_delimiter value='.' disabled />";
		row.insertCell(cells).innerHTML 	= "<input size=4 maxlength=4 style='width:4em;' onfocus='this.select()' onblur='this.obCtl.on_change_year()' onkeypress='return this.obCtl.on_key_press(event)' title='Year'/>";
		this.obYear = this.ob.childNodes[0].childNodes[0].childNodes[cells++].childNodes[0];
		this.obYear.obCtl = this;
	}

	if (this.type == dct_datetime || this.type == dct_time) {
		// /hh
		row.insertCell(cells++).innerHTML 	= "<input class=dtce_delimiter value='/' disabled />";
		row.insertCell(cells).innerHTML 	= "<input size=2 maxlength=2 style='width:2em' onfocus='this.select()' onblur='this.obCtl.on_change_hour()' onkeypress='return this.obCtl.on_key_press(event)' title='Hours'/>";
		this.obHour = this.ob.childNodes[0].childNodes[0].childNodes[cells++].childNodes[0];
		this.obHour.obCtl = this;
		
		// :mm
		row.insertCell(cells++).innerHTML 	= "<input class=dtce_delimiter value=':' disabled />";
		row.insertCell(cells).innerHTML 	= "<input size=2 maxlength=2 style='width:2em' onfocus='this.select()' onblur='this.obCtl.on_change_min()' onkeypress='return this.obCtl.on_key_press(event)' title='Minutes'/>";
		this.obMin = this.ob.childNodes[0].childNodes[0].childNodes[cells++].childNodes[0];
		this.obMin.obCtl = this;
		
		// :ss
		row.insertCell(cells++).innerHTML 	= "<input class=dtce_delimiter value=':' disabled />";
		row.insertCell(cells).innerHTML 	= "<input size=2 maxlength=2 style='width:2em' onfocus='this.select()' onblur='this.obCtl.on_change_sec()' onkeypress='return this.obCtl.on_key_press(event)' title='Seconds'/>";
		this.obSec = this.ob.childNodes[0].childNodes[0].childNodes[cells++].childNodes[0];
		this.obSec.obCtl = this;
	}	
	
//	row.insertCell(cells++).innerHTML 	= "(dd.mm.yyyy/hh:mi:ss)";
	
	this.obParent.appendChild( this.ob );
	
	if (this.obNull) {
		this.obNull.disabled = readonly==1;
	}
		
	this.set_disabled( readonly==1 || (this.obNull && !val) );
	
	if (val || !this.obNull) {
		this.update();
	}
	
	return ob;
}

sea.DateControl.prototype.type = function()
{
	return ftTime;
}

sea.DateControl.prototype.setFocus = function()
{
	this.obDate.focus();
}

/*********************************************************************************
	d 		Day of month as digits with no leading zero for single-digit days
	dd 	Day of month as digits with leading zero for single-digit days
	M 		Month as digits with no leading zero for single-digit months
	MM 	Month as digits with leading zero for single-digit months
	yyyy 	Year represented by full four digits

	H 		Hours with no leading zero for single-digit hours; 24-hour clock
	HH 	Hours with leading zero for single-digit hours; 24-hour clock
	m 		Minutes with no leading zero for single-digit minutes
	mm 	Minutes with leading zero for single-digit minutes
	s 		Seconds with no leading zero for single-digit seconds
	ss 	Seconds with leading zero for single-digit seconds
*********************************************************************************/
//MYSQL_DATETIME_FORMAT = 'yyyy-M-d H:m:s';
MYSQL_DATETIME_FORMAT = 'yyyy-MM-dd HH:mm:ss';
MYSQL_DATE_FORMAT = 'yyyy-MM-dd';

sea.DateControl.prototype.setFormat = function(fmt)
{
	this.fmt = fmt;
}

sea.DateControl.prototype.value = function()
{
	if (this.obNull && !this.obNull.checked) 
	{
		return '';
	}
	
	with (this) 
	{
		var month = val.getMonth() + 1;
		
		var s = this.fmt;		
		s = s.replace(/dd/g, 	val.getDate()<10 ? ('0'+val.getDate()) : val.getDate());
		s = s.replace(/d/g, 		val.getDate());
		s = s.replace(/MM/g, 	month<10 ? ('0'+month) : month);
		s = s.replace(/M/g, 		month);
		s = s.replace(/yyyy/g, 	val.getFullYear());
		s = s.replace(/HH/g, 	val.getHours()<10 ? ('0'+val.getHours()) : val.getHours());
		s = s.replace(/H/g, 		val.getHours());
		s = s.replace(/mm/g, 	val.getMinutes()<10 ? ('0'+val.getMinutes()) : val.getMinutes());
		s = s.replace(/m/g, 		val.getMinutes());
		s = s.replace(/ss/g,		val.getSeconds()<10 ? ('0'+val.getSeconds()) : val.getSeconds());
		s = s.replace(/s/g, 		val.getSeconds());
		
		return s;
	}
}

sea.DateControl.prototype.isNull = function()
{
	if (this.obNull) {
		return !this.obNull.checked;
	}
	return false;
}

sea.DateControl.prototype.isUserInputValid = function()
{
	return true;
}

sea.DateControl.prototype.on_key_press = function(event)
{
	var code;
	if (window.event != null) {		//workaround for Mozilla,Firefox
		code = window.event.keyCode;
	}  
	else {
		code = event.charCode;
	}
	if (code) {
		if (String('0123456789').indexOf(String.fromCharCode(code)) == -1) {
			return false;
		}
	}
	return true;
}

sea.DateControl.prototype.set_disabled = function(bDisable)
{
	with (this) {
		this.ob.className = bDisable ? 'dtc_disabled' : 'dtc';
		
		if (obDate) {
			obDate.readOnly = bDisable;
		}
		if (obMonth) {
			obMonth.readOnly = bDisable;
		}
		if (obYear) {
			obYear.readOnly = bDisable;
		}
		if (obHour) {
			obHour.readOnly = bDisable;
		}
		if (obMin) {
			obMin.readOnly = bDisable;
		}
		if (obSec) {
			obSec.readOnly = bDisable;
		}
	}
}

sea.DateControl.prototype.update = function()
{
	with (this) {
		if (obDate) {
			obDate.value = val.getDate();
		}
		if (obMonth) {
			obMonth.value = val.getMonth()+1;
		}
		if (obYear) {
			obYear.value = val.getFullYear();
		}
		if (obHour) {
			obHour.value = val.getHours();
		}
		if (obMin) {
			obMin.value	= val.getMinutes();
		}
		if (obSec) {
			obSec.value	= val.getSeconds();
		}
	}
}

sea.DateControl.prototype.on_change_null = function(bNull)
{
	with( this ) {
		if( bNull )
			obDate.value = obMonth.value = obYear.value = obHour.value =
				obMin.value = obSec.value = '';
		set_disabled(bNull);
	}
}

sea.DateControl.prototype.on_change_date = function()
{
	if( this.obDate.readOnly )
		return;
	if( !isNaN(this.obDate.value) )
		this.val.setDate(this.obDate.value);
	this.update();
}

sea.DateControl.prototype.on_change_month = function()
{
	if( this.obMonth.readOnly )
		return;
	if( !isNaN(this.obMonth.value) ) {
		if( this.obMonth.value == 0 )
			this.obMonth.value = 1;
		this.val.setMonth(this.obMonth.value-1);
	}
	this.update();
}

sea.DateControl.prototype.on_change_year = function()
{
	if( this.obYear.readOnly )
		return;
	if( !isNaN(this.obYear.value) )
		this.val.setYear(this.obYear.value);
	this.update();
}

sea.DateControl.prototype.on_change_hour = function()
{
	if( this.obHour.readOnly )
		return;
	if( !isNaN(this.obHour.value) )
		this.val.setHours(this.obHour.value);
	this.update();
}

sea.DateControl.prototype.on_change_min = function()
{
	if( this.obMin.readOnly )
		return;
	if( !isNaN(this.obMin.value) )
		this.val.setMinutes(this.obMin.value);
	this.update();
}

sea.DateControl.prototype.on_change_sec = function()
{
	if( this.obSec.readOnly )
		return;
	if( !isNaN(this.obSec.value) )
		this.val.setSeconds(this.obSec.value);
	this.update();
}



/***********************************************************

	SelectOption Control
	
***********************************************************/
sea.SelectOption = function() 
{ 
	this.ob = null;
	this.val = null;
}
sea.SelectOption.prototype = new sea.Control;

sea.SelectOption.prototype.create = function(name, val, nullAvail, readonly)
{
	this.super_create = this.constructor.prototype.create;
	var ob = this.super_create(name,val,nullAvail,readonly);
	
	this.val = val;
	this.ob = document.createElement('SELECT');
	this.ob.size = 1;
	this.ob.style.width = '100%';
	if (readonly == 1) {
		this.ob.disabled = true;
		this.ob.style.backgroundColor = 'LightGrey';
	}
	this.obParent.appendChild(this.ob);
	
	if (this.nullAvail) {
		this.addOption('',null);
	}
	
	return ob;
}

sea.SelectOption.prototype.addOption = function(text, value)
{
	this.ob.options[this.ob.options.length] = new Option(text, value);
	if (value == this.val) {
		this.ob.options[this.ob.options.length-1].selected = true;
	}
}

sea.SelectOption.prototype.type = function()
{
	return ftDict;
}

sea.SelectOption.prototype.value = function()
{
	return this.ob.options[this.ob.selectedIndex].value;
}

sea.SelectOption.prototype.isNull = function()
{
	return this.nullAvail ?
		(this.ob.selectedIndex == 0) : 
		(this.ob.selectedIndex < 0);
}

sea.SelectOption.prototype.isUserInputValid = function()
{
	return (this.ob.selectedIndex >= 0);
}

sea.SelectOption.prototype.setFocus = function()
{
	this.ob.focus();
}



function create_control(
	fieldType,
	name,			//later this control will be reachable through window.name or window['name']
	val,
	prec,			//=length for String,Raw,Integer   =type for Time
	scale,
	bNullAvail,
	bReadOnly)
{
	var ob, nt = new Number(fieldType);
	switch (nt.valueOf()) 
	{
		case ftInteger:	
			ob = new sea.IntControl(prec);
			break;
		case ftFloat:
			ob = new sea.FloatControl(prec,scale);
			break;
		case ftRaw: 	
			ob = new sea.RawControl(prec);	
			break;
		case ftTime:	
			ob = new sea.DateControl(prec);	
			break;
		case ftDict:
			ob = new sea.SelectOption;
			break;
		case ftString:	
		default:
			ob = new sea.StrControl(prec);
			break;
	}
	return ob.create(name, val, bNullAvail, bReadOnly);
}


function validateControlsInput(errMsg/*=null*/)
{
	for (var i=0; i<window.sea.controls.length; ++i) 
	{
		if (!window.sea.controls[i].isUserInputValid()) {
			if (errMsg) {
				alert(errMsg);
			}
			window.sea.controls[i].setFocus();
			return false;
		}
	}
	return true;
}

function addCtlValuesAsInputsOf(oForm)
{
	for (var i=0; i<window.sea.controls.length; ++i) 
	{
		var oInput = document.createElement('INPUT');
		oInput.type = 'hidden';
		oInput.name = window.sea.controls[i].name;
		oInput.value = window.sea.controls[i].value();
		oForm.appendChild(oInput);	
	}
}


function showHelp(catName, fName) 
{
	window.open(
		'help.php?catName='+catName+'&fName='+fName,
		'_blank',
		'location=no,menubar=no,toolbar=no,resizable=yes,scrollbars=yes,status=no'
	);
}

function setHint4Input(oInputCtl, hintMsg, color/*=gray*/)
{
	oInputCtl.origColor = oInputCtl.style.color;
	
	if (!oInputCtl.value)
	{
		oInputCtl.value = hintMsg;
		oInputCtl.style.color = color ? color : 'gray';
	}
	

	oInputCtl.onclick = function() 
	{ 
		oInputCtl.style.color = oInputCtl.origColor;
		if (oInputCtl.value==hintMsg)
		{
			oInputCtl.value = '';
		}
	}
	
	oInputCtl.onblur = function() 
	{
		if (!oInputCtl.value)
		{
			oInputCtl.value = hintMsg;
			oInputCtl.style.color = color ? color : 'gray';
		}
	}
}

