// complete at 2004-02-24 18:03
// 2004-07-30 edit input error
// 2004-08-02 fix setValue error
// 2004-08-19 fix some bug
// 2004-08-19 add onWeekClick event
// 2004-09-01 fix show date bit error
// 2004-09-08 fix show error where it in layout
// 2004-11-08 add property "maxValue, minValue"
// 2004-11-24 fix setValue bug for Clear value
// 2004-11-30 add event onChange
// 2004-12-02 fix property enableEdit
// 2004-12-07 fix input error(允许小键盘数字键)
// 2004-12-13 fix input error(禁止输入时的错误)
// 2004-12-30 fix weekClick
// 2005-01-12 fix input error(不能清空)
// 2005-01-26 fix _inputChange
// 2005-02-24 添加了可以设置周的显示顺序 （如可显示成：日、一、二、三、四、五、六 或 一、二、三、四、五、六、日）
// 2005-02-24 添加节日的显示
// 2005-03-04 添加了拖动功能
// 2005-04-08 fix onChange error
// 2005-08-18 add mehtods disabled and enabled

////////////////////// bopDynCalender /////////////////////////////////////////
//                                                                           //
//  this can run in IE(5.0+) or netscape                                     //
//  Copyright 2004 克莱锐富软件公司 All Rights Reserved                        //
//  Ver 1.0                                                                  //
//                                                                           //
//  Properties:                                                              //
//    in:                                                                    //
//      value, maxValue, minValue                                            //
//      imagesPath                                                           //
//      top, left, width, height, borderWidth, borderColor, borderStyle,     //
//          backColor, inputBackColor, isShow                                //
//      enableSelect, enableEdit, isCreateInput, useMonthCombo, useYearText  //
//    out:                                                                   //
//      value, currYear, currMonth, currDay, currWeek, currWeekList          //
//                                                                           //
//  Methods:                                                                 //
//         init                                                              //
//         getInputHTML                                                      //
//         refresh                                                           //
//         getCalHTML                                                        //
//         setCalHTML                                                        //
//         getDaysHTML                                                       //
//         setDaysHTML                                                       //
//         hide                                                              //
//         show                                                              //
//         setValue                                                          //
//                                                                           //
//  events:                                                                  //
//         onClick, onBlur, onFocus, onWeekClick, onChange                   //
//  for example:                                                             //
//         var datebox = new xbopDynCalendar('datebox','datebox1')           //
//         datebox.width = 120                                               //
//         datebox.height = 20                                               //
//         datebox.init()                                                    //
//         datebox.onClick = function() {                                    //
//             alert (this.value)                                            //
//         }                                                                 //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

//bopDynCalendar.dynCalendar_layers = []
//document.captureEvents(Event.KEYDOWN)
//if (!document.all)
//    document.captureEvents(Event.KEYDOWN)


