var MyDateInputClass = Class.create();

//defining the rest of the class implmentation
MyDateInputClass.prototype = {

   initialize: function(id, n) {
   		this.dateCtrl = $(id);
   		this.n = n;
   		if (this.dateCtrl.onblur)
   			this.oldOnblur = this.dateCtrl.onblur.bindAsEventListener(this);
   		if (this.dateCtrl.onfocus)
   			this.oldOnfocus = this.dateCtrl.onfocus.bindAsEventListener(this);
   		if (this.dateCtrl.onkeypress)
   			this.oldOnkeypress = this.dateCtrl.onkeypress.bindAsEventListener(this);
   		if (this.dateCtrl.onkeydown)
   			this.oldOnkeydown = this.dateCtrl.onkeydown.bindAsEventListener(this);
   		if (this.dateCtrl.onkeyup)
   			this.oldOnkeyup = this.dateCtrl.onkeyup.bindAsEventListener(this);
   		if (this.dateCtrl.onclick)
   			this.oldOnclick = this.dateCtrl.onclick.bindAsEventListener(this);
		//assigning our method to the event
		this.dateCtrl.onkeypress = this.DATEEDT_onkeypress.bindAsEventListener(this);
		this.dateCtrl.onkeydown = this.DATEEDT_onkeydown.bindAsEventListener(this);
		this.dateCtrl.onkeyup = this.DATEEDT_onkeyup.bindAsEventListener(this);
		this.dateCtrl.onblur = this.DATEEDT_onblur.bindAsEventListener(this);
		this.dateCtrl.onfocus = this.DATEEDT_onfocus.bindAsEventListener(this);
		this.dateCtrl.onclick = this.DATEEDT_onclick.bindAsEventListener(this);
   },

	DATEEDT_onblur:function (event)
	{
		
	  if(this.oldOnblur)		  
	   this.oldOnblur(event);
	  if (event.target)  
		  var oCtl = event.target;
		else
		  var oCtl = event.srcElement;
	  
		if (!DATEEDT_isDate(oCtl))
			oCtl.value = "";
	
		if(	oCtl.invalue != oCtl.value)
			if(oCtl.onchange != null)
				oCtl.onchange();
				
		oCtl.mnPos = getSelectionStart(oCtl);
	},

	DATEEDT_onclick: function (event)
	{
	  if(this.oldOnclick)
	  this.oldOnclick(event);
	  if (event.target)  
		  var oCtl = event.target;
		else
		  var oCtl = event.srcElement;
	  
		if (oCtl.value == "" || oCtl.value ==DATEEDT_mDef || oCtl.value ==DATEEDT_mDef3 )
			setSelectionStart(0, oCtl);	
	},
	
	
	DATEEDT_onfocus: function (event)
	{
	  if(this.oldOnfocus)
	  this.oldOnfocus(event);
	  if (event.target) 
		  var oCtl = event.target;
		else
		  var oCtl = event.srcElement;
	
		formato = this.n;
		oCtl.invalue = oCtl.value;
		if (oCtl.value == "" && formato == 3)
			textSetValue(DATEEDT_mDef3,oCtl);
		else if (oCtl.value == "")
			textSetValue(DATEEDT_mDef,oCtl);
		oCtl.msOld = oCtl.value;
		setSelectionStart(0,oCtl);
	},
	
	DATEEDT_onkeydown: function (event)
	{
	  if (this.oldkeydown)
	  this.oldkeydown(event);
	  if (event.target)  
		  var oCtl = event.target;
		else
		  var oCtl = event.srcElement;
	
		var nDst, oSel, nSel, sTxt;
		
		//Switch MSIE vs NS7/Mozilla
		if (event.target) {
		  var nKey = event.which;
	  }
	  else {	  
		  var nKey = event.keyCode;
	  }	  
	  
		oCtl.mbRet = true;
		oCtl.mbFmt = false;
	
		sTxt = oCtl.value;
		oSel = getSelectionStartLength(oCtl);
		nSel = oSel.start;
		
		switch (nKey)
		{
		case 0x08: // Backspace
			if(oSel.bSelected){
			  if (formato == 3)
				  oCtl.value = sTxt.substr(0, nSel) + DATEEDT_mDef3.substr(nSel,oSel.length) + sTxt.substr(nSel + oSel.length);
				else
				  oCtl.value = sTxt.substr(0, nSel) + DATEEDT_mDef.substr(nSel,oSel.length) + sTxt.substr(nSel + oSel.length);  
				setSelectionStart(nSel,oCtl);
				oCtl.mbRet = false;
			} else {
				if(nSel != 0) {
				  if (formato == 3)
	    			oCtl.value = sTxt.substr(0, nSel-1) + DATEEDT_mDef3.substr(nSel-1,oSel.length) + sTxt.substr(nSel);
	    		else 
	    		  oCtl.value = sTxt.substr(0, nSel-1) + DATEEDT_mDef.substr(nSel-1,oSel.length) + sTxt.substr(nSel);
	    		setSelectionStart(nSel-1, oCtl);
				}		
				oCtl.mbRet = false;
				
			}	
			break;
		case 0x2E: // CANC
		  if (formato == 3) {
	  		oCtl.value = sTxt.substr(0, nSel) + DATEEDT_mDef3.substr(nSel,oSel.length) + sTxt.substr(nSel + oSel.length);
	  	} else {
			  oCtl.value = sTxt.substr(0, nSel) + DATEEDT_mDef.substr(nSel,oSel.length) + sTxt.substr(nSel + oSel.length);
	  	}
			setSelectionStart(nSel,oCtl,0);
			oCtl.mbRet = false;
			break;
	 	case 0x0D: // return
	 	  //Switch MSIE vs NS7/Mozilla
	    if (oCtl.setSelectionRange) {
		    if (event.cancelable) event.preventDefault();
	       event.stopPropagation();	  	
	    }
	    else {
	   	  window.event.returnValue=false
	    }
	   	return false;
			
		}
		//Switch MSIE vs NS7/Mozilla
	  if (oCtl.setSelectionRange) {
	    if (!oCtl.mbRet)
	       if (event.cancelable) event.preventDefault();       
	    event.returnValue = oCtl.mbRet;                       
	    event.stopPropagation();
	  	return oCtl.mbRet;	  
	  } else {	
	  	if (!oCtl.mbRet)
	  		event.keyCode = 0;
	  	event.cancelBubble = true;
	  	event.returnValue = oCtl.mbRet;
	  	return oCtl.mbRet;
	  }  	
	
	},

	DATEEDT_onkeypress: function (event)
	{
	  if (this.oldOnkeypress)
	  this.oldOnkeypress(event);
	  if (event.target)  
		  var oCtl = event.target;
		else
		  var oCtl = event.srcElement;
	
		var nDst, nSel, sTxt;
	  //Switch MSIE vs NS7/Mozilla	
		if (event.target) {
		  var nKey = event.which;
		  if (nKey == 0) nKey = event.keyCode; //Perchè in alcuni casi (tab) non è valorizzato
	  }
	  else {	  
		  var nKey = event.keyCode;	  
	  }	        
	
		var sChr, sCh0, bFnd;
		switch (nKey)
		{
		case 0x08:
			if(oCtl.value == "" && formato == 3) // needed because when cursor is in 0 position IE setting value property to blank string
				oCtl.value = DATEEDT_mDef3;
			else if (oCtl.value == "")
				oCtl.value = DATEEDT_mDef;
	    //sposto su		event.keyCode = 0;
	    //Switch MSIE vs NS7/Mozilla
	    if (oCtl.setSelectionRange) {
	      if (event.cancelable) event.preventDefault();
	      event.stopPropagation();
	    } else {	
	  		event.cancelBubble = true;
	  		event.returnValue = false;
	  		event.keyCode = 0;
	  	}
	
			break;
	// sblocco il TAB	NS7/Mozilla	
		case 0x09:
		  return true;
		case 0x0D:
		  break;	  
		case 0x1B:
			oCtl.value = oCtl.msOld;
			setSelectionStart(0,oCtl);
			break;
	// sblocco freccette HOME FINE NS7/Mozilla	
		case 0x23:	
		case 0x24:	
		case 0x25:	
		case 0x26:	
		case 0x27:	
		case 0x28:
		  return true;	
		case 0x30:
		case 0x31:
		case 0x32:
		case 0x33:
		case 0x34:
		case 0x35:
		case 0x36:
		case 0x37:
		case 0x38:
		case 0x39:
			sTxt = oCtl.value;
			nSel = getSelectionStart(oCtl);
			var maxlen, maxday, minday, maxmounth, minmounth, maxyear, minyear, firstsep, secondsep;
			if (formato == 3)
			{
			  maxlen = 7;
			  maxday = 0;
			  minday = 0;
			  maxmounth = 2;
			  minmounth = 0;
			  maxyear = 7;
			  minyear = 3;
			  firstsep = 2;
			  secondsep = 2;
			}
			else if (formato == 2)
			{
			  maxlen = 10;
			  maxday = 5;
			  minday = 3;
			  maxmounth = 2;
			  minmounth = 0;
			  maxyear = 10;
			  minyear = 6;
			  firstsep = 2;
			  secondsep = 5;
			}
			else
			{
			  maxlen = 10;
			  maxday = 2;
			  minday = 0;
			  maxmounth = 5;
			  minmounth = 3;
			  maxyear = 10;
			  minyear = 6;
			  firstsep = 2;
			  secondsep = 5;
			}
			if (nSel < maxlen)
			{
				sChr = String.fromCharCode(nKey);
				bFnd = false;
				if (nSel >= minday && nSel < maxday)
				{
					// inside day
					if (nSel == minday && nKey > 0x33)
					{
						// can't be first of a 2 digits day
						if (minday == 0)
	  					sTxt = "0" + sChr + sTxt.substr(maxday);
	  				else
	  					sTxt = sTxt.substr(0,minday) + "0" + sChr + sTxt.substr(maxday);	  					  					
						oCtl.value = sTxt;
						sTxt = oCtl.value;					
						nSel = maxday + 1;
						bFnd = true;
					}
					else if (nSel == minday + 1)
					{
						sCh0 = sTxt.charAt(minday);
						if (parseInt(sCh0 + sChr,10) > 31)
						{
							// day can' be > 31
	    				if (minday == 0)
	    					sTxt = "0" + sChr + sTxt.substr(maxday);
	    				else
	  						sTxt = sTxt.substr(0,minday) + "0" + sChr + sTxt.substr(maxday);
							oCtl.value = sTxt;
							sTxt = oCtl.value;
							nSel = maxday + 1;
							bFnd = true;
						}
					}
				}
				else if (nSel >= minmounth && nSel < maxmounth)
				{
					// inside month
					if (nSel < minmounth + 1 && nKey > 0x31)
					{
						// can't be first of a 2 digits month
						sTxt = sTxt.substr(0, minmounth) + "0" + sChr + sTxt.substr(maxmounth);
						oCtl.value = sTxt;
						sTxt = oCtl.value;					
						nSel = maxmounth + 1;
						bFnd = true;
					}
					else if (nSel == minmounth + 1)
					{
						sCh0 = sTxt.charAt(minmounth);
						if (parseInt(sCh0 + sChr,10) > 12)
						{
							// day can' be > 31
							sTxt = sTxt.substr(0, minmounth) + "0" + sChr + sTxt.substr(maxmounth);
							oCtl.value = sTxt;
							sTxt = oCtl.value;						
							nSel = minmounth;
							bFnd = true;
						}
					}
					else if( nSel == firstsep || nSel == secondsep) // is /
					  ++nSel;
		
				}
				else if (nSel >= minyear && nSel < maxyear - 3)
				{
					// inside year
					if (nSel >= minyear && (nKey > 0x32 || nKey == 0x30))
					{
						// can't be first of a 4 digits year
						if (nKey >= 0x35)
							sTxt = sTxt.substr(0, minyear) + "19" + sChr + sTxt.substr(maxyear);
						else
							sTxt = sTxt.substr(0, minyear) + "20" + sChr + sTxt.substr(maxyear);
						oCtl.value = sTxt;
						sTxt = oCtl.value;					
						nSel = maxyear;
						bFnd = true;
					}
				  else if( nSel == firstsep || nSel == secondsep) // is /
					  ++nSel;
					
				}
				else if (nSel == minyear + 1)
				{
					var nTmp = parseInt(sTxt.substr(minyear, 1) + sChr,10);
					if (nTmp > 20)
					{
						// can't be first two digits of a 4 digits year
						if (nTmp >= 50)
							sTxt = sTxt.substr(0, minyear) + "19" + sTxt.substr(minyear, 1) + sChr;
						else
							sTxt = sTxt.substr(0, minyear) + "20" + sTxt.substr(minyear, 1) + sChr;												
						oCtl.value = sTxt;
						sTxt = oCtl.value;
						nSel = maxyear;
						bFnd = true;
					}
				}
				if (!bFnd)
				{
					nDst = sTxt.length - nSel;
					sTxt = sTxt.substr(0, nSel) + sChr + sTxt.substr(nSel + 1);
					oCtl.value = sTxt;
					sTxt = oCtl.value;								
					nSel = sTxt.length - nDst + 1;
					if (sTxt.charAt(nSel) == "/")
						++nSel;
				}
				setSelectionStart(nSel < 0 ? 0 : nSel, oCtl);
			}
			
			//Switch MSIE vs NS7/Mozilla
	    if (oCtl.setSelectionRange) {
	      if (event.cancelable) event.preventDefault();
	      event.stopPropagation();
	    } else {
	  		event.returnValue = false;
	  	}
	  	
			break;
		case 0x2D:
		case 0x2F:
			sTxt = oCtl.value;
			nSel = getSelectionStart(oCtl);
			if (nSel < firstsep)
			{
				nSel = firstsep;
				bFnd = true;
			}
			else if (nSel < secondsep)
			{
				nSel = secondsep;
				bFnd = true;
			}
			if (bFnd)
				setSelectionStart(nSel < 0 ? 0 : nSel, oCtl);
				
			//Switch MSIE vs NS7/Mozilla	
	    if (oCtl.setSelectionRange) {
	      if (event.cancelable) event.preventDefault();
	      event.stopPropagation();
	    } else {
	  		event.returnValue = false;
	  	}
			break;
		default:
		  //Switch MSIE vs NS7/Mozilla
	    if (oCtl.setSelectionRange) {
	      if (event.cancelable) event.preventDefault();
	      //event.stopPropagation();
	    } else {
	  		event.returnValue = false;
	  	}
			break;
		}
	},


	DATEEDT_onkeyup: function (event)
	{	  
	  if (this.oldOnkeyup)
	  this.oldOnkeyup(event);
	  if (event.target) 
		  var oCtl = event.target;
		else
		  var oCtl = event.srcElement;
	
	  //Switch MSIE vs NS7/Mozilla
	  if (oCtl.setSelectionRange) {
	    if (!oCtl.mbRet)
	       if (event.cancelable) event.preventDefault();
	       
	       event.returnValue = oCtl.mbRet;                       
	       event.stopPropagation();
	       
	  } else {	
	  	if (!oCtl.mbRet)
	  		event.keyCode = 0;
	  	event.cancelBubble = true;
	  	event.returnValue = oCtl.mbRet;
		}
	
		return oCtl.mbRet;
	}

};

