/*
 * Constructor
 */
 var MonthsNames = new Array();
 var aMonthsRussian = new Array( 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь');
 var bMonthsRussian = new Array( 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря');
 var aMonthsEnglish = new Array( 'January', 'February', 'March', 'April', 'May', 'Juny', 'July', 'August', 'September', 'October', 'November', 'December');
 var bMonthsEnglish = new Array( 'January', 'February', 'March', 'April', 'May', 'Juny', 'July', 'August', 'September', 'October', 'November', 'December');
 MonthsNames[1] = new Array(aMonthsRussian,bMonthsRussian);
 MonthsNames[2] = new Array(aMonthsEnglish,bMonthsEnglish);
 
function DateSelector( sName, sValue, sPath, bCalculatePrice)
{
        var oSelf = this

		this.bCalculatePrice = bCalculatePrice
        // Путь к картинкам
        this.sClassPath = sPath

        // Нода из BuildSelector()
        this.oSelector = null

        // Название месяцев
       /* this.aMonths = new Array( 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь')
        this.bMonths = new Array( 'Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря')*/
         this.aMonths = MonthsNames[Lang][0];
		 this.bMonths = MonthsNames[Lang][1];
        // Корневой элемент контрола
        this.oNode = document.createElement('table')
        this.oNode.className = 'DS_Control'

        // Кнопка
        this.oButton = this.oNode.insertRow(-1).insertCell(-1).appendChild( document.createElement('div') )
        this.oButton.parentNode.style.borderLeftWidth = '0'
        this.oButton.appendChild( document.createElement('img') )
        this.oButton.lastChild.src = this.sClassPath + 'calendar.jpg'
        this.oButton.lastChild.className = 'calendar-but'
        this.oButton.onclick = function(oEvent)
        {
                if( !oSelf.oSelector )
                {
                        oSelf.ShowSelector(oSelf.iYear, oSelf.iMonth)
                }
                else
                {
                        oSelf.HideSelector()
                }
                try { event.cancelBubble = true } catch (oException) { oEvent.stopPropagation() }
        }
          // input[@type='text'] в документе
        this.oInput = this.oNode.rows[this.oNode.rows.length-1].insertCell(-1).appendChild( this.CreateElement('input', 'text') )
        this.oInput.parentNode.style.borderRightWidth = '0'
        this.oInput.className = "red-bord" //rsh added
        this.oInput.name = sName
        this.oInput.value = sValue
		this.oInput.readOnly = 1
        this.oInput.onblur = function() { oSelf.ParseStrToValue(oSelf.oInput.value) }
        this.oInput.onclick = function() { oSelf.HideSelector() }
		
		
        // input[@type='hidden'] в документе
        this.oHidden = this.oNode.lastChild.lastChild.lastChild.appendChild( this.CreateElement('input', 'hidden') )
        this.oHidden.name = sName
		this.oHidden.id = sName+'t'
		
		 // input[@type='hidden'] в документе
        this.oHiddenTmsp = this.oNode.lastChild.lastChild.lastChild.appendChild( this.CreateElement('input', 'hidden') )
        this.oHiddenTmsp.name = sName+'tmsp'
		this.oHiddenTmsp.id = sName+'tmsp'
		

        // Автозакрывание селектора
        document.onclick = function() { oSelf.HideSelector() }

        // Текущее значение даты
        this.ParseStrToValue(this.oInput.value)

        this.sClientName = this.GetClientName()

        return this
}

/*
 * Private
 */

// Установить внутренние значения даты
DateSelector.prototype.SetValue = function( iYear, iMonth, iDay )
{
        if(
                ( (iYear > 9 && iYear < 100) || (iYear > 999 && iYear < 10000) ) &&
                ( iMonth > 0 && iMonth < 13 ) &&
                ( iDay <= this.GetDaysCountByMonth(iYear, iMonth) )
        )
        {
                this.iYear = iYear
                this.iMonth = iMonth
                this.iDay = iDay
                this.oInput.value = iDay + ' ' + this.bMonths[iMonth-1] + ' ' + iYear
                this.oHidden.value = iDay + '/' + iMonth + '/' + iYear
				var dDate = new Date(iYear,iMonth,iDay)
				this.oHiddenTmsp.value = dDate.getTime()
        }
        else
        {
                this.oInput.value = this.iDay + ' ' + this.bMonths[this.iMonth-1] + ' ' + this.iYear
                this.oHidden.value = this.iDay + '/' + this.iMonth + '/' + this.iYear
				var dDate = new Date(this.iYear,this.iMonth,this.iDay)
				this.oHiddenTmsp.value = dDate.getTime()
				
        }
		if( this.bCalculatePrice >0 )
		     RecalculatePrice()
}

// Отпарсить строку и попробовать получить три int: iYear, iMonth, iDay
DateSelector.prototype.ParseStrToValue = function( sStr )
{
        var re, aResult
        // '2003-4-16'
        re = /^(\d{2,4})\-(\d{1,2})\-(\d{1,2})$/
        aResult = re.exec(sStr)
        if( aResult )
        {
                this.SetValue( aResult[1], aResult[2], aResult[3] )
                return true
        }

        // '16.4.2003', '16/4/2003', '16 4 2003'
        re = /^(\d{1,2})[\.\/\s](\d{1,2})[\.\/\s](\d{2,4})$/
        aResult = re.exec(sStr)
        if( aResult )
        {
                this.SetValue( aResult[3], aResult[2], aResult[1] )
                return true
        }

        // '16-апр-2003', '16 апр 2003'
        re = /^(\d{1,2})[\s\.\-]([a-я]+)[\s\.\-](\d{2,4})$/i
        aResult = re.exec(sStr)
        if( aResult )
        {
                for( var i=0; i<this.aMonths.length; i++ )
                {
                        var sMonthNormalized = this.aMonths[i].toLowerCase()
                        if( sMonthNormalized.indexOf(aResult[2].toLowerCase()) == 0 )
                        {
                                this.SetValue( aResult[3], i+1, aResult[1] )
                                return true
                        }
                }
        }

        return false
}

// Вернуть количество дней в заданном месяце
DateSelector.prototype.GetDaysCountByMonth = function( iYear, iMonth )
{
        var dDate = new Date(iYear,iMonth,-1)
        return (dDate.getDate() + 1)
}

// Вернуть "правильное" значение месяца, т.е. вместо 13 -- 1 и вместо 0 -- 12
DateSelector.prototype.GetMonthNumber = function( iMonth )
{
        return ( iMonth < 1 || iMonth > 12 ) ? Math.abs( iMonth-12 ) : iMonth
}

// Вернуть "правильное" значение года по месяцу, т.е. вместо 2003(13) -- 2004(1)
DateSelector.prototype.GetYearNumber = function( iYear, iMonth )
{
        if ( iMonth < 1  ) return ( iYear-1 )
        if ( iMonth > 12 ) return ( parseInt(iYear)+1 )
        return iYear
}

// Приделать ноду с Selector к контролу
DateSelector.prototype.ShowSelector = function( iYear, iMonth )
{

        if ( !this.oSelector )
        {
                this.oButton.className = 'Pushed'
                this.oSelector = this.BuildSelector( this.BuildYearMonthSelector(iYear, iMonth), this.BuildDaySelector(iYear, iMonth) )
                this.oNode.parentNode.appendChild( this.oSelector )
        }
}

// Убить ноду с Selector
DateSelector.prototype.HideSelector = function()
{
        if ( this.oSelector && this.oSelector.parentNode )
        {
                this.oButton.className = ''
				if( navigator.userAgent.indexOf('Opera 8') != -1 )
				{
					this.oSelector.innerHTML = '';
                	this.oSelector.parentNode.removeNode(this.oSelector)
				}
				else
				   this.oSelector.parentNode.removeChild(this.oSelector)	
                this.oSelector = null
        }
}

// "Перерисовать" ноду с Selector к контролу
DateSelector.prototype.RedrawSelector = function( iYear, iMonth )
{
        
        this.HideSelector()
        this.ShowSelector(iYear, iMonth)
		event.cancelBubble = true
}

// Сгенерить ноду с выбором даты
DateSelector.prototype.BuildSelector = function( oYearMonthSelector, oDaySelector )
{
        var oNode = document.createElement('div')

        oNode.appendChild( document.createElement('fieldset') )
        oNode.lastChild.appendChild(oYearMonthSelector)
        oNode.lastChild.appendChild(oDaySelector)

        oNode.className = 'DS_Selector'
        // Эта заплатка сделана потому, что Moz и MSIE по-разному трактуют CSS
        oNode.style.width = ( this.sClientName == 'msie' ) ? '1%' : ''

        return oNode
}

// Сгенерить ноду с выбором месяца и года. Текущие значения установить в iYear, iMonth
// Такая замороченная нода получилась coz of moz
DateSelector.prototype.BuildYearMonthSelector = function( iYear, iMonth )
{
        var oCurrentRow, oNode
        var oSelf = this

		var today = new Date();
		curYear = today.getFullYear();
		curMon = today.getMonth()+1;

        oNode = document.createElement('div')
        oNode.className = 'DS_YearmonthSelector'
        oNode.appendChild( document.createElement('table') )
     
        oCurrentRow = oNode.lastChild.insertRow(-1)
		oCurrentRow.insertCell(-1).appendChild( document.createElement('img') )
		
		iPrevMon = iMonth-1
		iPrevYear = iYear
		if(iPrevMon < StartMon )
			{ iPrevYear--; iPrevMon = EndMon; }
		if( (iMonth == StartMon && iYear==curYear) || ( iMonth == StartMon && curYear<iYear && curMon>EndMon) )
		  oCurrentRow.lastChild.lastChild.src = this.sClassPath + 'spacer.gif'
		else
		{
           oCurrentRow.lastChild.lastChild.src = this.sClassPath + 'dateselector_ar-l.gif'
           oCurrentRow.lastChild.lastChild.alt = this.aMonths[ iPrevMon-1 ] + ' ' + this.GetYearNumber(iPrevYear, iPrevMon-1)
           oCurrentRow.lastChild.lastChild.setAttribute('month', this.GetMonthNumber(iPrevMon))
           oCurrentRow.lastChild.lastChild.setAttribute('year', this.GetYearNumber(iPrevYear, iPrevMon))
           oCurrentRow.lastChild.lastChild.onclick = function() { oSelf.RedrawSelector( this.getAttribute('year'), this.getAttribute('month') );}
        }

        oCurrentRow.insertCell(-1).appendChild( document.createTextNode( this.aMonths[iMonth-1] + ' ' + iYear ) )
        oCurrentRow.lastChild.style.textAlign = 'center'

        oCurrentRow.insertCell(-1).appendChild( document.createElement('img') )       
        	
		if( (iMonth == EndMon && iYear==curYear+1) || ( iMonth == EndMon && curYear==iYear && curMon<StartMon) )
		   oCurrentRow.lastChild.lastChild.src = this.sClassPath + 'spacer.gif'
		else
		{   
		    if( iMonth == '09' )
			  iMonth = 9
			iLastMon= parseInt(iMonth)+1
			iLastYear = iYear
			if( iLastMon > EndMon )
				{ iLastYear++; iLastMon = StartMon; }
			oCurrentRow.lastChild.style.textAlign = 'right'
        	oCurrentRow.lastChild.lastChild.src = this.sClassPath + 'dateselector_ar-r.gif'	
        	oCurrentRow.lastChild.lastChild.alt = this.aMonths[ iLastMon-1 ] + ' ' + this.GetYearNumber(iLastYear, iLastMon-1)
        	oCurrentRow.lastChild.lastChild.setAttribute('month', this.GetMonthNumber(parseInt(iLastMon)))
        	oCurrentRow.lastChild.lastChild.setAttribute('year', this.GetYearNumber(iLastYear, parseInt(iLastMon)))
        	oCurrentRow.lastChild.lastChild.onclick = function() { oSelf.RedrawSelector( this.getAttribute('year'), this.getAttribute('month') );}
        }
        return oNode
}

// Сгенерить ноду с выбором дня месяца iMonth года iYear
DateSelector.prototype.BuildDaySelector = function( iYear, iMonth )
{
        var oNode, i, j, oCurrentRow
        var oSelf = this
        var aDayOfWeekTitles = new Array('пн','вт','ср','чт','пт','сб','вс')
        var dFirstDay = new Date(iYear,iMonth-1,0)
        var iDaysCount = this.GetDaysCountByMonth(iYear,iMonth)

        oNode = document.createElement('table')
        oNode.className = 'DS_DaySelector'

        // Нужно отбить позицию до требумого дня недели
        oCurrentRow = oNode.insertRow(-1)

        for ( i=0; i<dFirstDay.getDay(); i++ ) oCurrentRow.insertCell(-1)

        // Собственно числа месяца
        for ( i=0; i<iDaysCount; i++ )
        {
                if ( (i+dFirstDay.getDay())%7 == 0 ) oCurrentRow = oNode.insertRow(-1)
                oCurrentRow.insertCell(-1).appendChild( document.createElement('span') ).appendChild( document.createTextNode(i+1) )

				if( (iMonth == StartMon && i < (StartDay-1)) || ( iMonth == EndMon && i>(EndDay-1) ) )
				    oCurrentRow.lastChild.className = 'DS_Disabled'
				else  
				{
                 oCurrentRow.lastChild.className = ( this.iYear == iYear && this.iMonth == iMonth && this.iDay == i+1 ) ? 'DS_Selected' : ''
                oCurrentRow.lastChild.onclick = function()
                {
                        // Процедура выбора дня
                        oSelf.SetValue( iYear, iMonth, this.lastChild.lastChild.nodeValue )
                        oSelf.HideSelector()
                }
			  }	
        }

        // Заголовок с днями недели
        oNode.createTHead().insertRow(0)
        for ( i=0; i<aDayOfWeekTitles.length; i++ )
        {
                oNode.tHead.rows[0].insertCell(i).appendChild( document.createTextNode(aDayOfWeekTitles[i]) )
        }

        return oNode
}

// Определение типа клиекта. Блин, не хотел я этого делать, но пришлось...
// Возвращает: msie|opera|mozilla
DateSelector.prototype.GetClientName = function()
{
        // Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) Opera 7.10 [en] 
        if( navigator.userAgent.indexOf('Opera') != -1 ) return 'opera'

        // Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3) Gecko/20030312
        if( navigator.userAgent.indexOf('Gecko') != -1 ) return 'mozilla'

        // Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705) 
        if( navigator.userAgent.indexOf('MSIE') != -1 ) return 'msie'
}

// Надо бы передеать createElement ...
// TODO: посмотреть такую функциональность на других браузерах
DateSelector.prototype.CreateElement = function( sNodeName, sTypeAttr )
{
        if( this.sClientName == 'msie' )
        {
                return document.createElement('<'+sNodeName+' type="'+sTypeAttr+'"/>')
        }
        else
        {
                var oElement = document.createElement(sNodeName)
                oElement.setAttribute('type', sTypeAttr)
                return oElement
        }
}