function bopDynCalendar(objName, id) {
    this.objName = objName
    this.id = id
    this.srcDateObj = null
    this.height = 20
    this.width = 100

    this.language = 'cn' // 'cn', 'en'
    this.borderWidth = 1
    this.borderColor = 'white'
    this.borderStyle = '3d'
    this.backColor = '' //'white'
    this.inputBackColor = 'white'

    //this.delimited = '-'
    this.enableDrag = false
    this.enableFestival = false
    this.enableSelect = true
    this.enableWeek = false
    this.enableEdit = false
    this.isShow = true
    this.value = null
    this.maxValue = null
    this.minValue = null
    this.formatStr = 'yyyy-mm-dd'

    this.imagesPath = 'images/'
    this.currDay = 20
    this.currMonth = 7
    this.currYear = 2004
    this.currWeek = 1
    this.currWeekList = []

    this.weeks = new Array(new Array())
    this.isCreateInput = true

    this.useMonthCombo = true
    this.useYearText = true

    this.offsetX = 1
    this.offsetY = 1

    this._TimerObj = null
    this._disabled = false
    //this._indexNumber    = bopDynCalendar.dynCalendar_layers.length
    //bopDynCalendar.dynCalendar_layers[this._indexNumber] = this

    //this.monthnames = {'en':['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
    //                   'cn':['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']}
    //this.weeknames = {'en':['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
    //                  'cn':['一','二','三','四','五','六','日']}


    this.monthnames = {'en':['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
                       'cn':['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']}
    this.weeknames = {'en':['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
                      'cn':['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']}
                      
                                            
    this.weekOrder = "7123456"

    //公历节日 *表示放假日 #表示较重要的节日(标题栏将显示"祝节日快乐"之类的祝词)
    //格式：每行在引号中放一个节日：起始年(yyyy四位)+月(mm二位)+日(dd二位),共八位表示日期
    //如果起始年不明,请填"0000"
    this.sFestival = []
    
    this._sFestival = new Array(
    //"00000101#元旦",
    //"00000214 情人节",
    //"19100308 妇女节",
    //"19790312 植树节",
    //"19830315 消费者权益日",
    //"19610323 世界气象日",
    //"15640401 愚人节",
    //"19380501#劳动节",
    //"19990502*",
    //"19990503*",
    //"19500504 青年节",
    //"19500601 儿童节",
    //"19210701 建党节",
    //"19970701 香港回归纪念",
    //"19270801 建军节",
    //"19850910 教师节",
    //"19491001#国庆节",
    //"19991002*",
    //"19991003*",
    //"19471024 联合国日",
    //"00001031 万圣节",
    //"18661112 孙中山诞辰",
    //"19991220 澳门回归纪念",
    //"00001225 圣诞节",
    //"18931226 毛泽东诞辰"
    )

    this._getDateString = function (textValue){
       var formatDesc = this.formatStr || 'yyyy-mm-dd'
       formatDesc = formatDesc.toLowerCase()
       var tmpDict = {}
       var tmpIndex = 0
       for (var k=0;k<2;k++ )
       {
         for (var i=tmpIndex;i<formatDesc.length;i++)
         {
           if (formatDesc.charAt(i) != 'y' && formatDesc.charAt(i) != 'm' && formatDesc.charAt(i) != 'd'){
               var tmpList1 = textValue.split(formatDesc.charAt(i))
               tmpDict[formatDesc.charAt(i-1)] = tmpList1[0]
               for (var j=0;j<tmpList1.length-1;j++)
                   tmpList1[j] = tmpList1[j+1]
               tmpList1.length = tmpList1.length - 1
               textValue = tmpList1.join(formatDesc.charAt(i))
               break
           }
         }
         if (k == 1){
            var tmpList1 = formatDesc.split(formatDesc.charAt(i))
            var d = ""
            for (var j=0;j<textValue.length;j++) {
                if (textValue.charAt(j) != "0") {
                    d = textValue.substring(j,textValue.length+1)
                    break
                }
            }
            tmpDict[tmpList1[tmpList1.length-1].charAt(0)] = ''+parseInt(d)
            break
         }
         tmpIndex = i+1
       }
       if (Number(tmpDict['y']) >= 50 && Number(tmpDict['y'])< 100)
          tmpDict['y'] = '' + (Number(tmpDict['y']) + 1900)
       if (Number(tmpDict['y']) < 50)
          tmpDict['y'] = '' + (Number(tmpDict['y']) + 2000)

       var tmpList = [tmpDict['m'], tmpDict['d'], tmpDict['y']]
       return tmpList.join('/')
    }

    this._formatDate = function (srcDate){
       var formatDesc = this.formatStr || 'yyyy-mm-dd'
       formatDesc = formatDesc.toLowerCase()
       if (new Date().constructor != srcDate.constructor)
          return srcDate

       var yearLen = 0
       var monthLen = 0
       var dayLen = 0
       for (var i=0;i<formatDesc.length;i++){
          if (formatDesc.charAt(i) == 'y')
              yearLen++
          if (formatDesc.charAt(i) == 'm')
             monthLen++
          if (formatDesc.charAt(i) == 'd')
             dayLen++
       }

       if (yearLen == 0 || monthLen == 0 || dayLen == 0)
          return srcDate
       var currYear = '' + srcDate.getFullYear()
       var currMonth = '' + (srcDate.getMonth()+1)
       var currDay = '' + srcDate.getDate()

       currYear = currYear.substring(4-yearLen, currYear.length)
       
       while (monthLen > currMonth.length){
          currMonth = '0' + currMonth   
       }
       
       while (dayLen > currDay.length){
          currDay = '0' + currDay   
       }

       formatDesc = formatDesc.replace(formatDesc.substring(formatDesc.indexOf('y'),formatDesc.lastIndexOf('y')+1), currYear)
       formatDesc = formatDesc.replace(formatDesc.substring(formatDesc.indexOf('m'),formatDesc.lastIndexOf('m')+1), currMonth)
       formatDesc = formatDesc.replace(formatDesc.substring(formatDesc.indexOf('d'),formatDesc.lastIndexOf('d')+1), currDay)
       return formatDesc
    }

    this._showCal = function() {
        if (!this.enableSelect)
            return
        this.setCalHTML()
        var o = this._getElById(this.id)
        if (!o)
            return
        o.style.top  = (mousePosY + this.offsetY) + 'px'
        o.style.left = (mousePosX + this.offsetX) + 'px'
        this._setElementPosition (o)
        if (document.all)
           this._hideSelect(o)
        o.style.visibility = 'visible'
        this._TimerObj = setTimeout(this.objName+'._hideCal()', 2000)
    }

    this._hideCal = function() {
        var o = this._getElById(this.id)
        if (!o)
            return
        o.style.visibility = 'hidden'
        if (document.all)
            this._showSelect(o)
    }

    this._adjustDate = function() {
        if (!this.value)
            return
        if (this.maxValue) {
            var tmpD = new Date(Date.parse(this._getDateString(this.maxValue)))
            if (!isNaN(tmpD)) {
                var tmpD1 = new Date(Date.parse(this._getDateString(this.value)))
                if (tmpD1 > tmpD) {
                    this.value = this.maxValue
                    this._parseDate()
                }
            }
        }

        if (this.minValue) {
            var tmpD = new Date(Date.parse(this._getDateString(this.minValue)))
            if (!isNaN(tmpD)) {
                var tmpD1 = new Date(Date.parse(this._getDateString(this.value)))
                if (tmpD1 < tmpD) {
                    this.value = this.minValue
                    this._parseDate()
                }
            }
        }
    }

    this._parseDate = function() {
        this.formatStr = 'yyyy-mm-dd'
        var tmpD
        if (this.value) {
            tmpD = new Date(Date.parse(this._getDateString(this.value)))
            if (isNaN(tmpD)) {
                if (this.srcDateObj)
                    tmpD = this.srcDateObj.value ? new Date(Date.parse(this._getDateString(this.srcDateObj.value))) : null//new Date()
            }
        } else if (this.srcDateObj)
            tmpD = this.srcDateObj.value ? new Date(Date.parse(this._getDateString(this.srcDateObj.value))) : null//new Date()

        if (isNaN(tmpD))
            tmpD = null//new Date()
        this.currMonth = ''
        this.currYear = ''
        this.currDay = ''
        this.currWeek = ''
        this.value = ''
        if (tmpD != null) {
            this.currMonth = tmpD.getMonth()
            this.currYear = tmpD.getFullYear()
            this.currDay = tmpD.getDate()
            this.currWeek = tmpD.getDay(new Date(this.currYear, this.currMonth, 1))
            if (!this.value)
                this.value = this._formatDate(tmpD)
        }
    }

    this._initCal = function() {
        var prevImgHTML, prevLinkHTML, nextImgHTML, nextLinkHTML
        var monthComboOptions, monthCombo, yearText, html

        this._parseDate()
        if (this.value == '') {
            var tmpD = new Date()
            this.currMonth = tmpD.getMonth()
            this.currYear = tmpD.getFullYear()
            this.currDay = tmpD.getDate()
            this.currWeek = tmpD.getDay(new Date(this.currYear, this.currMonth, 1))
            if (!this.value)
                this.value = this._formatDate(tmpD)
        }
        if (this.isCreateInput) {
            if (this._getElById(this.id+'_monthInput').value) {
                this.currMonth = this._getElById(this.id+'_monthInput').value - 1
                if (this.currMonth > 11)
                    this.currMonth = 11
                if (this.currMonth < 0)
                    this.currMonth = 0
            }
            if (this._getElById(this.id+'_dayInput').value)
                this.currDay = this._getElById(this.id+'_dayInput').value - 0
            if (this._getElById(this.id+'_yearInput').value)
                this.currYear = this._getElById(this.id+'_yearInput').value - 0
        }
        prevImgHTML  = '<img src="' + this.imagesPath + 'prev.gif" alt="<<" class="dynCalendar_img1" onmousedown=this.className="dynCalendar_img2" onmouseup=this.className="dynCalendar_img1">'// onClick="event.cancelBubble=true">'
        nextImgHTML  = '<img src="' + this.imagesPath + 'next.gif" alt=">>" class="dynCalendar_img1" onmousedown=this.className="dynCalendar_img2" onmouseup=this.className="dynCalendar_img1">'// onClick="event.cancelBubble=true">'
        prevYearLinkHTML = '<a href="javascript: ' + this.objName + '._setPrevYear()">' + prevImgHTML + '</a>'
        nextYearLinkHTML = '<a href="javascript: ' + this.objName + '._setNextYear()">' + nextImgHTML + '</a>'

        if (this.useMonthCombo) {
            monthComboOptions = ''
            for (i=0; i<12; i++) {
                selected = (i == this.currMonth ? 'selected' : '')
                monthComboOptions += '<option value="' + i + '" ' + selected + '>' + this.monthnames[this.language][i] + '</option>'
            }
            monthCombo = '<select class="dynCalendar_month" name="months"'
            monthCombo += ' ID="' + this.id + '_monthCombo"'
            monthCombo += ' onmouseover="event.cancelBubble=true;clearTimeout('+this.objName+'._TimerObj)"'
            monthCombo += ' onmousemove="event.cancelBubble=true;clearTimeout('+this.objName+'._TimerObj)"'
            monthCombo += ' onmouseout="event.cancelBubble=true;clearTimeout('+this.objName+'._TimerObj)"'
            monthCombo += ' onfocus="event.cancelBubble=true;clearTimeout('+this.objName+'._TimerObj)"'
            monthCombo += ' onblur="event.cancelBubble=true;'+this.objName+'._TimerObj=setTimeout(\''+this.objName+'._hideCal()\', 500);"'
            monthCombo += ' onclick="event.cancelBubble=true;clearTimeout('+this.objName+'._TimerObj)"'
            monthCombo += ' onchange="' + this.objName + '.currMonth=this.selectedIndex;'+this.objName+'.setDaysHTML();">' + monthComboOptions + '</select>'
        } else {
            monthCombo = this.monthnames[this.language][this.currMonth]
        }

        if (this.useYearText) {
            yearText = '<input class="dynCalendar_year" name="years"'
            yearText += ' ID="' + this.id + '_yearText"'
            yearText += ' onKeypress="if (event.keyCode==13)this.onblur();"'
            yearText += ' onkeydown="if (event.keyCode == 13 || event.keyCode == 46 || (event.keyCode>=37 && event.keyCode<=40) || event.keyCode == 9 || (event.keyCode>=48 && event.keyCode<=59) || event.keyCode == 8) {return true;} else return false;"'
            yearText += ' onBlur="if (isNaN(this.value)) this.value='+this.objName+'.currYear;' + this.objName + '.currYear=this.value-0;'+this.objName+'.setDaysHTML();"'
            yearText += ' maxlength=\"4\" value=\"' + this.currYear + '\">';
        }
        else {
            yearText = this.currYear
        }

        html = '<table cellspacing="0" cellpadding="0" style="border:0;align:center;width:100%">';

        html += '<tr><td style="width:10%">' + prevYearLinkHTML + '</td><td style="width:25%" align="center">' + yearText
        html += '</td><td style="width:10%">' + nextYearLinkHTML + '</td><td style="width:45%" align="center">' + monthCombo + '<td style="width:10%">';

        html += '<a href="javascript: ' + this.objName + '._hideCal()">'
        html += '<img src="' + this.imagesPath + 'close.gif" alt="Close" class="dynCalendar_img1" onmousedown=this.className="dynCalendar_img2" onmouseup=this.className="dynCalendar_img1"></a>'
        html += '</td></tr>'
        html += '<tr><td colspan="5" align="center" style="margin:1 0 1 0">'
        html += '<div style="width:100%;"'
        html += ' ID="' + this.id + '_dayDiv">'
        html += this.getDaysHTML()
        html += '</div></td></tr>'
        html += '</table>'
        return html
    }

    this.setCalHTML = function() {
        var o = this._getElById(this.id)
        if (o)
            o.innerHTML = this._initCal()
    }

    this.getCalHTML = function() {
        return this._initCal()
    }

    this._getFestival = function(year, month, day) {
        var arr = []
        for (var i=0;i<this.sFestival.length;i++) {
            if (this.sFestival[i].substring(0,4)-0<=year-0 && this.sFestival[i].substring(4,6) == month && this.sFestival[i].substring(6,8) == day)
                arr[arr.length] = this.sFestival[i].substring(8)
        }
        for (var i=0;i<this._sFestival.length;i++) {
            if (this._sFestival[i].substring(0,4)-0<=year-0 && this._sFestival[i].substring(4,6) == month && this._sFestival[i].substring(6,8) == day)
                arr[arr.length] = this._sFestival[i].substring(8)
        }
        return arr.join(',')
    }

    this._initDays = function (){
        var docStart = '<table cellspacing="0" style="width:100%;"><tr style="background-color:#779191;color:white">'
        var docEnd = '</tr></table>'

        var month,date1, year, numdays, thisMonth, firstOfMonth, numdaysprev
        var ret, row, i, cssClass, linkHTML
        var nextmonth, prevmonth
        var weekHTML = ''
        if (this.enableWeek)
            weekHTML += '<td class="dynCalendar_dayname2">&nbsp;</td>'
        for (i=0;i<7;i++) {
            var idx = this.weekOrder.charAt(i)
            if (i==this.weekOrder.indexOf('7') || i==this.weekOrder.indexOf('6'))
                weekHTML += '<td class="dynCalendar_dayname2">' + this.weeknames[this.language][--idx] + '</td>'
            else
                weekHTML += '<td class="dynCalendar_dayname1">' + this.weeknames[this.language][--idx] + '</td>'
        }
        weekHTML += '</tr><tr>'

        month = this.currMonth
        year  = this.currYear
        date1 = this.currDay

        nextmonth = (month == 11)? 0 : month+1
        prevmonth = (month == 0)? 11 : month-1
        var tmpYear1 = (month == 0)? year-1 : year
        var tmpYear2 = (month == 11)? year+1 : year
        numdays    = this._getDaysInMonth(month, year)
        numdaysprev = this._getDaysInMonth(prevmonth, tmpYear1)
        thisMonth    = new Date(year, month,1)
        firstOfMonth = thisMonth.getDay()-(parseInt(this.weekOrder.charAt(1))-1)
        if (firstOfMonth<=0)
            firstOfMonth = 7 + firstOfMonth
        ret = new Array(new Array())
        this.weeks[0] = []
        for (i=0; i<firstOfMonth; i++){
           this.weeks[0][this.weeks[0].length] = [numdaysprev-firstOfMonth+i+1, prevmonth+1, tmpYear1]
           ret[0][ret[0].length] = '<td class="dynCalendar_dayother">' + (numdaysprev-firstOfMonth+i+1) + '</td>'
        }
        row = 0
        i   = 1
        while (i <= numdays){
             if (ret[row].length == 7){
                ret[++row] = new Array()
                this.weeks[row] = new Array()
             }
             cssClass = (i == date1) ? 'dynCalendar_today' : 'dynCalendar_day'
             if ((ret[row].length == this.weekOrder.indexOf('7') || ret[row].length == this.weekOrder.indexOf('6')) && cssClass != 'dynCalendar_today')
                cssClass = 'dynCalendar_holiday'
             cssClassSelect = 'dynCalendar_dayselect'
             var title = ""
             if (this.enableFestival) {
                 title = this._getFestival(year, Number(month)+1, i)
                 if (title != "") {
                     if (title.charAt(0)=="#")
                         cssClass = 'dynCalendar_festival_vital'
                     else if (title.charAt(0)=="*")
                         cssClass = 'dynCalendar_holiday'
                     else
                         cssClass = 'dynCalendar_festival'
                     title = ' title="' + title.substring(1) + '"'
                 }
             }
             var tmpRowLen = ret[row].length
             ret[row][tmpRowLen] = '<td align="center" style="cursor:hand;cursor:pointer;" onmouseover=this.className="'+ cssClassSelect + '" onmouseout=this.className="' + cssClass + '" class="' + cssClass + '" onClick="'
             ret[row][tmpRowLen] += this.objName + '.currDay='+i+';'+this.objName+'._dayClick('+row+');'
             ret[row][tmpRowLen] += '"' + title
             ret[row][tmpRowLen] += '>' + i + '</td>'
             this.weeks[row][this.weeks[row].length] = [i++, Number(month)+1, year]
        }
        row = 1
        for (i=0;i<6;i++){
            if (ret[i]){
                for (var j=ret[i].length;j<7;j++){
                     ret[i][j] = '<td class="dynCalendar_dayother">' + row + '</td>'
                     this.weeks[i][j] = [row++, Number(nextmonth)+1, tmpYear2]
                }
            }else{
                ret[i] = new Array()
                this.weeks[i] = new Array()
                for (var j=0;j<7;j++){
                     ret[i][j] = '<td class="dynCalendar_dayother">' + row + '</td>'
                     this.weeks[i][j] = [row++, Number(nextmonth)+1, tmpYear2]
                }
            }
        }
        var WS = '<td class="dynCalendar_dayother"><a href="javascript:'+this.objName+'._weekClick($index$)"><img style="border:0px;" src="'+this.imagesPath+'week.gif"></a></td>'
        for (i=0; i<ret.length; i++){
            ret[i] = ret[i].join('\n') + '\n'
            if (this.enableWeek)
                ret[i] = WS.split('$index$').join(i)+'\n'+ret[i]
        }

        var doc = docStart
        doc += weekHTML
        doc += ret.join('</tr>\n<tr>')
        doc += docEnd
        return doc
    }

    this.getDaysHTML = function() {
        return this._initDays()
    }

    this.setDaysHTML = function() {
        var o = this._getElById(this.id+'_dayDiv')
        if (o)
            o.innerHTML = this._initDays()
    }

    this._inputBlur = function(obj) {
        var tp = obj.id.split('_')[obj.id.split('_').length-1]
        switch (tp) {
            case 'yearInput':
                if (obj.readOnly)
                    return
                if (obj.value != '' && isNaN(obj.value))
                    obj.value=this.currYear
                this._inputChange()
                break
            case 'monthInput':
                if (obj.readOnly)
                    return
                if (obj.value != '' && isNaN(obj.value))
                    obj.value=this.currMonth
                if (obj.value-0>12)
                    obj.value = 12
                this._inputChange()
                break
            case 'dayInput':
                if (obj.readOnly)
                    return
                if (obj.value != '' && isNaN(obj.value))
                    obj.value=this.currDay
                this._inputChange()
                break
            default: break
        }
    }

    this._getInputBox = function() {
        this._parseDate()
        this._adjustDate()
        if (this.srcDateObj)
            this.srcDateObj.value = this.value
        var tmpLeft = 0
        var _doc = ''
        if (this.width < 110)
            this.width = 110
        var W = this.width
        var H = this.height
        if (this.isCreateInput) {
            _doc += '    <input id="'+this.id+'_yearInput"'
            _doc += '    style="position:absolute;background-color:'+this.inputBackColor+';\n'
            if (this.borderStyle == '3d')
                _doc += '                  border-top:'+this.borderWidth+'px solid black;border-left:'+this.borderWidth+'px solid black;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            else
                _doc += '                  border-top:'+this.borderWidth+'px solid '+this.borderColor+';border-left:'+this.borderWidth+'px solid '+this.borderColor+';border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            var tmpW = parseInt((W - 95 - (this.enableSelect? H: 0))/3)+30
            _doc += '                  width:'+tmpW+'px;height:'+H+'px;left:0px;top:0px;text-align:center;" maxlength=4'
            if (!this.enableEdit)
                _doc += '    readOnly'
            _doc += '    value="'+this.currYear+'"'
            _doc += ' onfocus="if (!this.readOnly) this.select();"'
            _doc += ' onclick="if (!this.readOnly) this.select();"'
            _doc += ' onblur="'+this.objName+'._inputBlur(this)"' //if (this.value!=\'\' && isNaN(this.value) && this.readOnly) {this.value='+this.objName+'.currYear;this.onchange()}"'
            _doc += ' onkeydown="if (event.keyCode == 46 || event.keyCode == 9 || (event.keyCode>=48 && event.keyCode<=59) || (event.keyCode>=96 && event.keyCode<=105) || event.keyCode == 8) {return true;} else if (event.keyCode == 39 || event.keyCode==13) {document.getElementById(\''+this.id+'_monthInput\').focus();return false;} else return false;"'
            _doc += ' onChange="'+this.objName+'._inputChange()"'
            _doc += '>\n'

            tmpLeft += tmpW
            _doc += '    <div style="cursor:default;position:absolute;overflow:hidden;background-color:'+this.inputBackColor+';\n'
            _doc += '                font-family:Verdana, Arial, Helvetica, Sans-Serif;font-size:13px;\n'
            if (this.borderStyle == '3d')
                _doc += '                border-top:'+this.borderWidth+'px solid black;border-left:0px;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            else
                _doc += '                border-top:'+this.borderWidth+'px solid '+this.borderColor+';border-left:0px;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            if (document.all)
                _doc += '                width:10px;height:'+H+'px;left:'+tmpLeft+'px;top:0px;">-</div>\n'
            else
                _doc += '                width:10px;height:'+(H-(this.borderWidth*2))+'px;left:'+tmpLeft+'px;top:0px;">-</div>\n'

           tmpLeft += 10
            _doc += '    <input id="'+this.id+'_monthInput" style="position:absolute;background-color:'+this.inputBackColor+';\n'
            if (this.borderStyle == '3d')
                _doc += '                border-top:'+this.borderWidth+'px solid black;border-left:0px;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            else
                _doc += '                border-top:'+this.borderWidth+'px solid '+this.borderColor+';border-left:0px;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            tmpW = parseInt((W - 95 - (this.enableSelect? H: 0))/3)+20
            _doc += '                  width:'+tmpW+'px;height:'+H+'px;left:'+tmpLeft+'px;top:0px;text-align:center;" maxlength=2'
            if (!this.enableEdit)
                _doc += '    readOnly'
            _doc += '    value="'
            if (this.currMonth === '')
                _doc += '"'
            else if (this.currMonth-0 < 9)
                _doc += '0'+(this.currMonth+1) + '"'
            else
                _doc += (this.currMonth+1) + '"'
            _doc += ' onfocus="if (!this.readOnly) this.select();"'
            _doc += ' onclick="if (!this.readOnly) this.select();"'
            _doc += ' onblur="'+this.objName+'._inputBlur(this)"' //if (this.readOnly) return; if (this.value!=\'\' && isNaN(this.value)){this.value='+this.objName+'.currMonth;this.onchange();}else if (this.value-0 > 12){this.value=\'12\';this.onchange();}else if (this.value-0<1){this.value=\'01\';this.onchange();}"'
            _doc += ' onkeydown="if (event.keyCode == 46 || event.keyCode == 9 || (event.keyCode>=48 && event.keyCode<=59) || (event.keyCode>=96 && event.keyCode<=105) || event.keyCode == 8) return true; else if (event.keyCode==37){document.getElementById(\''+this.id+'_yearInput\').focus();event.returnValue=0;return false;} else if (event.keyCode==39 || event.keyCode==13){document.getElementById(\''+this.id+'_dayInput\').focus();return false;} else{event.returnValue=false;return false;}"'
            _doc += ' onkeyup="if (event.keyCode == 8 && this.value == \'\') document.getElementById(\''+this.id+'_yearInput\').focus();"'
            _doc += ' onChange="'+this.objName+'._inputChange()"'
            _doc += '>\n'

            tmpLeft += tmpW
            _doc += '    <div style="cursor:default;position:absolute;overflow:hidden;background-color:'+this.inputBackColor+';\n'
            _doc += '                font-family:Verdana, Arial, Helvetica, Sans-Serif;font-size:13px;\n'
            if (this.borderStyle == '3d')
                _doc += '                border-top:'+this.borderWidth+'px solid black;border-left:0px;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            else
                _doc += '                border-top:'+this.borderWidth+'px solid '+this.borderColor+';border-left:0px;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:0px;\n'
            if (document.all)
                _doc += '                width:10px;height:'+H+'px;left:'+tmpLeft+'px;top:0px;">-</div>\n'
            else
                _doc += '                width:10px;height:'+(H-(this.borderWidth*2))+'px;left:'+tmpLeft+'px;top:0px;">-</div>\n'

            tmpLeft += 10
            _doc += '    <input id="'+this.id+'_dayInput" style="position:absolute;background-color:'+this.inputBackColor+';\n'
            if (this.borderStyle == '3d')
                _doc += '                  border-top:'+this.borderWidth+'px solid black;border-left:0px solid black;border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:'+this.borderWidth+'px solid '+this.borderColor+';\n'
            else
                _doc += '                  border-top:'+this.borderWidth+'px solid '+this.borderColor+';border-left:0px solid '+this.borderColor+';border-bottom:'+this.borderWidth+'px solid '+this.borderColor+';border-right:'+this.borderWidth+'px solid '+this.borderColor+';\n'
            tmpW = parseInt((W - 95 - (this.enableSelect? H: 0))/3)+20
            _doc += '                  width:'+tmpW+'px;height:'+H+'px;left:'+tmpLeft+'px;top:0px;text-align:center;" maxlength=2'
            if (!this.enableEdit)
                _doc += '    readOnly'
            _doc += '    value="'
            if (this.currDay === '')
                _doc += '"'
            else if (this.currDay-0 <= 9)
                _doc += '0'+this.currDay + '"'
            else
                _doc += this.currDay + '"'
            _doc += ' onfocus="if (!this.readOnly) this.select();"'
            _doc += ' onclick="if (!this.readOnly) this.select();"'
            _doc += ' onblur="'+this.objName+'._inputBlur(this)"' //if (this.readOnly) return; if (this.value!=\'\' && isNaN(this.value)){this.value='+this.objName+'.currDay;this.onchange();}else if (this.value-0 > 31){this.value=\'31\';this.onchange();}else if (this.value-0<1){this.value=\'01\';this.onchange();}"'
            _doc += ' onkeydown="if (event.keyCode == 46 || event.keyCode == 9 || (event.keyCode>=48 && event.keyCode<=59) || (event.keyCode>=96 && event.keyCode<=105) || event.keyCode == 8) return true; else if (event.keyCode==37){document.getElementById(\''+this.id+'_monthInput\').focus();return false;} else return false;"'
            _doc += ' onkeyup="if (event.keyCode == 8 && this.value == \'\') document.getElementById(\''+this.id+'_monthInput\').focus();"'
            _doc += ' onChange="'+this.objName+'._inputChange()"'
            _doc += '>\n'
            tmpLeft += (tmpW + 5 + ((W - 95 - (this.enableSelect? H: 0))%3))
        }
        if (this.enableSelect) {
            _doc += '    <div id="'+this.id+'_selectButton" style="position:absolute; background-color:buttonface;background-position: center;background-repeat: no-repeat;font-size:0px;\n'
            _doc += '                 cursor:pointer;cursor:hand;'
            if (document.all)
                _doc += '                width:'+(H-2)+'px;height:'+(H-2)+'px;border:1px outset white;left:'+tmpLeft+'px;top:1px;background-image:url(\''+this.imagesPath+'dynCalendar.gif\');"\n'
            else
                _doc += '                width:'+(H-4)+'px;height:'+(H-4)+'px;border:1px outset white;left:'+tmpLeft+'px;top:1px;background-image:url(\''+this.imagesPath+'dynCalendar.gif\');"\n'
            _doc += '         onmousedown="this.style.borderStyle=\'inset\';"\n'
            _doc += '         onmouseup="this.style.borderStyle=\'outset\';"\n'
            _doc += '         onmouseout="this.style.borderStyle=\'outset\';"\n'
            _doc += '         onclick="'+this.objName+'._showCal();"'//event.cancelBubble=true;"'
            _doc += '         >\n</div>\n'
        }
        return _doc
    }

    this._initInput = function() {
        if (this.width < 110)
            this.width = 110
        var W = this.width
        var H = this.height
        var _doc =  ''
        _doc += '<div id="'+this.id+'_inputbox" style="border:0px;width:'+W+'px;height:'+H+'px;'
        if (this.backColor)
            _doc += 'background-color:'+this.backColor+';'
        if (typeof this.left != 'undefined' && typeof this.top != 'undefined')
            _doc += 'position:absolute;left:'+this.left+'px;top:'+this.top+'px;'
        else
            _doc += 'position:relative;left:0px;top:0px;'
        if (this.isShow)
            _doc += 'visibility:visible;'
        else
            _doc += 'visibility:hidden;'
        _doc += '">'
        _doc += this._getInputBox()
        _doc += '</div>'
        if (!document.getElementById(this.id)) {
            var _doc1 = '<div class="dynCalendar" id="' + this.id + '"'
            _doc1 += ' onmouseout="'+this.objName+'._TimerObj=setTimeout(\''+this.objName+'._hideCal()\',500)"'
            _doc1 += ' onmousedown="if ('+this.objName+'.enableDrag) bopDraggable.startLayerDrag(\''+this.id+'\')"'
            _doc1 += ' onmouseup="if ('+this.objName+'.enableDrag) bopDraggable.endLayerDrag()"'
            if (document.all)
                _doc1 += ' onmousemove="'+this.objName+'._move()"'
            _doc1 += ' onmouseover="clearTimeout('+this.objName+'._TimerObj)"></div>'
            document.body.insertAdjacentHTML("afterBegin", _doc1)
        }
        return _doc
    }

    this._move = function() {
        if (!this.enableDrag)
            return
        if (bopDraggable.layer) {
            this._showSelect(this._getElById(this.id))
            bopDraggable.onLayerDrag()
            this._hideSelect(this._getElById(this.id))
        }
    }

    this.initInput = function() {
        document.write(this._initInput())
    }

    this.getInputHTML = function() {
        return this._initInput()
    }

    this.setValue = function(v) {
        this.value = v
        if (this.value == "" && this.srcDateObj)
            this.srcDateObj.value = ""
        this.change()
        this.refresh()
    }

    this.init = function() {
        this.initInput()
    }

    this.refreshCal = function() {
        this.setCalHTML()
    }

    this.refresh = function() {
        var o = this._getElById(this.id+'_inputbox')
        if (!o)
            return
        o.style.position = 'relative'
        o.style.backgroundColor = this.backColor
        if (typeof this.left != 'undefined' && typeof this.top != 'undefined') {
            o.style.position = 'absolute'
            o.style.left = this.left + 'px'
            o.style.top = this.top + 'px'
        }
        this._getElById(this.id+'_inputbox').innerHTML = this._getInputBox()
        if (this.srcDateObj)
            this.srcDateObj.value = this.value
        if (this.isShow)
            o.style.visibility = 'visible'
    }

    this.show = function() {
        var o = this._getElById(this.id+'_inputbox')
        if (!o)
            return
        o.style.visibility = 'visible'
        this.isShow = true
    }

    this.hide = function() {
        var o = this._getElById(this.id+'_inputbox')
        if (!o)
            return
        var o1 = this._getElById(this.id)
        if (o1 && o1.visibility != 'hidden')
            o1.style.visibility = 'hidden'
        o.style.visibility = 'hidden'
        this.isShow = false
        this.blur()
    }

    this.onChange = function(){}
    this.change = function() {
        this.onChange()
    }

    this.onBlur = function() {}
    this.blur = function() {
        this.onBlur()
    }

    this.onFocus = function() {}
    this.focus = function() {
        //if (this.srcDateObj)
        //    this.srcDateObj.focus()
        if (this.isCreateInput) {
            var o = this._getElById(this.id+'_yearInput')
            if (o && this.isShow)
                o.focus()
        }
        this.onFocus()
    }

    this._inputChange = function() {
        if (this._getElById(this.id+'_yearInput').value=="" || this._getElById(this.id+'_monthInput').value=="" || this._getElById(this.id+'_dayInput').value=="") {
            this.currYear = ""
            this.currMonth = 0
            this.currDay = 0
            if (this.srcDateObj)
                this.srcDateObj.value = ""
            this.currWeek = ""
            this.currWeekList = []
            var dateString = ""
            var oldValue = this.value
            this.value = dateString
            if (this.value != oldValue)
                this.change()
            return
        }
        this.currYear = this._getElById(this.id+'_yearInput').value-0
        this.currMonth = this._getElById(this.id+'_monthInput').value - 1
        if (this.currMonth < 9)
            this._getElById(this.id+'_monthInput').value = '0'+(this.currMonth+1)
        this.currDay = this._getElById(this.id+'_dayInput').value-0
        var dd = this._getDaysInMonth(this.currMonth, this.currYear)
        if (this.currDay<=0)
            this.currDay = 1
        if (this.currDay>dd)
            this.currDay = dd
        if (this.currDay <= 9)
            this._getElById(this.id+'_dayInput').value = '0'+this.currDay

        var dateString = this._formatDate(new Date(this.currYear, this.currMonth, this.currDay))
        var oldValue = this.value
        this.value = dateString
        this._adjustDate()
        dateString = this.value
        if (this.isCreateInput) {
             this._getElById(this.id+'_yearInput').value = this.currYear
             this._getElById(this.id+'_monthInput').value = (this.currMonth>=9)?(this.currMonth + 1): ('0'+(this.currMonth+1))
             this._getElById(this.id+'_dayInput').value = (this.currDay >9)?(this.currDay): ('0'+(this.currDay))
        }

        if (this.srcDateObj)
            this.srcDateObj.value = dateString
        this._initDays()
        this.currWeek = new Date(this.currYear, this.currMonth, this.currDay).getDay()
         for (var i=0;i<this.weeks.length;i++) {
             if (this.weeks[i][this.currWeek][0] == this.currDay) {
                 this.currWeekList = this.weeks[i]
                 break
             }
         }
         if (this.value != oldValue)
             this.change()
    }

    this.onWeekClick = function() {}
    this._weekClick = function(idx) {
        this.currWeekList = this.weeks[idx]
        this.currYear = this.currWeekList[this.weekOrder.indexOf('1')][2]
        this.currMonth = this.currWeekList[this.weekOrder.indexOf('1')][1]-1
        this.currDay = this.currWeekList[this.weekOrder.indexOf('1')][0]
        this._dayClick()
        this.onWeekClick()
    }

    this.onClick = function() {}
    this._dayClick = function() {
         var dateString = this._formatDate(new Date(Date.parse((this.currMonth + 1) + '/' + this.currDay + '/' + this.currYear)))
         var oldValue = this.value
         if (this.srcDateObj)
             oldValue = this.srcDateObj.value
         else if (this.isCreateInput && (this._getElById(this.id+'_yearInput').value == "" || this._getElById(this.id+'_monthInput').value == "" || this._getElById(this.id+'_dayInput').value == ""))
             oldValue = ""
         this.value = dateString
         this._adjustDate()
         dateString = this.value
         this.currWeek = new Date(this.currYear, this.currMonth, this.currDay).getDay()
         for (var i=0;i<this.weeks.length;i++) {
             if (this.weeks[i][this.currWeek][0] == this.currDay) {
                 this.currWeekList = this.weeks[i]
                 break
             }
         }
         this._hideCal()
         if (this.isCreateInput) {
             this._getElById(this.id+'_yearInput').value = this.currYear
             this._getElById(this.id+'_monthInput').value = (this.currMonth>=9)?(this.currMonth + 1): ('0'+(this.currMonth+1))
             this._getElById(this.id+'_dayInput').value = (this.currDay >9)?(this.currDay): ('0'+(this.currDay))
         }
         if (this.srcDateObj)
             this.srcDateObj.value = dateString
         this.onClick()
        if (this.value != oldValue)
             this.change()
    }

    this._setPrevYear = function() {
            var tmpObj = this._getElById(this.id + '_yearText')
            tmpObj.value = this.currYear - 1
            this.currYear = this.currYear - 1
            this.setDaysHTML()
    }

    this._setNextYear = function () {
            var tmpObj = this._getElById(this.id + '_yearText')
            tmpObj.value = this.currYear + 1
            this.currYear = this.currYear + 1
            this.setDaysHTML()
    }

    this._getDaysInMonth = function (month, year) {
        monthdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        if (month != 1) {
            return monthdays[month];
        } else {
            return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? 29 : 28);
        }
    }

    this._getElById = function (elementId) {
        var layerID = elementId
        if (document.getElementById) {
            return document.getElementById(layerID);
        } else if (document.all) {
            return document.all(layerID)
        }
    }

    this._setElementPosition = function (elm){
        var currWinWidth, currWinHeight
        var selfWidth, selfHeight, selfLeft, selfTop

        if (document.body && document.body.clientWidth)
          currWinWidth = document.body.clientWidth + document.body.scrollLeft
        else
          currWinWidth = window.innerWidth

        if (document.body && document.body.clientHeight)
          currWinHeight = document.body.clientHeight + document.body.scrollTop
        else
          currWinHeight = window.innerHeight

        selfWidth = elm.offsetWidth 
        selfHeight = elm.offsetHeight
        if (document.all){
          selfLeft = Number(elm.style.left.split('px')[0])
          selfTop = Number(elm.style.top.split('px')[0])
        }else{
          selfLeft = elm.offsetLeft
          selfTop = elm.offsetTop
          var o = elm
          while (o.offsetParent!=null) { 
                oParent = o.offsetParent
                selfLeft += oParent.offsetLeft
                selfTop += oParent.offsetTop
                o = oParent
          }
        }

        if (selfLeft + selfWidth > currWinWidth){
          if (selfWidth > currWinWidth)
             elm.style.left = 1 + 'px'
          else if (selfLeft > selfWidth || selfLeft > currWinWidth - selfLeft)
             elm.style.left = (selfLeft - selfWidth) + 'px'
        }

        if (selfTop + selfHeight > currWinHeight){
          if (selfTop > selfHeight || selfTop > currWinHeight - selfTop)
             elm.style.top = (selfTop - selfHeight) + 'px'
        }
    }

    this._hiddenselect_ = {}
    this._hideSelect = function(divObj){
        if (!this._hiddenselect_[divObj])
            this._hiddenselect_[divObj] = []
        var selects = document.getElementsByTagName("SELECT")
        for (var i=0;i<selects.length;i++){
            var o = selects[i]
            var oLeft = o.offsetLeft
            var oTop = o.offsetTop
            while(o.offsetParent!=null) { 
                oParent = o.offsetParent 
                oLeft += oParent.offsetLeft
                oTop += oParent.offsetTop
                o = oParent
            }

            var divLeft = Number(divObj.style.left.split('px')[0])
            var divTop = Number(divObj.style.top.split('px')[0])
            if (this._isOverLap(oLeft,divLeft,oTop,divTop,oLeft+selects[i].clientWidth,divLeft+divObj.clientWidth,oTop+selects[i].clientHeight,divTop+divObj.clientHeight)) {
                if (this._elmIsHidden(selects[i], divObj)) {
                       selects[i].style.visibility = 'hidden'
                       this._hiddenselect_[divObj][this._hiddenselect_[divObj].length] = selects[i]
                }
            }
        }
    }

    this._elmIsHidden = function (selectObj, divObj){
       var divObj = divObj || new Object()
       var parentObj = selectObj
       while (parentObj)
       {
           if (parentObj == divObj || (parentObj.style.visibility && parentObj.style.visibility == 'hidden'))
               return false
           parentObj = parentObj.parentElement
       }
       return true
    }

    this._showSelect = function(divObj){
        var selectList = this._hiddenselect_[divObj]
        this._hiddenselect_[divObj] = []
        if (!selectList || !selectList.length)
            return
        for (var i=0;i<selectList.length;i++) {
           selectList[i].style.visibility = ''
        }
    }

    this._isOverLap = function(leftS,leftD,topS,topD,rightS,rightD,bottomS,bottomD){
        if (leftS > leftD && leftS < rightD)
            if (bottomS > topD && topS < bottomD)
                return true
        if (leftS < leftD && rightS > leftD)
            if (bottomS > topD && topS < bottomD)
                return true
        if (bottomS > topD && topS < bottomD)
            if (leftS > leftD && leftS < rightD)
                return true
        return false
    }
    this.disabled = function() {
        if (this._disabled)
            return
        this._disabled = true
        this._enabledEdit = this.enableEdit
        this.enableEdit = false
        this._enableSelect = this.enableSelect
        this.enableSelect = false
        this._inputBackColor = this.inputBackColor
        this.inputBackColor = '#d4d0c8'
        this.refresh()
        var elm = document.getElementById(this.id+'_selectButton')
        elm.style.visibility = 'hidden'
    }

    this.enabled = function() {
        if (!this._disabled)
            return
        this._disabled = false
        this.enableEdit = this._enabledEdit
        this.enableSelect = this._enableSelect
        if (typeof this._inputBackColor != 'undefined')
            this.inputBackColor = this._inputBackColor
        this.refresh()
        var elm = document.getElementById(this.id+'_selectButton')
        elm.style.visibility = 'visible'
    }
}


mousePosX=0
mousePosY=0
function getMouseXY(e) {
	
	try{
	    if (document.all) {
	        mousePosX = event.clientX + document.body.scrollLeft
	        mousePosY = event.clientY + document.body.scrollTop
	    } else {
	        mousePosX = e.pageX
	        mousePosY = e.pageY
	    }
	}
	catch(e)
	{
	}
}
document.onmousemove = getMouseXY 

