//--------------------------------// PsCalendar.js
var PsCalendar = {
    // since 2008-01-02
    Name: 'PsCalendar',
    Author: 'Xuxiaowen',
    Version: '1.0.0,',
    browser: (function() {
        var _agt = (navigator == null || navigator.userAgent == null) ? '' : navigator.userAgent.toLowerCase();
        var _app = (navigator == null || navigator.appVersion == null) ? '' : navigator.appVersion;
        var _major = parseInt(_app, 10);
        var tmp = {};
        tmp._opera = _agt.indexOf('opera') != -1;
        tmp._ie = !tmp._opera && (_agt.indexOf('msie') != -1);
        tmp._ieVersionNumber = (function() {
            var msieOffset = _agt.indexOf("msie ");
            if (msieOffset < 0) {
                return 0;
            }
            return parseFloat(_agt.substring(msieOffset + 5, _agt.indexOf(";", msieOffset)));
        })();
        tmp._iemac = tmp._ie && (_agt.indexOf('mac') != -1);
        tmp._safari = _agt.indexOf('safari') != -1;
        tmp._konqueror = _agt.indexOf('konqueror') != -1;
        tmp._mozilla = !tmp._ie && !tmp._opera && !tmp._safari && ((_agt.indexOf('netscape') != -1) || (_agt.indexOf('mozilla') != -1)) && (_major >= 5);
        tmp._gtIE6 = tmp._ie && (tmp._ieVersionNumber < 7);
        return tmp;
    })(),
    cumulativeOffset: function(element) {
        var valueT = 0, valueL = 0;
        do {
            valueT += element.offsetTop || 0;
            valueL += element.offsetLeft || 0;
            element = element.offsetParent;
        }
        while (element);
        return [valueL, valueT];
    },
    hide: function() {
        for (var i = 0; i < arguments.length; i++) {
            var element = $PS(arguments[i]);
            element.style.display = 'none';
        }
    },
    show: function() {
        for (var i = 0; i < arguments.length; i++) {
            var element = $PS(arguments[i]);
            element.style.display = '';
        }
    }
}

