/* ------------------------------------------------------------------------------------------------------------ */

InputTemplate = function( data ) {
	InputTemplate.superClass.apply( this, arguments );

	this.input = this.getEl( data['id'] );
	if( !this.input ) return false;

	this.template = data['params']['reg'] || /.*/;
	this.delimiter = data['params']['delimiter'] || /\./;
	this.mask = data['params']['mask'] || this.input.value;
	this.length = this.mask.length || 10;

	this.addHandler( this.input, 'keypress', this.onKeyPress );
	this.addHandler( this.input, 'keydown', this.onKeyDown );
}
InputTemplate.inheritsFrom( Glyph );

InputTemplate.prototype.setValue = function( val ) {
	this.input.value = val;
}

/* ------------------------------------------------------------------------------------------------------------ */

InputTemplate.prototype.onKeyDown = function( params, ev ) {
	var ev = ev || window.event;
	var code = ev.charCode || ev.keyCode;
	if( ev.ctrlKey || ev.altKey ) return true;
	var sel = this.getSelectionStart();

	if ( code == 35 || code == 36 || code == 37 || code == 39 || code == 9 || code == 13 ) return true;
	if( 
		!( ( code >= 48 && code <= 57 ) || ( code >= 96 && code <= 105 ) ) ||
		code == 8
	) {
		this.preventDefault( ev );
	}

	if( code == 8 && !this.bs && 'v' == '\v' ) {		// 8 - удалить предыдущий символ
		this.bs = true;
		this.onKeyPress( false, { charCode: 8 } );
	};
}

/* ----------------------------------------------------------------------- */

InputTemplate.prototype.onKeyPress = function( params, ev ) {
	var ev = ev || window.event;
	var code = ev.charCode || ev.keyCode;
	var cVal = this.input.value;
	if ( ev.ctrlKey || ev.altKey ) return true;
	if ( code == 27 ) {
		this.input.blur();
		return false;
	}
	if ( code == 13 ) {
		this.input.blur();
		return true;
	}

	if ( code < 32 && code != 8 ) return true;
	if ( code == 35 || code == 36 || code == 37 || code == 39 || code == 9 ) return true;

	if( ( code >= 48 && code <= 57 ) || ( code >= 96 && code <= 105 ) ) {
		var sel = this.getSelectionStart();

		if( this.delimiter.test( cVal.substr( sel, 1 ) ) )
			this.moveCaretTo( sel++ );

		var key = String.fromCharCode( ( ( code < 96 ) ? code : ( code - 48 ) ) );
		nVal = ( ( sel > 0 ) ? cVal.substring( 0, sel ) : '' ) + key.toString() + cVal.substring( sel + 1, cVal.length );
		if( !this.template.test( nVal ) || nVal.length > this.length ) {
			this.preventDefault( ev );
			return false;
		}

		sel++;
		
		if( this.delimiter.test( cVal.substr( sel, 1 ) ) )
			sel++;
	}

	if( code == 8 ) {
		var sel = this.getSelectionStart();
		
		if( this.delimiter.test( cVal.substr( --sel, 1 ) ) ) {
			this.moveCaretTo( sel-- );
		}
		var key = this.mask.substr( sel, 1 );
		nVal = ( ( sel > 0 ) ? cVal.substring( 0, sel ) : '' ) + key.toString() + cVal.substring( sel + 1, cVal.length );

		var self = this;
		window.setTimeout( function() { self.bs = false }, 50 );
		var test = 'a';
	}
	if( nVal.length == this.length ) {
		this.setValue( nVal + '' );
		this.moveCaretTo( sel );
	}
	
	this.preventDefault( ev );
}

InputTemplate.prototype.moveCaretTo = function( position ) {
	if( this.input.setSelectionRange ) {
		this.input.setSelectionRange( position, position );
	} else {
		var rng = this.input.createTextRange();
		rng.collapse( true );
		rng.move( 'character', position );
		rng.select();
	}
}

InputTemplate.prototype.getSelectionStart = function() {
	if( this.input.selectionStart ) return this.input.selectionStart;
	else if ( document.selection && 'v' == '\v' ) {
		var sel = document.selection.createRange();
		var clone = this.input.createTextRange();
		clone.setEndPoint( 'EndToStart', sel );
		return clone.text.length;
	}
	return 0;
}

/* ----------------------------------------------------------------------- */

InputTemplate.prototype.getSelectionEnd = function() {
	if( this.input.selectionEnd ) return this.input.selectionEnd;
	else if ( document.selection && 'v' == '\v' ) {
		var sel = document.selection.createRange();
		var clone = this.input.createTextRange();
		clone.setEndPoint( 'EndToEnd', sel );
		return clone.text.length;
	}
	return 0;
}


