(function () {
    var dlcalendar_oCalendarDefaults={
    	urlbase: "",
    	idbase: "dl_calendar_",
    	months: "Ene,Feb,Mar,Abr,May,Jun,Jul,Ago,Sep,Oct,Nov,Dic",
    	days: "Do,Lu,Ma,Mi,Ju,Vi,Sa",
    	firstday: "Lu",
    	date_format: "dd/mm/yyyy",
    	start_date: "1920-01-01",
    	end_date: "2200-01-01",
    	root_date: "1975-01-01",
    	tool_tip: "Seleccione la fecha",
    	nav_images: "dlcalendar_prevyear.gif,dlcalendar_prevmonth.gif,dlcalendar_nextmonth.gif,dlcalendar_nextyear.gif",
    	navbar_style: "",
    	daybar_style: "",
    	input_element_id: null,
    	click_element_id: null,
    	selecteddate_style: "",
    	weekenddate_style: "",
    	regulardate_style: "",
    	othermonthdate_style: "",
    	hide_selects: true,
    	hide_onselection: true,
    	callfunction_onselection: null
    };

    function dlcalendar_start() {
    	dlcalendar_assignGlobalVariables();
    	if(dlcalendar_isCompatible()) {
    		dlcalendar_assignPrototypes();
    		dlcalendar_parseCalendarTags();
    	}
    }

    function dlcalendar_assignGlobalVariables() {
    	window.dlcalendar_aAllCalendars=new Array();
    	window.dlcalendar_bBrowserSniffed=false;
    	window.dlcalendar_bCompatible=false;
    	window.dlcalendar_sBrowser=null;
    }

    function dlcalendar_assignPrototypes() {
    	window.Object.prototype.dlcalendar_mToBoolean=function(){return((this==true) || (this=="true"));}
    	window.String.prototype.dlcalendar_mTrim=function(){ return this.replace(/(^\s*)|(\s*$)/g,'')};
    	if(("1234").slice(-2).length==2) {
    		window.String.prototype.dlcalendar_mLastTwoChars=function(){ return(("0" + this).slice(-2))};
    	} else {
    		window.String.prototype.dlcalendar_mLastTwoChars=function() {
    			var sPrepended=("0" + this);
    			return(sPrepended.substr(sPrepended.length-2,2));
    		}
    	}
    	window.String.prototype.dlcalendar_mValueToObject=function() {
    		return(this=="null") ? null : (this=="false") ? false : (this=="true") ? true : this;
    	}
    	window.Date.prototype.dlcalendar_mGetMonthString=function(aMonths) {
    		return aMonths[this.getMonth()];
    	}
    	window.Date.prototype.dlcalendar_mIsWeekend=function() {
    		var nDayofWeek=this.getDay();
    		return(nDayofWeek==0 || nDayofWeek==6);
    	}
    	if(window.Array.prototype.push==null) {
    		window.Array.prototype.push=function(vObject) {
    			this[this.length]=vObject;
    		}
    	}
    	window.Array.prototype.dlcalendar_mAppendArray=function() {
    		var aArguments=arguments;
    		var nArguments=aArguments.length;
    		var aArray,nArray,j;
    		for(var i=0; i<nArguments; i++) {
    			aArray=aArguments[i];
    			nArray=aArray.length;
    			for(j=0; j<nArray; j++) {
    				this.push(aArray[j]);
    			}
    		}
    	}
    	dlcalendar_buildCalendar.prototype=dlcalendar_oCalendarDefaults;
    }

    function dlcalendar_isCompatible() {
    	if(window.dlcalendar_bBrowserSniffed) {
    		return window.dlcalendar_bCompatible;
    	}
    	var sBrowser;
    	var bCompatible=false;
    	var oNavigator=window.navigator;
    	var bWindows=(oNavigator.platform.toLowerCase().indexOf("win") !=-1);
    	if(bWindows) {
    		var bDOM=(document.getElementById !=null);
    		var bOpera=false;
    		var bGecko=false;
    		var bIE=false;
    		var bNetscape=false;
    		var bMozilla=false;
    		if(bDOM) {
    			if(window.opera !=null) {
    				var aMatches=oNavigator.userAgent.match(/Opera.([\d]+\.[\d]+)/);
    				if(aMatches !=null) {
    					var nVersion=parseFloat(aMatches[1]);
    					if(nVersion >=7.02) {
    						bOpera=true;
    						sBrowser="Opera";
    					}
    				}
    			} else {
    				if((oNavigator.product !=null) && (oNavigator.product.toLowerCase()=="gecko")) {
    					var nVendorSub=parseFloat(oNavigator.vendorSub);
    					bNetscape=((oNavigator.vendor.toLowerCase().indexOf('netscape') !=-1) && (nVendorSub >=6.1));
    					if(!bNetscape) {
    						var aMatches=oNavigator.userAgent.match(/rv.([\d]+\.[\d]+)/);
    						if(aMatches !=null) {
    							//0.9.3 crashes on occasion
    							var sVersion=aMatches[1]
    							if(sVersion !="0.9.3") {
    								var nVersion=parseFloat(sVersion);
    								bMozilla=(nVersion >=0.9);
    							}
    						}
    					} else {
    						window.dlcalendar_nNetscapeVendorSub=nVendorSub;
    					}
    					if(bNetscape || bMozilla) {
    						bGecko=true;
    						sBrowser="Gecko";
    					}
    				} else {
    					if(document.all !=null) {
    						var aMatches=oNavigator.userAgent.match(/MSIE ([\d]+\.[\d]+)/);
    						if(aMatches !=null) {
    							var sVersion=aMatches[1];
    							var nVersion=parseFloat(sVersion);
    							if(nVersion >=5) {
    								bIE=true;
    								sBrowser="IE";
    								window.dlcalendar_bIE5=(nVersion <=5.5);
    							}
    						}
    					}
    				}
    			}
    			var bCompatible=(bOpera || bGecko || bIE);
    			if(bCompatible) {
    				window.dlcalendar_bOpera=bOpera;
    				window.dlcalendar_bGecko=bGecko;
    				window.dlcalendar_bIE=bIE;
    				window.dlcalendar_sBrowser=sBrowser;
    				bCompatible=true;
    			}
    		}
    	}
    	window.dlcalendar_bBrowserSniffed=true;
    	window.dlcalendar_bCompatible=bCompatible;
    	return bCompatible;
    }

    function dlcalendar_parseCalendarTags() {
    	var aCalendarTagsUPPER=document.getElementsByTagName('DLCALENDAR');
    	var aCalendarTagsLower=document.getElementsByTagName('dlcalendar');
    	if(aCalendarTagsUPPER==aCalendarTagsLower) {
    		var aCalendarTags=aCalendarTagsUPPER;
    	} else {
    		var aCalendarTags=new Array();
    		aCalendarTags.dlcalendar_mAppendArray(aCalendarTagsUPPER,aCalendarTagsLower);
    	}
    	var nCalendarTags=aCalendarTags.length;
    	var mParseAttributes=window.dlcalendar_bIE ? window.dlcalendar_bIE5 ? dlcalendar_parseAttributesIE5 : dlcalendar_parseAttributesIE6 : dlcalendar_parseAttributesDOM;
    	for(var i=0; i<nCalendarTags; i++) {
    		dlcalendar_makeCalendar(mParseAttributes(aCalendarTags[i]));
    	}
    }

    function dlcalendar_parseAttributesIE5(eCalendarTag) {
    	var oCalendarParams=new Object();
    	var oCalendarDefaults=dlcalendar_oCalendarDefaults;
    	for(sAttribute in oCalendarDefaults) {
    		if(eCalendarTag[sAttribute]!=null) {
    			oCalendarParams[sAttribute]=eCalendarTag[sAttribute];
    		}
    	}
    	return oCalendarParams;
    }

    function dlcalendar_parseAttributesIE6(eCalendarTag) {
    	var oCalendarParams=new Object();
    	var aAttributes=eCalendarTag.attributes;
    	var oAttribute;
    	for(sAttribute in aAttributes) {
    		oAttribute=aAttributes[sAttribute];
    		if((oAttribute !=null) && oAttribute.specified) {
    			oCalendarParams[sAttribute.toLowerCase()]=oAttribute.nodeValue.dlcalendar_mValueToObject();
    		}
    	}
    	return oCalendarParams;
    }

    function dlcalendar_parseAttributesDOM(eCalendarTag) {
    	var oCalendarParams=new Object();
    	var aAttributes=eCalendarTag.attributes;
    	var nAttributes=aAttributes.length;
    	var oAttribute;
    	for(var i=0; i<nAttributes; i++) {
    		oAttribute=aAttributes[i];
    		oCalendarParams[oAttribute.nodeName]=oAttribute.nodeValue.dlcalendar_mValueToObject();
    	}
    	return oCalendarParams;
    }

    function dlcalendar_makeCalendar(oParams) {
    	if(dlcalendar_isCompatible()) {
    		new dlcalendar_buildCalendar(oParams);
    	}
    }

    function dlcalendar_buildCalendar(oParams) {
    	if(oParams !=null) {
    		for(var sProp in oParams) {
    			this[sProp]=oParams[sProp];
    		}
    	}
    	this.id=this.idbase + '_' + (this.id || dlcalendar_aAllCalendars.length);
    	if(window.dlcalendar_bOpera || window.dlcalendar_nNetscapeVendorSub >=7.1) {
    		this.hide_selects=false;
    	}
    	this.aNavChars=this.nav_images.split(",");
    	this.aNavHandlers=[dlcalendar_prevYearOnClick,dlcalendar_prevMonthOnClick,dlcalendar_nextMonthOnClick,dlcalendar_nextYearOnClick];
    	this.aMonths=this.months.split(",");
    	this.aDays=this.days.split(",");
    	for(var i=0; i<7; i++) {
    		if(this.aDays[i]==this.firstday) {
    			this.nFirstDay=i;
    			break;
    		}
    	}
    	this.bCalendarCreated=false;
    	this.mCreateCalendarElement=dlcalendar_createCalendarElement;
    	this.mInitialize=dlcalendar_initialize;
    	this.mPaint=dlcalendar_paint;
    	this.mBuildNavigationCell=dlcalendar_buildNavigationCell;
    	this.mCreateHeader=dlcalendar_createHeader;
    	this.mCreateHeaderRow=dlcalendar_createHeaderRow;
    	this.mWriteHeaderDate=dlcalendar_writeHeaderDate;
    	this.mCreateBody=dlcalendar_createBody;
    	this.mCreateDaysRow=dlcalendar_createDaysRow;
    	this.mCreateDateRows=dlcalendar_createDateRows;
    	this.mWriteDateCells=dlcalendar_writeDateCells;
    	this.mPosition=dlcalendar_position;
    	this.mGetCalendarElement=dlcalendar_getCalendarElement;
    	this.mSetDisplayedDate=dlcalendar_setDisplayedDate;
    	this.mGetDisplayedDate=dlcalendar_getDisplayedDate;
    	this.mSetSelectedDate=dlcalendar_setSelectedDate;
    	this.mGetSelectedDate=dlcalendar_getSelectedDate;
    	this.mSetStartDate=dlcalendar_setStartDateMethod;
    	this.mSetEndDate=dlcalendar_setEndDateMethod;
    	this.mCompareDates=dlcalendar_compareDates;
    	this.mIsBeyondLimits=dlcalendar_isBeyondLimits;
    	this.mCheckDateLimit=dlcalendar_checkDateLimit;
    	this.mParseInput=dlcalendar_parseInput;
    	this.mSelectedDateToString=dlcalendar_selectedDateToString;
    	this.mDateObjectToString=dlcalendar_dateObjectToString;
    	this.mGetInputElement=dlcalendar_getInputElement;
    	this.mGetInputValue=dlcalendar_getInputValue;
    	this.bHasInput=(this.mGetInputElement() !=null);
    	this.mUpdateInputWithDate=this.bHasInput ? dlcalendar_updateInputWithDate : new Function;
        this.mUpdateInputsValues = dlcalendar_updateInputsValues;
    	this.mOnNewSelection=dlcalendar_onNewSelection;
    	this.mShow=dlcalendar_show;
    	this.mHide=dlcalendar_hide;
    	this.mMakeInlineStyle=dlcalendar_makeInlineStyle;
    	dlcalendar_setCalendarObject(this);
    	this.mInitialize();
    	return this;
    }

    function dlcalendar_setCalendarObject(oCalendar) {
    	window.dlcalendar_aAllCalendars.push(oCalendar.id);
    	window.dlcalendar_aAllCalendars[oCalendar.id]=oCalendar;
    }

    function dlcalendar_getCalendarObject(sId) {
    	return window.dlcalendar_aAllCalendars[sId];
    }

    function dlcalendar_getCalendarElement() {
    	return dlcalendar_getElementById(this.id);
    }

    function dlcalendar_getInputElement() {
    	return MVD.Form.getFecha(this.input_element_id);
    }

    function dlcalendar_setSelectedDate(dSelectedDate) {
    	this.dSelectedDate=new Date(dSelectedDate);
    	this.mSetDisplayedDate(dSelectedDate);
    }

    function dlcalendar_getSelectedDate() {
    	return this.dSelectedDate;
    }

    function dlcalendar_setDisplayedDate(dDate) {
    	this.dDisplayedDate=new Date(dDate);
    }

    function dlcalendar_getDisplayedDate() {
    	return this.dDisplayedDate;
    }

    function dlcalendar_cancelEvent() {
    	return false;
    }

    function dlcalendar_calendarOnMouseDown(e) {
    	(e || window.event).cancelBubble=true;
    }

    function dlcalendar_initialize() {
    	this.mSetDisplayedDate(new Date());
    	this.mSetSelectedDate(new Date());
    	document.body.appendChild(this.mCreateCalendarElement());
    	var fDocumentOnMousedown=(document.onmousedown || new Function());
    	document.onmousedown=function(){ dlcalendar_hideAll(); fDocumentOnMousedown();};
    	this.mPaint();
    }

    function dlcalendar_createCalendarElement() {
    	//create the physical calendar element
    	var eCalendar=document.createElement('div');
    	var sId=this.id;
    	eCalendar.id=sId;
    	eCalendar.style.position='absolute';
    	eCalendar.style.left='0px';
    	eCalendar.style.top='0px';
    	eCalendar.style.visibility='hidden';
    	eCalendar.style.backgroundColor='#ffffff';
    	eCalendar.onselectstart=dlcalendar_cancelEvent;
    	eCalendar.oncontextmenu=dlcalendar_cancelEvent;
    	eCalendar.onmousedown=dlcalendar_calendarOnMouseDown;
    	var eClick=dlcalendar_getElementById(this.click_element_id);
    	if(eClick !=null) {
    		eClick.onclick=dlcalendar_showCalendar;
    		eClick.style.cursor=(window.dlcalendar_bIE ? "hand" : "pointer");
    		eClick.title=this.tool_tip;
    		eClick.sCalendarId=sId;
    	}
    	var eTableContainer=document.createElement('table');
    	eTableContainer.cellSpacing=0;
    	eTableContainer.cellPadding=0;
    	eTableContainer.border=0;
    	eTableContainer.id='dlcalendar_container';
    	var eTBody=document.createElement('tbody');
    	var eHeadRow=document.createElement('tr');
    	var eHeadCell=document.createElement('td');
    	eHeadRow.appendChild(eHeadCell);
    	var eBodyRow=document.createElement('tr');
    	var eBodyCell=document.createElement('td');
    	eBodyRow.appendChild(eBodyCell);
    	eTBody.appendChild(eHeadRow);
    	eTBody.appendChild(eBodyRow);
    	eTableContainer.appendChild(eTBody);
    	eCalendar.appendChild(eTableContainer);
    	this.eHeadCell=eHeadCell;
    	this.eBodyCell=eBodyCell;
    	return eCalendar;
    }

    function dlcalendar_paint() {
    	if(!this.bCalendarCreated) {
    		this.eHeadCell.appendChild(this.mCreateHeader());
    		this.eBodyCell.appendChild(this.mCreateBody());
    		this.bCalendarCreated=true;
    	}
    	this.mWriteHeaderDate();
    	this.mWriteDateCells();
    	if(window.dlcalendar_bOpera) {
    		var eCalendar=this.mGetCalendarElement();
    		eCalendar.style.posLeft+=1;
    		eCalendar.style.posLeft-=1;
    	}
    }

    function dlcalendar_createHeader() {
    	var eHeadTable=document.createElement('table');
    	eHeadTable.id='dlcalendar_navigationRow';
    	eHeadTable.cellSpacing=0;
    	eHeadTable.cellPadding=0;
    	eHeadTable.border=0;
    	this.mMakeInlineStyle(eHeadTable,this.navbar_style);
    	eHeadTable.appendChild(this.mCreateHeaderRow());
    	return eHeadTable;
    }

    function dlcalendar_createHeaderRow() {
    	var eHeadTableTBody=document.createElement("tbody");
    	var eHeadTableRow=document.createElement("tr");
    	eHeadTableRow.vAlign="middle";
    	eHeadTableRow.appendChild(this.mBuildNavigationCell(0));
    	eHeadTableRow.appendChild(this.mBuildNavigationCell(1));
    	var sDisplayedMonthCellId=this.id + "dlcalendar_monthYearCell";
    	var eDisplayedMonthCell=document.createElement('td');
    	eDisplayedMonthCell.id=sDisplayedMonthCellId;
    	eDisplayedMonthCell.className="dlcalendar_monthYearCell";
    	eDisplayedMonthCell.align="center";
    	eDisplayedMonthCell.style.width="100%";
    	eDisplayedMonthCell.style.whiteSpace='nowrap';
    	this.sDisplayedMonthCellId=sDisplayedMonthCellId;
    	eHeadTableRow.appendChild(eDisplayedMonthCell);
    	eHeadTableRow.appendChild(this.mBuildNavigationCell(2));
    	eHeadTableRow.appendChild(this.mBuildNavigationCell(3));
    	eHeadTableTBody.appendChild(eHeadTableRow);
    	return eHeadTableTBody;
    }

    function dlcalendar_buildNavigationCell(nDirection) {
    	var eNavCell=document.createElement("td");
    	var sNavChar=this.urlbase+this.aNavChars[nDirection];
    	eNavCell.className='dlcalendar_navImages';
    	var eImage=document.createElement('img');
    	eImage.src=sNavChar;
    	eNavCell.appendChild(eImage);
    	eNavCell.onmousedown=this.aNavHandlers[nDirection];
    	eNavCell.sCalendarId=this.id;
    	return eNavCell;
    }

    function dlcalendar_createBody() {
    	var eBodyTable=document.createElement('table');
    	eBodyTable.cellSpacing=0;
    	eBodyTable.cellPadding=0;
    	eBodyTable.id="dlcalendar_bodyTable";
    	eBodyTable.appendChild(this.mCreateDaysRow());
    	eBodyTable.appendChild(this.mCreateDateRows());
    	return eBodyTable;
    }

    function dlcalendar_createDaysRow() {
    	var eBodyTableHead=document.createElement('thead');
    	var eBodyTableHeadRow=document.createElement('tr');
    	eBodyTableHeadRow.id="dlcalendar_headerRow";
    	var aDays=this.aDays;
    	var nFirstDay=this.nFirstDay;
    	var eBodyTableHeadCell;
    	for(var i=0; i<7; i++) {
    		eBodyTableHeadCell=document.createElement('th');
    		eBodyTableHeadCell.className="dlcalendar_headerRowCell";
    		this.mMakeInlineStyle(eBodyTableHeadCell,this.daybar_style);
    		eBodyTableHeadCell.innerHTML=aDays[(nFirstDay + i) % 7];
    		eBodyTableHeadRow.appendChild(eBodyTableHeadCell);
    	}
    	eBodyTableHead.appendChild(eBodyTableHeadRow);
    	return eBodyTableHead;
    }

    function dlcalendar_createDateRows() {
    	var sCalendarId=this.id;
    	var eBodyTableBody=document.createElement('tbody');
    	var sBodyTableBodyId=sCalendarId + "dlcalendar_idDateBody";
    	eBodyTableBody.id=sBodyTableBodyId;
    	var eDateRow,j,eDateCell;
    	for(var i=0; i < 6; i++) {
    		eDateRow=document.createElement('tr');
    		eDateRow.className="dlcalendar_dateRow";
    		for(j=0; j < 7; j++) {
    			eDateCell=document.createElement('td');
    			eDateCell.sCalendarId=sCalendarId;
    			eDateRow.appendChild(eDateCell);
    		}
    		eBodyTableBody.appendChild(eDateRow);
    	}
    	this.sBodyTableBodyId=sBodyTableBodyId;
    	return eBodyTableBody;
    }

    function dlcalendar_writeHeaderDate() {
    	var dDisplayedDate=this.mGetDisplayedDate();
    	dlcalendar_getElementById(this.sDisplayedMonthCellId).innerHTML=(dDisplayedDate.dlcalendar_mGetMonthString(this.aMonths) + " " + dDisplayedDate.getFullYear());
    }

    function dlcalendar_getElementById(sElementId) {
    	return document.getElementById(sElementId);
    }

    function dlcalendar_writeDateCells() {
    	var eBodyTableBody=dlcalendar_getElementById(this.sBodyTableBodyId);
    	var dDisplayedDate=this.mGetDisplayedDate();
    	var dTempDate=new Date(dDisplayedDate);
    	dTempDate.setDate(1); //set temp date to first of displayed month
    	var nFirstDayofMonth=dTempDate.getDay(); //get day of week of first of displayed month
    	var nDisplayedDate=dDisplayedDate.getDate();
    	var nDisplayedMonth=dDisplayedDate.getMonth();
    	var sSelectedDateStyle=(this.selecteddate_style || "");
    	var sWeekendDateStyle=(this.weekenddate_style || "");;
    	var sRegularDateStyle=(this.regulardate_style || "");
    	var sOtherMonthDateStyle=(this.othermonthdate_style || "");
    	var aDateRows=eBodyTableBody.getElementsByTagName('tr');
    	var eDateRow,aDateCells,j,eDateCell,nTempMonth,nTempDate,sClassName,sUserStyle,bDisabled,mClick,sDisplayText;
    	var nStartCell=((7 + nFirstDayofMonth - this.nFirstDay) % 7);
    	for(var i=0; i < 6; i++) {
    		eDateRow=aDateRows[i];
    		aDateCells=eDateRow.getElementsByTagName("td");
    		for(j=0; j < 7; j++) {
    			eDateCell=aDateCells[j];
    			nTempMonth=dTempDate.getMonth();
    			mClick=null;
    			if(i==0 && j < nStartCell || nTempMonth !=nDisplayedMonth) {
    				sClassName="dlcalendar_dayOtherMonth";
    				sCustomStyle=sOtherMonthDateStyle;
    				sDisplayText="&nbsp;";
    			} else {
    				nTempDate=dTempDate.getDate();
    				if(this.mCompareDates(this.mGetSelectedDate(),dTempDate)==0) {
    					sClassName="dlcalendar_daySelected";
    					sCustomStyle=sSelectedDateStyle;
    				} else if(dTempDate.dlcalendar_mIsWeekend()) {
    					sClassName="dlcalendar_dayWeekend";
    					sCustomStyle=sWeekendDateStyle;
    				} else {
    					sClassName="dlcalendar_dayRegular";
    					sCustomStyle=sRegularDateStyle;
    				}
    				bDisabled=this.mIsBeyondLimits(dTempDate);
    				eDateCell.disabled=bDisabled;
    				if(bDisabled) {
    					sClassName="dlcalendar_dayDisabled";
    				} else {
    					eDateCell.nDayOfMonth=nTempDate;
    					mClick=dlcalendar_dateOnMousedown;
    				}
    				sDisplayText=nTempDate;
    				dTempDate.setDate(nTempDate + 1);
    			}
    			eDateCell.className=sClassName;
    			this.mMakeInlineStyle(eDateCell,sCustomStyle);
    			eDateCell.innerHTML=sDisplayText;
    			eDateCell.onclick=mClick;
    		}
    	}
    }

    function dlcalendar_compareDates(dDate0,dDate1) {
    	var bSameDate=((dDate0.getDate()==dDate1.getDate()) && (dDate0.getMonth()==dDate1.getMonth()) && (dDate0.getFullYear()==dDate1.getFullYear()));
    	if(!bSameDate) {
    		return((dDate0 < dDate1) ? -1 : 1);
    	}
    	return 0;
    }

    function dlcalendar_checkDateLimit(dDateToCheck) {
    	var bValidDate=true;
    	if(this.start_date !=null) {
    		var dLimitDate=dlcalendar_dateObjectFromString(this.start_date);
    		bValidDate=(dDateToCheck >=dLimitDate);
    	}
    	if(bValidDate && (this.end_date !=null)) {
    		dLimitDate=dlcalendar_dateObjectFromString(this.end_date);
    		bValidDate=(dDateToCheck <=dLimitDate);
    	}
    	return bValidDate ? dDateToCheck : dLimitDate;
    }

    function dlcalendar_isBeyondLimits(dDate) {
    	var dNewDate=this.mCheckDateLimit(dDate);
    	return(!(this.mCompareDates(dNewDate,dDate)==0));
    }

    function dlcalendar_setStartDate(sId,sDate) {
    	var sCalendarId=(dlcalendar_oCalendarDefaults.idbase + '_' + sId);
    	var oCalendar=dlcalendar_getCalendarObject(sCalendarId);
    	oCalendar.mSetStartDate(sDate);
    }

    function dlcalendar_setEndDate(sId,sDate) {
    	var sCalendarId=(dlcalendar_oCalendarDefaults.idbase + '_' + sId);
    	var oCalendar=dlcalendar_getCalendarObject(sCalendarId);
    	oCalendar.mSetEndDate(sDate);
    }

    function dlcalendar_setStartDateMethod(sDate) {
    	this.start_date=sDate;
    }

    function dlcalendar_setEndDateMethod(sDate) {
    	this.end_date=sDate;
    }

    function dlcalendar_showCalendar(e) {//this==click element (image)
    	var oEvent=(e || window.event);
    	dlcalendar_hideAll();
    	var sCalendarId=this.sCalendarId;
    	var oCalendar=dlcalendar_getCalendarObject(sCalendarId);
    	oCalendar.mPosition(e);
    	if(oCalendar.bHasInput && (oCalendar.mGetInputValue().length > 0) ) {
    		oCalendar.mSetSelectedDate(oCalendar.mParseInput());
    		oCalendar.mUpdateInputWithDate();
    	} else if(oCalendar.root_date !=null) {
    		oCalendar.mSetSelectedDate(dlcalendar_dateObjectFromString(oCalendar.root_date));
    	} else {
    		oCalendar.mSetSelectedDate(new Date());
    	}
    	oCalendar.mPaint();
    	oCalendar.mShow();
    	oEvent.cancelBubble=true;
    }

    function dlcalendar_position(e) {
    	var oEvent=(e || window.event);
    	var eDocBody=document.body;
    	var nWindowLeftEdge=eDocBody.scrollLeft;
    	var nWindowTopEdge=eDocBody.scrollTop;
    	var nLeftPos=(oEvent.pageX || oEvent.x + nWindowLeftEdge);
    	var nTopPos=(oEvent.pageY || oEvent.y + nWindowTopEdge);
    	dlcalendar_keepInWindow(this.mGetCalendarElement(),nLeftPos,nTopPos)
    }

    function dlcalendar_keepInWindow(eElement,nLeftPos,nTopPos) {
    	var nMinSpace=5;
    	var eDocBody=document.body;
    	var nWindowLeftEdge=eDocBody.scrollLeft;
    	var nWindowTopEdge=eDocBody.scrollTop;
    	var nWindowWidth=(window.innerWidth !=null) ? window.innerWidth : eDocBody.clientWidth;
    	var nWindowHeight=(window.innerHeight !=null) ? window.innerHeight : eDocBody.clientHeight;
    	var nWindowRightEdge=(nWindowLeftEdge + nWindowWidth) - nMinSpace;
    	var nWindowBottomEdge=(nWindowTopEdge + nWindowHeight) - nMinSpace;
    	var nElementRightEdge=nLeftPos + eElement.offsetWidth;
    	var nElementBottomEdge=nTopPos + eElement.offsetHeight;
    	if(nElementRightEdge > nWindowRightEdge) {
    		nLeftPos -=(nElementRightEdge - nWindowRightEdge);
    		nLeftPos=Math.max(nMinSpace,nLeftPos);
    	}
    	if(nElementBottomEdge > nWindowBottomEdge) {
    		nTopPos -=(nElementBottomEdge - nWindowBottomEdge);
    		nTopPos=Math.max(nMinSpace,nTopPos);
    	}
    	eElement.style.left=(nLeftPos + "px");
    	eElement.style.top=(nTopPos + "px");
    }

    function dlcalendar_updateInputWithDate() {
    	var eInput=this.mGetInputElement();
    	var sInputValue=this.mGetInputValue();
    	var sDateString=this.mSelectedDateToString();
    	if(sInputValue !=sDateString) {
    		this.mUpdateInputsValues();
    	}
    }

    function dlcalendar_getInputValue() {
    	var eInput = this.mGetInputElement();
        var v = eInput.getDMY();
        var date = v ?  new Date(v[2], v[1] - 1, v[0]) : new Date();
        return this.mDateObjectToString(date);
    }

    function dlcalendar_updateInputsValues() {
        var eInput = this.mGetInputElement();
        var d = this.dSelectedDate;
        eInput.setValue(d.getDate(), d.getMonth() + 1, d.getFullYear());
    }

    function dlcalendar_selectedDateToString() {
    	return this.mDateObjectToString(this.mGetSelectedDate());
    }

    function dlcalendar_dateObjectToString(dDate) {
    	var xRegExp=/(\{.*\})|(d+)|(m+)|(M+)|(y+)|[^dMmy]/g;
    	var sFormat=this.date_format;
    	var aMatches=sFormat.match(xRegExp);
    	var nMatches=aMatches.length;
    	var aStringDate=new Array();
    	var sMatch,nChars,sChar,sDisplay,sYear,sMonth,nMonth,sDate;
    	for(var i=0; i<nMatches; i++) {
    		sMatch=aMatches[i];
    		nChars=sMatch.length;
    		sChar=sMatch.charAt(0);
    		sDisplay="";
    		switch(sChar) {
    			case 'y':
    				sYear=dDate.getFullYear().toString();
    				if(nChars <=2) {
    					sYear=sYear.dlcalendar_mLastTwoChars();
    				}
    				sDisplay=sYear;
    				break;
    			case 'm':
    				sMonth=(dDate.getMonth() + 1).toString();
    				if(nChars >=2) {
    					sMonth=sMonth.dlcalendar_mLastTwoChars();
    				}
    				sDisplay=sMonth;
    				break;
    			case 'M':
    				sMonth=dDate.dlcalendar_mGetMonthString(this.aMonths);
    				sDisplay=sMonth.substr(0,nChars);
    				break;
    			case 'd':
    				sDate=(dDate.getDate()).toString();
    				if(nChars >=2) {
    					sDate=sDate.dlcalendar_mLastTwoChars();
    				}
    				sDisplay=sDate;
    				break;
    			default:
    				sDisplay=sMatch.replace(/\{|\}/g,'');
    				break;
    		}
    		aStringDate[i]=sDisplay;
    	}
    	return aStringDate.join("");
    }

    function dlcalendar_parseInput(sDateString) {
    	var sInputValue=this.mGetInputValue();
    	var sFormat=this.date_format;
    	var xRegExp=/([^dmMy])|($)/;
    	var oDate=new Object();
    	var aMatches,sMaskSegment,nMaskSegmentLength,sDelimiter,bEndOfDateFormat,sInputSegment,nInputSegmentLength,sFirstMaskChar;
    	while(sInputValue.length !=0) {
    		aMatches=sFormat.match(xRegExp);
    		if(aMatches !=null) {
    			sMaskSegment=sFormat.substr(0,aMatches.index);
    			nMaskSegmentLength=sMaskSegment.length;
    			sDelimiter=aMatches[0];
    			bEndOfDateFormat=(sDelimiter.length==0);
    			sInputSegment=(bEndOfDateFormat ? sInputValue : (sInputValue.substr(0,sInputValue.indexOf(sDelimiter))));
    			nInputSegmentLength=sInputSegment.length;
    			sFirstMaskChar=sMaskSegment.charAt(0);
    			switch(sFirstMaskChar) {
    				case 'y':
    					var nYear=Number(sInputSegment);
    					if((!isNaN(nYear))) {
    						if((nMaskSegmentLength <=2) && (nInputSegmentLength <=2)) {
    							if(nYear > 50) {
    								nYear=nYear + 1900;
    							} else {
    								nYear=nYear + 2000;
    							}
    						}
    						oDate.nYear=nYear;
    					}
    					break;
    				case 'm':
    					var nMonth=Number(sInputSegment);
    					if((!isNaN(nMonth)) && (nMonth >=1) && (nMonth <=12)) {
    						oDate.nMonth=(nMonth - 1);
    					}
    					break;
    				case 'M':
    					var aMonths=this.aMonths;
    					sMonth=sInputSegment.toLowerCase();
    					for(var i=0; i<12; i++) {
    						if(sMonth==aMonths[i].toLowerCase()) {
    							oDate.nMonth=i;
    							break;
    						}
    					}
    					break;
    				case 'd':
    					var nDate=Number(sInputSegment);
    					if((!isNaN(nDate)) && (nDate >=1) && (nDate <=31)) {
    						oDate.nDate=nDate;
    					}
    					break;
    			}
    			sFormat=sFormat.slice(aMatches.index + 1);
    			sInputValue=sInputValue.slice(nInputSegmentLength + 1);
    		}
    	}
    	if(!isNaN(oDate.nYear + oDate.nMonth + oDate.nDate)) {
    		var dNewDate=new Date(oDate.nYear,oDate.nMonth,oDate.nDate);
    		return this.mCheckDateLimit(dNewDate);
    	} else {
    		return new Date();
    	}
    }

    function dlcalendar_nextMonthOnClick(e) {
    	dlcalendar_navigate(e,this.sCalendarId,true,true);
    }

    function dlcalendar_prevMonthOnClick(e) {
    	dlcalendar_navigate(e,this.sCalendarId,true,false);
    }

    function dlcalendar_nextYearOnClick(e) {
    	dlcalendar_navigate(e,this.sCalendarId,false,true);
    }

    function dlcalendar_prevYearOnClick(e) {
    	dlcalendar_navigate(e,this.sCalendarId,false,false);
    }

    function dlcalendar_navigate(e,sCalendarId,bMonth,bNext) {
    	(e || window.event).cancelBubble=true;
    	var oCalendar=dlcalendar_getCalendarObject(sCalendarId);
    	var dDisplayedDate=oCalendar.mGetDisplayedDate();
    	var nDisplayedYear=dDisplayedDate.getFullYear();
    	var nDisplayedMonth=dDisplayedDate.getMonth();
    	var nDirection=(bNext ? 1 : -1);
    	var dNewDate=new Date(dDisplayedDate);
    	if(bMonth) {
    		dNewDate.setMonth(nDisplayedMonth + nDirection);
    	} else {
    		dNewDate.setFullYear(nDisplayedYear + nDirection);
    	}
    	oCalendar.mSetDisplayedDate(oCalendar.mCheckDateLimit(dNewDate));
    	oCalendar.mPaint();
    }

    function dlcalendar_onNewSelection(nDayOfMonth) {
    	var oNewDate=new Date(this.mGetDisplayedDate());
    	oNewDate.setDate(nDayOfMonth);
    	this.mSetSelectedDate(oNewDate);
    	this.mUpdateInputWithDate();
    	if(this.hide_onselection.dlcalendar_mToBoolean()) {
    		this.mHide();
    	} else {
    		this.mPaint();
    	}
    	if(this.callfunction_onselection) {
    		var dSelectedDate=this.mGetSelectedDate();
    		(window[this.callfunction_onselection]|| new Function)(dSelectedDate,dSelectedDate.getFullYear(),dSelectedDate.getMonth()+1,dSelectedDate.getDate(),dSelectedDate.getDay()+1);
    	}
    }

    function dlcalendar_show() {
    	var eCalendar=this.mGetCalendarElement();
    	if(this.hide_selects) {
    		dlcalendar_hideSelects(eCalendar);
    	}
    	eCalendar.style.visibility='inherit';
    }

    function dlcalendar_hide() {
    	var eCalendar=this.mGetCalendarElement();
    	eCalendar.style.visibility='hidden';
    	if(this.hide_selects) {
    		dlcalendar_showSelects(eCalendar);
    	}
    }

    function dlcalendar_dateOnMousedown() { //this==table cell
    	var oCalendar=dlcalendar_getCalendarObject(this.sCalendarId);
    	oCalendar.mOnNewSelection(this.nDayOfMonth);
    }

    function dlcalendar_dateObjectFromString(sDate) {
    	var aDate=(sDate.indexOf("-") !=-1) ? sDate.split('-') : sDate.split(',');
    	return(new Date(aDate[0],aDate[1]-1,aDate[2]));
    }

    function dlcalendar_hideAll() {
    	var aAllCalendars=dlcalendar_aAllCalendars;
    	var nAllCalendars=aAllCalendars.length;
    	var sCalendarId,oCalendar,eCalendar;
    	for(var i=0; i<nAllCalendars; i++) {
    		sCalendarId=dlcalendar_aAllCalendars[i];
    		oCalendar=dlcalendar_getCalendarObject(sCalendarId);
    		eCalendar=oCalendar.mGetCalendarElement();
    		eCalendar.style.visibility="hidden";
    		if(oCalendar.hide_selects) {
    			dlcalendar_showSelects(eCalendar);
    		}
    	}
    }

    function dlcalendar_getElementLeft(eElement) {
    	var nLeftPos=eElement.offsetLeft;
    	var eParElement=eElement.offsetParent;
    	while(eParElement !=null) {
    		if(window.dlcalendar_bIE && (eParElement.tagName !="table") && (eParElement.tagName !="body")) {
    			nLeftPos +=eParElement.clientLeft;
    		}
    		nLeftPos +=eParElement.offsetLeft;
    		eParElement=eParElement.offsetParent;
    	}
    	return nLeftPos;
    }

    function dlcalendar_getElementTop(eElement) {
    	var nTopPos=eElement.offsetTop;
    	var eParElement=eElement.offsetParent;
    	while(eParElement !=null) {
    		if(window.dlcalendar_bIE && (eParElement.tagName !="table") && (eParElement.tagName !="body")) {
    			nTopPos +=eParElement.clientTop;
    		}
    		nTopPos +=eParElement.offsetTop;
    		eParElement=eParElement.offsetParent;
    	}
    	return nTopPos;
    }

    function dlcalendar_hideSelects(eElement) {
    	var nElementLeft=eElement.offsetLeft;
    	var nElementTop=eElement.offsetTop;
    	var nElementRight=(nElementLeft + eElement.offsetWidth);
    	var nElementBottom=(nElementTop + eElement.offsetHeight);
    	var aSelects=document.getElementsByTagName("select");
    	var nSelects=aSelects.length;
    	var eSelect,nSelectLeft,nSelectWidth,nSelectRight,nSelectTop,nSelectHeight,nSelectBottom,bCurrentStyle,bComputedStyle,sVisibility;
    	for(var i=0; i<nSelects; i++) {
    		eSelect=aSelects[i];
    		nSelectLeft=dlcalendar_getElementLeft(eSelect);
    		nSelectWidth=eSelect.offsetWidth;
    		nSelectRight=(nSelectLeft + eSelect.offsetWidth);
    		nSelectTop=dlcalendar_getElementTop(eSelect);
    		nSelectHeight=eSelect.offsetHeight;
    		nSelectBottom=(nSelectTop + eSelect.offsetHeight);
    		if((nSelectLeft >=(nElementLeft - nSelectWidth)) && (nSelectLeft <=nElementRight) && (nSelectTop >=(nElementTop - nSelectHeight)) && (nSelectTop <=nElementBottom)) {
    			bCurrentStyle=(eSelect.currentStyle !=null);
    			bComputedStyle=(document.defaultView !=null && document.defaultView.getComputedStyle !=null);
    			if(bCurrentStyle || bComputedStyle) {
    				sVisibility=(bCurrentStyle ? eSelect.currentStyle.visibility : document.defaultView.getComputedStyle(eSelect,"").getPropertyValue("visibility"));
    			} else {
    				sVisibility=eSelect.style.visibility;
    				if(sVisibility.dlcalendar_mTrim()=="") {
    					sVisibility="inherit";
    				}
    			}
    			eSelect.sPreviousVisibility=sVisibility;
    			eSelect.style.visibility="hidden";
    		}
    	}
    }

    function dlcalendar_showSelects(eElement) {
    	var aSelects=document.getElementsByTagName("select");
    	var nSelects=aSelects.length;
    	var eSelect,sPreviousVisibility;
    	for(var i=0; i<nSelects; i++) {
    		eSelect=aSelects[i];
    		sPreviousVisibility=eSelect.sPreviousVisibility;
    		if(sPreviousVisibility !=null) {
    			eSelect.style.visibility=sPreviousVisibility;
    			eSelect.sPreviousVisibility=null;
    		}
    	}
    }

    function dlcalendar_makeInlineStyle(eElement,sStyle) {
    	if(sStyle !=null && sStyle !="") {
    		if(window.dlcalendar_bIE) {
    			eElement.style.cssText=sStyle;
    		} else {
    			eElement.setAttribute("style",sStyle);
    		}
    	}
    }

    function dlcalendar_validate() {
    	//future use;
    }

    dlcalendar_start();
}) ();
//end
