// *********************************** Calendar ***********************************
// путь к картинкам
var imagesFolder = '/i/calendar/';

// язык интерфейса
var tasksLanguage = 'ru'


// имена месяцев и т.п.
var calendarNamesHash = new Array();
calendarNamesHash.ru = new Array();
calendarNamesHash.en = new Array();
calendarNamesHash.ru.month = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
calendarNamesHash.ru.monthShort = ['янв', 'фев', 'мар', 'апр', 'мая', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
calendarNamesHash.ru.weekday = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
calendarNamesHash.ru.today= 'сегодня';

calendarNamesHash.en.month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
calendarNamesHash.en.monthShort = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
calendarNamesHash.en.weekday = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
calendarNamesHash.en.today= 'today';
var calendarNames = calendarNamesHash[tasksLanguage=='en'?'en':'ru'];



// интерфейсные функции
var closeCalendarTimeOut = 0;
var activeCalendarName = '';


// получить текущую дату календаря
function getCalendarDate(name) {
    if (!LSCalendars[name].GetDate()) { return (new Date()); }
    else { return LSCalendars[name].GetDate(); }

//    return LSCalendars[name].GetDate();
}


// переопределить дату календаря и на выводе
function setDateForCalendar(dayToSet, monthToSet, yearToSet) {
    // что бы сохранить минуты, мы делаем так
    if (!LSCalendars[activeCalendarName].GetDate()) { var dateToSet = new Date(); }
    else { var dateToSet = LSCalendars[activeCalendarName].GetDate(); }

    dateToSet.setFullYear(yearToSet);
    dateToSet.setMonth(monthToSet,1);
    dateToSet.setDate(dayToSet);

    LSCalendars[activeCalendarName].SetDate(dateToSet);
    setInputByLSCalendar(activeCalendarName);
    
    // закрываем календарь
    hideCalendar();
}



// переопределить дату календаря из строки
function setCalendarDateByStr(name, strDate) {
    if (strDate==null || strDate=="") { // если пустая строка
        LSCalendars[name].SetDate(null);
    } 
    else {
        MyCal=new LSCalendar();
        if (!MyCal.Validate(strDate)) {
            alert("Неверный формат даты - "+strDate);
            return false;
        }
        else {
            LSCalendars[name].SetDate(strDate);
            setInputByLSCalendar(name);
            return true;
        }
    }
    closeCalendarTimeOut = 0; // важно
}


// синхронизирует текущее значение календаря и форму ввода
function setInputByLSCalendar(name) {
    document.getElementsByName(name)[0].value=LSCalendars[name].GetStrDate();
    return true;
}


// задать сегодняшнюю дату для значений календаря
function setTodayFromCalendar() {
    var date=new Date();
    setDateForCalendar(date.getDate(),date.getMonth(),date.getFullYear());
}



// вычислить элементы select и div под слоем и скрыть или показать
function ChangeElVis(MyVisibility) {
    var calLeer = document.getElementById('candarLeer');
    
    if ((MyVisibility=='hide') || (MyVisibility=='hidden')) { MyVisibility='hidden'; }
    else { MyVisibility='visible'; }
    
    // вычисляем где именно должен быть этот календарь.
    var calPosition = new getElementPosition(calLeer);
    
    CalTop=calPosition.y;
//    CalLeft=Math.round(calPosition.x-calLeer.offsetWidth/3*2);
    CalLeft=calPosition.x;
    CalBottom=CalTop+calLeer.clientHeight;
    CalRight=CalLeft+calLeer.clientWidth;
//    alert(CalTop+"x"+CalLeft+"x"+CalBottom+"x"+CalRight); 


    // select
    for (var i=0; i<document.getElementsByTagName("select").length; i++) {
        Cu=document.getElementsByTagName("select")(i);
        if (Cu.name=='calMonth') { continue; } // calMonth - селект выбора месяца в календаре

        // координаты углов объекта
        var CuPosition=new getElementPosition(Cu);
        CuTop=CuPosition.y;
        CuLeft=CuPosition.x;
        CuBottom=CuTop+Cu.clientHeight;
        CuRight=CuLeft+Cu.clientWidth;
//        alert(CuTop+"x"+CuLeft+"x"+CuBottom+"x"+CuRight); 

        if ((CuLeft<=CalLeft)&&(CuRight>=CalLeft)||
            (CuLeft>=CalLeft)&&(CuRight<=CalRight)||
            (CuLeft<=CalRight)&&(CuRight>=CalRight)) {

            if ((CuTop<=CalTop)&&(CuBottom>=CalTop)||
                (CuTop>=CalTop)&&(CuBottom<=CalBottom)||
                (CuTop<=CalBottom)&&(CuBottom>=CalBottom)) {
                Cu.style.visibility = MyVisibility;
            }
        }
    }


    // iframe
    for (var i=0; i<document.getElementsByTagName("iframe").length; i++) {
        Cu=document.getElementsByTagName("iframe")(i);

        // координаты углов объекта
        var CuPosition=new getElementPosition(Cu);
        CuTop=CuPosition.y;
        CuLeft=CuPosition.x;
        CuBottom=CuTop+Cu.clientHeight;
        CuRight=CuLeft+Cu.clientWidth;
//        alert(CuTop+"x"+CuLeft+"x"+CuBottom+"x"+CuRight); 

        if ((CuLeft<=CalLeft)&&(CuRight>=CalLeft)||
            (CuLeft>=CalLeft)&&(CuRight<=CalRight)||
            (CuLeft<=CalRight)&&(CuRight>=CalRight)) {

            if ((CuTop<=CalTop)&&(CuBottom>=CalTop)||
                (CuTop>=CalTop)&&(CuBottom<=CalBottom)||
                (CuTop<=CalBottom)&&(CuBottom>=CalBottom)) {
                Cu.style.visibility = MyVisibility;
            }
        }
    }

    return true;
}


function showCalendarForElement(elemName, evt, defaultDate) {
    var calPtr = document.getElementById(elemName + 'Ptr');
    if (calPtr) {
        // показывает календарь в слое (создает слой, если необходимо)
        var calLeer = document.getElementById('candarLeer');
        if (!calLeer) {
            calLeer = document.createElement('div');
            calLeer.id = 'candarLeer';
            document.getElementsByTagName('body')[0].appendChild(calLeer);
        }
        
        // проверяем показан ли слой, если да - скрываем
        if (calLeer.style.visibility=='visible' && activeCalendarName==elemName) {
            calLeer.style.visibility = 'hidden';
            ChangeElVis('visible');
        }
        else {
            activeCalendarName = elemName;
            // скрываем слой
            calLeer.style.visibility = 'hidden';
            // вычисляем где именно должен быть этот календарь.
            var calPosition = new getElementPosition(calPtr);
            // заполняем нужным кодом...
            // смотрим какая дата нас интересует
            var currDate = getCalendarDate(elemName);


            // дата по умолчанию, применяется если по умолчанию сеголня
            CDate=currDate.getDate()+"-"+currDate.getMonth()+"-"+currDate.getFullYear();
            TDate=(new Date()).getDate()+"-"+(new Date()).getMonth()+"-"+(new Date()).getFullYear();
            if (CDate==TDate) {
                if (typeof(defaultDate)=="object" && defaultDate) { currDate=defaultDate; }
            }
            
                        
            // собственно вызываем код
            calLeer.innerHTML = calendarHTML(currDate.getMonth(), currDate.getFullYear(), currDate);
            // ставим слой на место
            calLeer.style.left = calPosition.x;
//			calLeer.style.left = getElementByName(elemName)[0].offsetWidth;
//            calLeer.style.left = calPosition.x - calLeer.offsetWidth/3*2;
            calLeer.style.top = calPosition.y;

            // показываем календарик
            calLeer.style.visibility = 'visible';
            ChangeElVis('hidden');

            // наконец, прекращаем баблинг (может, кто-то открыл без event'а)
            if (evt) { evt.cancelBubble = true; }
            
            // и ставим свой обработчик на клик на календаре (чтобы не скрывался)
            addEvent(calLeer, 'click', calendarClick);
            // и на mouseout (чтобы скрывался, но через некоторое время ;-)
            addEvent(calLeer, 'mouseover', calendarMouseOver);
            addEvent(calLeer, 'mouseout', calendarMouseOut);
        }
    }
}


function calendarClick(e) {
    evt = (e)? e : window.event;
    evt.cancelBubble = true;
}


function calendarMouseOver(e) {
    if (closeCalendarTimeOut) {
        clearTimeout(closeCalendarTimeOut);
        closeCalendarTimeOut = 0;
    }
}


function calendarMouseOut(e) {
    if (closeCalendarTimeOut) {
        clearTimeout(closeCalendarTimeOut);
    }
//    closeCalendarTimeOut = setTimeout('hideCalendar()', 5000);
}


function hideCalendar() {
    var calLeer = document.getElementById('candarLeer');
    if (calLeer) {
        ChangeElVis('show');
        calLeer.style.visibility = 'hidden';
    }
    closeCalendarTimeOut = 0;
}


function switchMonthTo(month, year) {
    var calLeer = document.getElementById('candarLeer');
    if (calLeer) {
        // заполняем нужным кодом...
        // смотрим какая дата нас интересует
        var currDate = getCalendarDate(activeCalendarName);
        // собственно вызываем код
        calLeer.innerHTML = calendarHTML(month, year, currDate);
    }
}


function calendarHTML(month, year, currDate) {
    // смотрим этот ли месяц показываем
    var isThisMonth = (currDate)? (currDate.getMonth() == month && currDate.getFullYear() == year) : false;

    // генерирует html-код для указанного месяца
    // устанавливаем месяц, который будем рисовать
    var drawMonth = new Date();
    drawMonth.setMonth(month, 1);
    drawMonth.setYear(year);
    drawMonth.setDate(1);
    
    // переменные для кнопок навигации по месяцам/годам
    var thisMonth = drawMonth.getMonth();
    var nextMonth = (thisMonth == 11)? 0 : thisMonth + 1;
    var prevMonth = (thisMonth == 0)? 11 : thisMonth - 1;
    
    var thisYear = drawMonth.getFullYear();
    var nextYear = thisYear + 1;
    var prevYear = thisYear - 1;
    var nextMonthYear = (thisMonth == 11)? thisYear + 1 : thisYear;
    var prevMonthYear = (thisMonth == 0)? thisYear - 1 : thisYear;
    
    
    // запихиваем в строку весь код - открываем таблицы...
    // #D7D7D7
    var calendarCode = '<table border="0" cellspacing="0" cellpadding="0" style="border: 1px solid #D7D7D7;">';
    calendarCode += '<tr><td class="purpleCell"><table cellpadding="0" cellspacing="3" border="0" width="100%">';
    // здесь указываем клик на прошлый год
    calendarCode += '<tr><td><img src="' + imagesFolder + 'arr-prev.gif" width="15" height="16" border="0" onClick="switchMonthTo(' + thisMonth + ', ' + prevYear + ')" style="cursor: pointer; cursor: hand;" /><\/td>';
    // текущий (показываемый) год
    calendarCode += '<td align="center" class="purpleCell">' + thisYear + '<\/td>';
    // клик на следующий год
    calendarCode += '<td align="right"><img src="' + imagesFolder + 'arr-next.gif" width="15" height="16" border="0" onClick="switchMonthTo(' + thisMonth + ', ' + nextYear + ')" style="cursor: pointer; cursor: hand;" /><\/td><\/tr>';
    // клик на предыдущий месяц
    calendarCode += '<tr><td><img src="' + imagesFolder + 'arr-prev.gif" width="15" height="16" border="0" onClick="switchMonthTo(' + prevMonth + ', ' + prevMonthYear + ')" style="cursor: pointer; cursor: hand;" /><\/td>';
    // текущий месяц
    calendarCode += '<td align="center" class="purpleCell">' + calendarNames.month[thisMonth] + '<\/td>';
    // клик на следующий месяц
    calendarCode += '<td align="right"><img src="' + imagesFolder + 'arr-next.gif" width="15" height="16" border="0" onClick="switchMonthTo(' + nextMonth + ', ' + nextMonthYear + ')" style="cursor: pointer; cursor: hand;" /><\/td><\/tr>';
    calendarCode += '<\/table><\/td><\/tr>';


    // начинаем таблицу самого месяца #D7D7D7
    calendarCode += '<tr><td style="border-top: 1px solid #D7D7D7;" bgcolor="#ffffff"><table cellpadding="0" cellspacing="0" border="0" width="100%" style="border-bottom: 1px solid #D7D7D7;"><tr>';
    calendarCode += '<td class="whiteCell"><br /><\/td><td class="whiteCell"><br /><\/td>';
    for (var i = 0; i < calendarNames.weekday.length; i++) {
        var styleClass = (i < calendarNames.weekday.length - 1)? 'whiteCell' : 'sundayCell';
        calendarCode += '<td class="weekDay" align="right">' + calendarNames.weekday[i] + '<\/td>';
    }
    calendarCode += '<td class="whiteCell"><br /><\/td><td class="whiteCell"><br /><\/td><\/tr>';

    // сам месяц
    calendarCode += '<tr><td class="whiteCell"><br /><\/td><td class="whiteCell"><br /><\/td>';
    // рисуем пустые ячейки если нужно...
    var daysToStart = (drawMonth.getDay() == 0)? 7 : drawMonth.getDay();
    for (var i = 0; i < daysToStart - 1; i++) calendarCode += '<td class="whiteCell"><br /><\/td>';

    // собственно циферки
    for (var i = 1; i < 33; i++) {
        drawMonth.setDate(i);
        if (isThisMonth && i == currDate.getDate()) {
            calendarCode += '<td class="blackCell" align="right" onClick="setDateForCalendar(' + i + ', ' + month + ', ' + year + ');" style="cursor: pointer; cursor: hand;">' + i + '<\/td>'
        }
        else {
            if (drawMonth.getMonth() == thisMonth) {
                var styleClass = (drawMonth.getDay() == 0)? 'sundayCell' : 'whiteCell'
                calendarCode += '<td class="' + styleClass + '" align="right" onMouseOver="this.className = \'overCell\';" onMouseOut="this.className = \'' + styleClass + '\';" onClick="setDateForCalendar(' + i + ', ' + month + ', ' + year + ');" style="cursor: pointer; cursor: hand;">' + i + '<\/td>';
            }
            else {
                break;
            }
        }
        if (drawMonth.getDay() == 0) calendarCode += '<td class="whiteCell"><br /><\/td><td class="whiteCell"><br /><\/td><\/tr><tr><td class="whiteCell"><br /><\/td><td class="whiteCell"><br /><\/td>';
    }

    // опять рисуем пустые ячейки
    if (drawMonth.getDay() != 1) {
        var daysToEnd = 8 - ((drawMonth.getDay() == 0)? 7 : drawMonth.getDay());
        for (var i = 0; i < daysToEnd; i++) calendarCode += '<td class="whiteCell"><br /><\/td>';
    }
    calendarCode += '<td class="whiteCell"><br /><\/td><td class="whiteCell"><br /><\/td><\/tr><\/table><\/td><\/tr>';
    // ссылка на сегодня
    calendarCode += '<tr><td class="whiteCell" onMouseOver="this.className = \'overCell\';" onMouseOut="this.className = \'whiteCell\';" style="padding: 6px; cursor: pointer; cursor: hand;" align="center" onClick="setTodayFromCalendar();">'+calendarNames.today+'<\/td><\/tr>';
    // конец

    calendarCode += '<\/table>';


    return calendarCode;
}




function getElementPosition(elemPtr) {
    var posX = elemPtr.offsetLeft;
    var posY = elemPtr.offsetTop;

    while (elemPtr.offsetParent != null) {
        elemPtr = elemPtr.offsetParent;
        posX += elemPtr.offsetLeft;
        posY += elemPtr.offsetTop;
    }
    this.x = posX;
    this.y = posY;
    
    return this;
}



function addEvent(Obj, eventType, eventFunc) {
    if (Obj.addEventListener) { Obj.addEventListener(eventType, eventFunc, false); }
    else if (Obj.attachEvent) { Obj.attachEvent('on'+eventType, eventFunc); }
    else {
        // что делать если ни то ни другое не поддерживается
    }
}

addEvent(document, 'click', hideCalendar);
addEvent(window, 'resize', hideCalendar);
// *********************************** Calendar ***********************************


// *********************************** LSCalendar ***********************************
/*
Конструктор класса

MyCal=new LSCalendar();
MyCal.SetDate((new Date));

MyCal2=new LSCalendar();
MyCal2.SetDate("05-10-2003");

alert(MyCal.GetStrDate());
alert(MyCal2.GetStrDate());
*/
function LSCalendar() {
    // члены
    this.date=null;
    this.format='dd-mm-yyyy';
    
    // методы
    this.SetDate=_SetDate;
    this.GetStrDate=_GetStrDate;
    this.GetDate=_GetDate;
    this.Str2Date=_Str2Date;
    this.zeroFill=_zeroFill;
    this.Validate=_Validate;
    this.SetFormat=_SetFormat;
    
    return true;
}



// Date - текст или объект Date
function _SetDate(Date) {
    if (Date==null || Date=="") { this.date=null; }
    else if (typeof(Date)=="object") { this.date=Date; }
    else { this.date=this.Str2Date(Date)?this.Str2Date(Date):(new Date()); }

    return true;
}



// Получить текущую дату, объект Date
function _GetDate() {
    return this.date;
}


/*
*/
function _zeroFill(value) {
    return (value<10?'0':'')+value;
}



// Получить дату в строковом формате
function _GetStrDate() {
    if (!this.date) {
        return "";
    }
    else {
        var Day=this.zeroFill(this.date.getDate());
        var Month=this.zeroFill(this.date.getMonth()+1);
        var Year=this.date.getFullYear();
        var shortYear=this.date.getYear();
        if (shortYear>=2000) { shortYear-=2000; } // перегибы на местах
        shortYear=this.zeroFill(shortYear);
    
        if (this.format=='dd-mm-yy') { return Day+'-'+Month+'-'+shortYear; }
        else if (this.format=='dd.mm.yy') { return Day+'.'+Month+'.'+shortYear; }
        else if (this.format=='yyyy-mm-dd') { return Year+'-'+Month+'-'+Day; }
        else if (this.format=='yyyy.mm.dd') { return Year+'.'+Month+'.'+Day; }
        else if (this.format=='dd.mm.yyyy') { return Day+'.'+Month+'.'+Year; }
        else { return Day+'-'+Month+'-'+Year; }
    }
}



// маленькая хитрая функция, проверки правильности формата даты
function _Validate(Str) {
    return this.Str2Date(Str)?true:false;
}


// Преобразовать строку в объект Date
function _Str2Date(Str) {
    if (Str) {
        var RegYMDHIS = /^(\d{4})[-|.|\/](\d+)[-|.|\/](\d+)\s+(\d+):(\d+):(\d+)$/i; // yyyy-mm-dd hh:ii:ss
        var RegDMYHIS = /^(\d+)[-|.|\/](\d+)[-|.|\/](\d{4})\s+(\d+):(\d+):(\d+)$/i; // dd-mm-yyyy hh:ii:ss
        var RegYMD = /^(\d{4})[-|.|\/](\d+)[-|.|\/](\d+)$/i; // yyyy-mm-dd
        var RegDMY = /^(\d+)[-|.|\/](\d+)[-|.|\/](\d{4})$/i; // dd-mm-yyyy
        var RegDMY2 = /^(\d+)[-|.|\/](\d+)[-|.|\/](\d{2})$/i; // dd-mm-yy

        var date = RegYMDHIS.exec(Str);
        if (date) { return (new Date(date[1],date[2]-1,date[3],date[4],date[5],date[6])); }

        var date = RegDMYHIS.exec(Str);
        if (date) { return (new Date(date[3],date[2]-1,date[1],date[4],date[5],date[6])); }

        var date = RegYMD.exec(Str);
        if (date) { return (new Date(date[1],date[2]-1,date[3])); }

        var date = RegDMY.exec(Str);
        if (date) { return (new Date(date[3],date[2]-1,date[1])); }

        var date = RegDMY2.exec(Str);
        if (date) {
            Year=Number(date[3]);
            if (Year<10) { Year+=2000; }
            else { Year+=1900; }
            return (new Date(Year, (date[2]-1), date[1]));
        }
    }
    
    return null;
}



function _SetFormat(Str) {
    if (Str=='dd-mm-yy') { this.format='dd-mm-yy'; }
    else if (Str=='dd.mm.yy') { this.format='dd.mm.yy'; }
    else if (Str=='yyyy-mm-dd') { this.format='yyyy-mm-dd'; }
    else if (Str=='yyyy.mm.dd') { this.format='yyyy.mm.dd'; }
    else if (Str=='dd.mm.yyyy') { this.format='dd.mm.yyyy'; }
    else { this.format='dd-mm-yyyy'; }

    return true;
}
// *********************************** LSCalendar ***********************************







// функция инициализации
var pixelSpacer = '<div style="width: 1px; height: 1px;"><spacer type="block" width="1" height="1" /><\/div>';

// массив объектов LSCalendar для каждого календаря
var LSCalendars=new Array();

function calendar(name, Date) {
    LSCalendars[name]=new LSCalendar();
    LSCalendars[name].SetDate(Date);
    

    // Вставляет HTML-код с необходимыми полями...
    document.write('<table cellpadding="0" cellspacing="0" border="0"><tr valign="bottom">');
    document.write('<td><input type="text" name="' + name + '" size="12" value="' + LSCalendars[name].GetStrDate() + '" onBlur="setCalendarDateByStr(this.name, this.value);"><\/td>');
    document.write('<td>' + pixelSpacer + '<\/td>');
    document.write('<td valign="middle"><input type="button" class="calBtn" style="width: 40px; font-size: 70%; background: url(' + imagesFolder + 'dayselect.gif) no-repeat center;" onClick="showCalendarForElement(\'' + name + '\', event); return false;"></td>');
    document.write('<td>' + pixelSpacer + '<\/td>');
    

    document.write('<\/tr><tr><td colspan="2">' + pixelSpacer + '<\/td>');
    document.write('<td><div id="' + name + 'Ptr" style="width: 1px; height: 1px;"><spacer type="block" width="1" height="1" /><\/div><\/td><\/tr>');
    document.write('<\/table>');
}