/*************/

InputCalendar = function( data ) {
	InputCalendar.superClass.apply( this, arguments );
	if( !this.input ) return false;

	this.tplShow = data['params']['tplShow'] || 'dd.mm.yyyy';
	this.input.tpl = data['params']['tplInput'] || 'dd.mm.yyyy';
	this.tplHidden = data['params']['tplHidden'] || 'yyyy-mm-dd';
	this.input.hideCalendar = false;
	this.dateStart = data['params']['date_start'];
	this.dateEnd = data['params']['date_end'];
	
	if( data['params']['date'] && data['params']['date'] instanceof Date ) {
		this.dateCurrent = data['params']['date'];
		this.input.value = Calendar.dateFormat( this.dateCurrent, this.tplHidden );
	}
	else if( this.input.value ) 
		this.dateCurrent = Calendar.dateFormat( this.input.value, this.tplHidden );
	else {
		this.dateCurrent = new Date();
		if( !data['params']['date'] )
		    this.input.value = Calendar.dateFormat( this.dateCurrent, this.tplHidden );
	}

	//create visible element
	this.visible = this.createNode( 'input', false, { 'class' : this.input.className + ' calInput' } );
	var inputStyle = this.input.getAttribute( 'style' );
	if( inputStyle ) {
		if( typeof inputStyle  == 'object' ) 
			this.visible.style.cssText = inputStyle.cssText;
		else 
			this.visible.setAttribute('style', inputStyle );
	}
	this.input.parentNode.insertBefore( this.visible, this.input );
	this.input.style.display = 'none';
	
	this.CheckDate();
	if( data['params']['date'] ) {
		if( data['params']['date'] instanceof Date )
			this.visible.value = Calendar.dateFormat( this.dateCurrent, this.tplShow );
		else
			this.visible.value = data['params']['date'];
	}
	else 
		this.visible.value = Calendar.dateFormat( this.dateCurrent, this.tplShow );
	
	this.cal = new Calendar( this.input, this.dateCurrent, this.dateStart, this.dateEnd );

	this.addHandler( this.visible, 'focus', this.FocusElement );
	this.addHandler( this.input, 'blur', this.BlurInput );	
	this.addHandler( this.input, 'change', this.ChangeDate );
}
InputCalendar.inheritsFrom( InputTemplate );

InputCalendar.prototype.CheckDate = function() {
	if( this.dateStart && ( this.dateStart.valueOf() > this.dateCurrent.valueOf() ) )
	    this.dateCurrent = this.dateStart;
	if( this.dateEnd && ( this.dateEnd.valueOf() < this.dateCurrent.valueOf() ) )
	    this.dateCurrent = this.dateEnd;

    if( isNaN( this.dateCurrent ) && this.dateEnd )
        this.dateCurrent = this.dateEnd;
}

InputCalendar.prototype.FocusElement = function() {
	this.input.value = Calendar.dateFormat( this.dateCurrent, this.input.tpl );
	this.cal.show();

	this.input.style.display = 'inline';
	this.visible.style.display = 'none';
	this.input.focus();
	this.moveCaretTo(0);
}

InputCalendar.prototype.BlurInput = function() {
    var date = Calendar.dateFormat( this.input.value, this.input.tpl );
    if( !isNaN( date ) )
        this.dateCurrent = date 
	this.CheckDate();
	this.visible.value = Calendar.dateFormat( this.dateCurrent, this.tplShow );
	this.input.value = Calendar.dateFormat( this.dateCurrent, this.tplHidden );
	//

	this.input.style.display = 'none';
	if( this.visible ) this.visible.style.display = 'inline';
	//this.input.value = Calendar.dateFormat( this.dateCurrent, this.tplHidden );

	if( this.input.hideCalendar ) {
		this.cal.hide();
		this.input.hideCalendar = false;
	}
}

InputCalendar.prototype.ChangeDate = function() {
	var date = this.cal.selectedDate;
	if( date && ( date instanceof Date ) ) {
		this.dateCurrent = date;
		this.CheckDate();
		//this.setContent( dateFormat( this.dateCurrent, this.tplShow ), this.visible );
		this.visible.value = Calendar.dateFormat( this.dateCurrent, this.tplShow );
		this.input.value = Calendar.dateFormat( this.dateCurrent, this.tplHidden );
	}
}

/*************/

/*$( function() {
	new InputCalendar({
		id : 'test', 
		params : {
			reg : /([0-3][0-9])\.([01][0-9])\.([0-9])/, 
			tplShow : 'dd M yyyy',
			tplInput : 'dd.mm.yyyy',
			delimiter : /\./, 
			mask: '00.00.0000'
		}
	});
});*/