var DATEEDT_mDef = "  /  /    ";
var DATEEDT_mDef3 = "  /    ";
var formato; 


function getSelectionStart(obj)
{
    if (obj.setSelectionRange) {
      var selectionStart = obj.selectionStart;
      return selectionStart;
  } else {

  	var oRng = document.selection.createRange();
  	if (oRng) {
  		var sBmk = oRng.getBookmark();
  		var nMov = oRng.move("character", -99);
  		oRng.moveToBookmark(sBmk);
  		return -nMov; }
  	else
  		return 0
  }
}

function getSelectionStartLength(obj)
{
	oSel = new Object;
	oSel.start = 0;
	oSel.length = 0;
	oSel.bSelected = true;
	
  if (obj.setSelectionRange) {
    var selectionStart = obj.selectionStart;
    var selectionEnd = obj.selectionEnd;
    if (selectionStart>=0) {
      oSel.length = selectionEnd-selectionStart;
      if (oSel.length==0) {
  			oSel.bSelected = false;
  			oSel.length++;
      }

    	oSel.start = selectionStart;
  	} 
  	return oSel;
      
     
  } else {
  	var oRng = document.selection.createRange();
  	if (oRng) {
  		oSel.length = oRng.text.length;
  		if(!oSel.length) {
  			oSel.bSelected = false;
  			oSel.length++;
  		}	
  		var sBmk = oRng.getBookmark();
  		var nMov = oRng.move("character", -99);
  		oRng.moveToBookmark(sBmk);
  		oSel.start = -nMov;
  	} 
  	return oSel;
  }  		
}