function showPsCalendar(options) {
    this.name = 'calendarDiv';//Dom Object Name
    var oThis = this;//To be used in innerFunctions
    this.browserV = PsCalendar.browser._gtIE6;
    this.eventObj = null;
    this.isReady = false;
    this.closingCn = '關閉';
    this.closingEn = 'Close';
    this.clearingCn = "清空";
    this.clearingEn = "Clear";
    this.monthNameCn = new Array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12');
    this.monthNameEn = new Array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12');
    this.weekNameCn = new Array('日', '一', '二', '三', '四', '五', '六');
    this.weekNameEn = new Array('S', 'M', 'T', 'W', 'T', 'F', 'S');
    this.monthNumS = new Array('31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31');
    this.monthNumL = new Array('31', '29', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31');
    this.now = new Date();
    this.curY = this.minY = this.maxY = this.nowY = this.now.getFullYear();
    this.curM = this.minM = this.maxM = this.nowM = this.now.getMonth();
    this.curD = this.minD = this.maxD = this.nowD = this.now.getDate();
    this.setOptions(options ? options : new Object());
    this.initialize();
}

showPsCalendar.prototype = {
    setOptions: function(options) {
        this.options = options;
        if (!this.options.language) 
            this.options.language = 'cn';
        if (!this.options.minDate) {
            this.options.minDate = new Date(this.curY, this.curM, this.curD - (-1));
        }
        if (!this.options.maxDate) {
            this.options.maxDate = new Date(this.curY - (-1), 11, 31);
        }
        if (!this.options.name) {
            this.options.name = 'calendarDiv';
        }
        if (!this.options.mode) {
            this.options.mode = false;
        }
    },
    
    appendZero: function(n) {
        return (('00' + n).substr(('00' + n).length - 2));
    },
    
    switchLan: function(cn, en) {
        return (this.options.language == 'en' ? en : cn);
    },
    
    setDom: function(cn, en) {
        if (!this.isReady) {
            var strFontFamily = this.switchLan('font-family: "宋體" !important;', '');
            var minusYSpan = document.createElement('span');
            minusYSpan.setAttribute('id', this.name + '_MinusY');
            minusYSpan.appendChild(document.createTextNode('  << '));
            minusYSpan.oThis = this;
            var yearSpan = document.createElement('span');
            yearSpan.setAttribute('id', this.name + '_Year');
            yearSpan.style.cssText = 'margin: 0 4px;';
            yearSpan.appendChild(document.createTextNode(this.curY));
            yearSpan.oThis = this;
            var plusYSpan = document.createElement('span');
            plusYSpan.setAttribute('id', this.name + '_PlusY');
            plusYSpan.appendChild(document.createTextNode(' >>'));
            plusYSpan.oThis = this;
            var YearDivSpan = document.createElement('span');//Year float left
            YearDivSpan.className = 'calfl';
            YearDivSpan.appendChild(minusYSpan);
            YearDivSpan.appendChild(yearSpan);
            YearDivSpan.appendChild(plusYSpan);
            var minusMSpan = document.createElement('span');
            minusMSpan.setAttribute('id', this.name + '_MinusM');
            minusMSpan.appendChild(document.createTextNode('< '));
            minusMSpan.oThis = this;
            var monthName = this.switchLan(this.monthNameCn, this.monthNameEn)[this.curM];
            var monthSpan = document.createElement('span');
            monthSpan.setAttribute('id', this.name + '_Month');
            monthSpan.style.cssText = 'margin: 0 4px;';
            monthSpan.appendChild(document.createTextNode(monthName));
            monthSpan.oThis = this;
            var plusMSpan = document.createElement('span');
            plusMSpan.setAttribute('id', this.name + '_PlusM');
            plusMSpan.appendChild(document.createTextNode(' >  '));
            plusMSpan.oThis = this;
            var MonthDivSpan = document.createElement('span');//Month float right
            MonthDivSpan.className = 'calfr';
            MonthDivSpan.appendChild(plusMSpan);
            MonthDivSpan.appendChild(monthSpan);
            MonthDivSpan.appendChild(minusMSpan);
            var YMDiv = document.createElement('div');//Year Month Div
            YMDiv.setAttribute('style', 'height: 22px; font: bold 12px Arial; text-align: center; padding: 4px 4px 0px 4px;');
            YMDiv.style.cssText = 'height: 22px; font: bold 12px Arial; text-align: center; padding: 4px 4px 0px 4px;';
            YMDiv.appendChild(YearDivSpan);
            YMDiv.appendChild(MonthDivSpan);
            var row = document.createElement('tr');
            for (var iWeek = 0; iWeek < 7; iWeek++) {
                var weekName = (this.switchLan(this.weekNameCn, this.weekNameEn))[iWeek];
                var cell = document.createElement('th');
                cell.setAttribute('style', 'background: #F9C605; font: 12px Arial; text-align: center; border: 1px solid #FFCC82;');
                cell.style.cssText = 'background: #F9C605; font: 12px Arial; text-align: center; border: 1px solid #FFCC82;';
                cell.appendChild(document.createTextNode(weekName));
                row.appendChild(cell);
            }
            var calBody = document.createElement('tbody');//calender TBody
            calBody.appendChild(row);
            for (var iRow = 1; iRow <= 6; iRow++) {
                var rowN = document.createElement('tr');
                for (var iCol = 1; iCol <= 7; iCol++) {
                    var cellN = document.createElement('td');
                    cellN.setAttribute('id', this.name + '_' + (7 * (iRow - 1) - (-iCol)));
                    cellN.setAttribute('style', 'padding: 4px; width: 18px; height: 18px;');
                    cellN.style.cssText = 'padding: 4px; width: 18px; height: 18px;';
                    cellN.appendChild(document.createTextNode('&nbsp;'));
                    rowN.appendChild(cellN);
                }
                calBody.appendChild(rowN);
            }
            var calTable = document.createElement('table');//calender Table
            calTable.setAttribute('style', 'clear: both; width: 160px; margin: 0 auto; border-collapse: collapse; border: 1px solid #FFCC82;');
            calTable.style.cssText = 'clear: both; width: 160px; margin: 0 auto; border-collapse: collapse; border: 1px solid #FFCC82;';
            calTable.appendChild(calBody);
            var ClosingDiv = document.createElement('span');//Closing Div
            ClosingDiv.setAttribute('style', 'padding: 0 5px; margin: 0 auto; width: 50px; cursor: pointer; font: 13px Arial; text-align: center;' + strFontFamily);
            ClosingDiv.style.cssText = 'padding: 0 5px; margin: 0 auto; width: 50px; cursor: pointer; font: 13px Arial; text-align: center;' + strFontFamily;
            var closing = this.switchLan(this.closingCn, this.closingEn);
            ClosingDiv.appendChild(document.createTextNode(closing));
            ClosingDiv.oThis = this;
            ClosingDiv.onmouseover = this._over;
            ClosingDiv.onmouseout = this._out;
            ClosingDiv.onclick = this._close;
            var calDiv00 = document.createElement('div');//calender Div
            if (this.browserV) {
                calDiv00.innerHTML = '<iframe class="zIndexIframe" id="' + this.name + '_ifm" frameborder="0"></iframe>';
            }
            var calDiv = document.createElement('div');//calender Div
            calDiv.setAttribute('id', this.name);
            calDiv.setAttribute('style', 'z-index: 999; text-align: center; width: 180px; position: absolute; left: -300px; top: -300px; background: #FFF9F3; border: 1px solid #CACACA; display: none;');
            calDiv.style.cssText = 'z-index: 999; text-align: center; width: 180px; position: absolute; left: -300px; top: -300px; background: #FFF9F3; border: 1px solid #CACACA; display: none;';
            calDiv.appendChild(YMDiv);
            calDiv.appendChild(calTable);
            if (this.mode) {
                var ClearingDiv = document.createElement('span');
                ClearingDiv.setAttribute('style', 'padding: 0 5px; margin: 0 auto; width: 50px; cursor: pointer; font: 13px Arial; text-align: center;' + strFontFamily);
                ClearingDiv.style.cssText = 'padding: 0 5px; margin: 0 auto; width: 50px; cursor: pointer; font: 13px Arial; text-align: center;' + strFontFamily;
                var clearing = this.switchLan(this.clearingCn, this.clearingEn);
                ClearingDiv.appendChild(document.createTextNode(clearing));
                ClearingDiv.oThis = this;
                ClearingDiv.onmouseover = this._over;
                ClearingDiv.onmouseout = this._out;
                ClearingDiv.onclick = this._clearInput;
                calDiv.appendChild(ClearingDiv);
            }
            calDiv.appendChild(ClosingDiv);
            calDiv00.appendChild(calDiv);
            document.body.appendChild(calDiv00);
            this.isReady = true;
        }
        $PS(this.name + '_MinusY').onmouseover = this._over;
        $PS(this.name + '_MinusY').onmouseout = this._out;
        $PS(this.name + '_MinusY').onclick = this._minusYear;
        $PS(this.name + '_Year').onmouseover = this._over;
        $PS(this.name + '_Year').onmouseout = this._out;
        $PS(this.name + '_Year').onclick = this._selectYear;
        $PS(this.name + '_PlusY').onmouseover = this._over;
        $PS(this.name + '_PlusY').onmouseout = this._out;
        $PS(this.name + '_PlusY').onclick = this._plusYear;
        $PS(this.name + '_MinusM').onmouseover = this._over;
        $PS(this.name + '_MinusM').onmouseout = this._out;
        $PS(this.name + '_MinusM').onclick = this._minusMonth;
        $PS(this.name + '_Month').onmouseover = this._over;
        $PS(this.name + '_Month').onmouseout = this._out;
        $PS(this.name + '_Month').onclick = this._selectMonth;
        $PS(this.name + '_PlusM').onmouseover = this._over;
        $PS(this.name + '_PlusM').onmouseout = this._out;
        $PS(this.name + '_PlusM').onclick = this._plusMonth;
    },
    
    initialize: function() {
        this.minY = this.options.minDate.getFullYear();
        this.minM = this.options.minDate.getMonth();
        this.minD = this.options.minDate.getDate();
        this.maxY = this.options.maxDate.getFullYear();
        this.maxM = this.options.maxDate.getMonth();
        this.maxD = this.options.maxDate.getDate();
        //this.setDom();
        //this.create();
        this.name = this.options.name;
        this.mode = this.options.mode;
    },
    
    getDateValue: function(dateNum) {
        this.now.setFullYear(this.curY);
        this.now.setMonth(this.curM);
        this.now.setDate(1);
        var weekday = this.now.getDay();
        return '' + this.curY + '-' + this.appendZero(this.curM - (-1)) + '-' + this.appendZero(dateNum - weekday);
    },
    
    start: function(e) {
        this.eventObj = e;
        var curDateArr = this.eventObj.value.split('-');
        var isDate = true;
        for (var i = 0; i < curDateArr.length; i++) {
            if (isNaN(curDateArr[i])) {
                isDate = false;
                break;
            }
        }
        if (isDate && (curDateArr.length == 3)) {
            this.curY = this.nowY = parseInt(curDateArr[0], 10);
            this.curM = this.nowM = parseInt(curDateArr[1], 10) - 1;
            this.curD = this.nowD = parseInt(curDateArr[2], 10);
        }
        this.setDom();
        this.create();
        var pos = PsCalendar.cumulativeOffset(this.eventObj);
        $PS(this.name).style.left = pos[0] + "px";
        $PS(this.name).style.top = (pos[1] + this.eventObj.offsetHeight) + "px";
        PsCalendar.show($PS(this.name));
        if (this.browserV) {
            $PS(this.name + "_ifm").style.left = pos[0] + "px";
            $PS(this.name + "_ifm").style.top = (pos[1] + this.eventObj.offsetHeight) + "px";
        }
    },
    
    create: function() {
        $PS(this.name + '_Year').innerHTML = this.curY;
        if (this.curY <= this.minY) {
            PsCalendar.hide($PS(this.name + '_MinusY'));
        }
        else {
            PsCalendar.show($PS(this.name + '_MinusY'));
        }
        if (this.curY >= this.maxY) {
            PsCalendar.hide($PS(this.name + '_PlusY'));
        }
        else {
            PsCalendar.show($PS(this.name + '_PlusY'));
        }
        $PS(this.name + '_Year').onclick = this._selectYear;//Add Event
        $PS(this.name + '_Year').className = '';
        var monthName = this.switchLan(this.monthNameCn, this.monthNameEn)[this.curM];
        $PS(this.name + '_Month').innerHTML = monthName;
        if (this.curY < this.minY || (this.curY == this.minY && this.curM <= this.minM)) {
            PsCalendar.hide($PS(this.name + '_MinusM'));
        }
        else {
            PsCalendar.show($PS(this.name + '_MinusM'));
        }
        if (this.curY > this.maxY || (this.curY == this.maxY && this.curM >= this.maxM)) {
            PsCalendar.hide($PS(this.name + '_PlusM'));
        }
        else {
            PsCalendar.show($PS(this.name + '_PlusM'));
        }
        $PS(this.name + '_Month').onclick = this._selectMonth;//Add Event
        $PS(this.name + '_Month').className = '';
        var MonthArray = (0 == this.curY % 4 && (this.curY % 100 != 0 || this.curY % 400 == 0)) ? this.monthNumL : this.monthNumS;
        this.now.setFullYear(this.curY);
        this.now.setMonth(this.curM);
        this.now.setDate(1);
        var weekday = this.now.getDay();
        for (var iDate = 1; iDate <= 42; iDate++) {
            var handleObj = $PS(this.name + '_' + iDate);
            if ((iDate >= (weekday - (-1))) && (iDate <= weekday - (-MonthArray[this.curM]))) {
                var isIllegal = (iDate - weekday < this.minD && this.curM == this.minM && this.curY == this.minY) || (iDate - weekday > this.maxD && this.curM == this.maxM && this.curY == this.maxY) || (this.curM < this.minM && this.curY == this.minY) || (this.curM > this.maxM && this.curY == this.maxY) || this.curY < this.minY || this.curY > this.maxY;
                var isCurrent = (iDate - weekday == this.nowD) && (this.curM == this.nowM) &&
                (this.curY == this.nowY);
                if (isIllegal) {
                    this._illegal(handleObj);
                }
                else if (isCurrent) {
                    handleObj.style.backgroundColor = '#F37021';
                    this._current(handleObj);
                }
                else {
                    this._normal(handleObj);
                }
                handleObj.innerHTML = iDate - weekday;
                handleObj.onmouseover = isIllegal ? null : this._over;
                handleObj.onmouseout = isIllegal ? null : this._out;
                handleObj.onclick = isIllegal ? null : this._click;
            }
            else {
                this._illegal(handleObj);
                handleObj.innerHTML = '&nbsp;';
                handleObj.onmouseover = null;
                handleObj.onmouseout = null;
                handleObj.onclick = null;
            }
            handleObj.oThis = this;
        }
        //hide useless rows
        for (var iDate = 1; iDate <= 42; iDate += 7) {
            var tRow = $PS(this.name + '_' + iDate).parentNode;
            if ($PS(this.name + '_' + iDate).innerHTML == "&nbsp;" && $PS(this.name + '_' + (iDate + 6)).innerHTML == "&nbsp;") {
                PsCalendar.hide(tRow);
            }
            else {
                PsCalendar.show(tRow);
            }
        }
    },
    
    _normal: function(obj) {
        obj.setAttribute('style', 'background: #FFF9F3; font: 12px Arial; color: #333333; text-align: center; text-decoration: none; border: 1px solid #FFCC82; cursor: pointer;');
        obj.style.cssText = 'background: #FFF9F3; font: 12px Arial; color: #333333; text-align: center; text-decoration: none; border: 1px solid #FFCC82; cursor: pointer;';
    },
    
    _illegal: function(obj) {
        obj.setAttribute('style', 'background: #FFF9F3; font: 12px Arial; color: #ABABAB; text-align: center; text-decoration: none; border: 1px solid #FFCC82; cursor: default;');
        obj.style.cssText = 'background: #FFF9F3; font: 12px Arial; color: #ABABAB; text-align: center; text-decoration: none; border: 1px solid #FFCC82; cursor: default;';
    },
    
    _current: function(obj) {
        obj.setAttribute('style', 'background: #F37021; font:bold 12px Arial; color: #333333; text-align: center; text-decoration: none; border: 1px solid #FFCC82; cursor: pointer;');
        obj.style.cssText = 'background: #F37021; font:bold 12px Arial; color: #333333; text-align: center; text-decoration: none; border: 1px solid #FFCC82; cursor: pointer;';
    },
    
    _over: function(e) {
        this.className = 'hover';
    },
    
    _out: function(e) {
        this.className = '';
    },
    
    _minusYear: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        if (oThis.curY > oThis.minY) {
            oThis.curY--;
        }
        oThis.create();
    },
    
    _selectYear: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        if ($PS(oThis.name + '_Month').firstChild.value) {
            oThis.create();//Do month select first
        }
        while (this.childNodes.length > 0) {
            this.removeChild(this.childNodes[0]);
        }
        var selectYear = document.createElement("select");
        selectYear.oThis = oThis;
        selectYear.onblur = oThis._doSelectYear;
        selectYear.onchange = oThis._doSelectYear;
        for (var kYear = oThis.minY; kYear <= oThis.maxY; kYear++) {
            option = document.createElement("option");
            option.appendChild(document.createTextNode(kYear));
            option.value = kYear;
            if (kYear == oThis.curY) 
                option.selected = true;
            selectYear.appendChild(option);
        }
        this.appendChild(selectYear);
        this.onclick = null;//Remove Event
    },
    
    _doSelectYear: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        oThis.curY = this.value;
        oThis.create();
    },
    
    _plusYear: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        if (oThis.curY < oThis.maxY) {
            oThis.curY++;
        }
        oThis.create();
    },
    
    _minusMonth: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        if (oThis.curY > oThis.minY || (oThis.curY == oThis.minY && oThis.curM > oThis.minM)) {
            oThis.curM--;
            if (oThis.curM < 0) {
                oThis.curM += 12;
                oThis.curY--;
            }
        }
        oThis.create();
    },
    
    _selectMonth: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        if ($PS(oThis.name + '_Year').childNodes[0].value) {
            oThis.create();//Do year select first
        }
        while (this.childNodes.length > 0) {
            this.removeChild(this.childNodes[0]);
        }
        var selectMonth = document.createElement("select");
        selectMonth.oThis = oThis;
        selectMonth.onblur = oThis._doSelectMonth;
        selectMonth.onchange = oThis._doSelectMonth;
        var minM = oThis.curY == oThis.minY ? oThis.minM : 0;
        var maxM = oThis.curY == oThis.maxY ? oThis.maxM : 11;
        for (var kMonth = minM; kMonth <= maxM; kMonth++) {
            var monthName = oThis.switchLan(oThis.monthNameCn, oThis.monthNameEn)[kMonth];
            option = document.createElement("option");
            option.appendChild(document.createTextNode(monthName));
            option.value = kMonth;
            if (kMonth == oThis.curM) 
                option.selected = true;
            selectMonth.appendChild(option);
        }
        this.appendChild(selectMonth);
        this.onclick = null;//Remove Event
    },
    
    _doSelectMonth: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        oThis.curM = this.value;
        oThis.create();
    },
    
    _plusMonth: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        if (oThis.curY < oThis.maxY || (oThis.curY == oThis.maxY && oThis.curM < oThis.maxM)) {
            oThis.curM++;
            if (oThis.curM > 11) {
                oThis.curM -= 12;
                oThis.curY++;
            }
        }
        oThis.create();
    },
    
    _click: function(e) {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        if (oThis.eventObj) 
            oThis.eventObj.value = oThis.getDateValue(this.id.split('_')[1]);
        PsCalendar.hide($PS(oThis.name));
        $PS(oThis.name + '_Year').onclick = oThis._selectYear;//Add Event
        $PS(oThis.name + '_Month').onclick = oThis._selectMonth;//Add Event
    },
    
    _close: function() {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        
        if (oThis.eventObj.getAttribute('hasdefault') == 'true') {
            var valNow = oThis.eventObj.value.replace(/^( )*|( )*$/g, '');
            if (valNow == '' || valNow == oThis.eventObj.title) {
                oThis.eventObj.value = oThis.eventObj.title;
                oThis.eventObj.style.color = '#c2c2c2';
            }
        }
        
        PsCalendar.hide($PS(oThis.name));
    },
    
    _clearInput: function(e) {
        var oThis = this.oThis;
        if (!oThis) 
            return;
        oThis.eventObj.value = "";
        
        if (oThis.eventObj.getAttribute('hasdefault') == 'true') {
            oThis.eventObj.value = oThis.eventObj.title;
            oThis.eventObj.style.color = '#c2c2c2';
        }
        
        PsCalendar.hide(oThis.name);
    }
}

function $PS() {
    var elements = new Array();
    for (var i = 0; i < arguments.length; i++) {
        var element = arguments[i];
        if (typeof element == 'string') 
            element = document.getElementById(element);
        if (arguments.length == 1) 
            return element;
        elements.push(element);
    };
    return elements;
}