function setSelectionStart(nPos, obj, nLen)
{
  if (obj.setSelectionRange || typeof(event)=="undefined") {
    obj.setSelectionRange(nPos,nPos);
  } else {
  	var oRng = document.selection.createRange();
  	oRng.move("character", -99);
  	oRng.move("character", nPos);
  	if (nLen && nLen > 0)
  	{
  		oRng.moveEnd("character", nLen);
  	}
  	oRng.select();
	}
}

function textSetValue(sVal,obj)
{
  if (obj.setSelectionRange) {
    obj.setSelectionRange(0,0);
    obj.text=sVal;
    obj.value=sVal;
  } 
  else {
    var oRng = document.selection.createRange();
    oRng.move("character", 0);
    oRng.moveEnd("character", 0);
    oRng.select();
    oRng.text = sVal;
  }
}

function DATEEDT_isDate(vDat)
{
	var sTmp, sTempor, theDay, theMounth, theYear;
	if (typeof vDat == "string")
		sTempor = vDat;
	else
		sTempor = vDat.value;
		
	
	if (formato == 3)
	{
	  theDay = 10;
	  theMounth = sTempor.substr(0,2);
	  theYear = sTempor.substr(3,4);
	  sTmp = theDay + "/" + theMounth + "/" + theYear;
	}
	else if (formato == 2)
	{
	  theMounth = sTempor.substr(0,2);  
	  theDay = sTempor.substr(3,2);
	  theYear = sTempor.substr(6,4);
	  sTmp = theDay + "/" + theMounth + "/" + theYear;
	}
	else 
	  sTmp = sTempor;
	
	var arDate = sTmp.match(/(\d\d)[-\/](\d\d)[-\/](\d\d\d\d)/);
	if(arDate == null)
		return false;
	var sDay = RegExp.$1, nDay = parseInt(sDay,10);
	var sMth = RegExp.$2, nMth = parseInt(sMth,10);
	var sYea = RegExp.$3, nYea = parseInt(sYea,10);
	
	if (isNaN(nDay))
		nDay = 0;
	if (isNaN(nMth))
		nMth = 0;
	if (isNaN(nYea))
		nYea = 0;

	var xDat = new Date(nYea, nMth - 1, nDay);

	return (xDat.getDate() == nDay && xDat.getMonth() == nMth -1 && xDat.getFullYear() == nYea);
}
