/* Календарь */

/* Пример использования:

    <form>
    <script>
        var cFrom = new clite('2004-03-09');
        cFrom.addField('from', '%Y-%M-%D 00:00:00');
        cFrom.write();
    </script>
    <br/>
    <script>
        var cTo = new clite(); // даты не выбрана
        cTo.addField('to-year', '%Y');
        cTo.addField('to-month', '%M');
        cTo.addField('to-day', '%D');
        cTo.write();
    </script>

    <input type="submit"/>
    </form>

    Метод addField добавляет поле с заданным именем и нужным форматом даты.
    Пока что есть %Y, %M, %D.
    При необходимости можно добавить новые "теги" в метод format.

    Дата принимается в формате YYYY-MM-DD, можно изменить в функции string2date.

*/

// ------------------------------------------------------------------------------------------------

var mShort = ['янв', 'фев', 'мар', 'апр', 'мая', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'];
var mLong  = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'];
var wShort = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];

var currentId = -1;

// ------------------------------------------------------------------------------------------------

/*
    id-шники:

    calDiv - div, в котором отображается календарь

    calObj4462 - object
    calInput4462 - input
    calButton4462 - button
*/

// clite.calendar()
function clite(string)
{
    this.date = string2date(string);
    if (!this.date)
    {
        this.date = new Date();
        this.empty = true; // если empty = true, то поле с датой пустое и ничего не сабмитится
    }

    this.fields = new Object;
    this.rnd = Math.floor(Math.random() * 1000000);
    window['calObj' + this.rnd] = this;

    // methods
    this.toString = date2string;
    this.addField = addField;
    this.format   = format;
    this.write    = write;
    this.update   = update;
    this.html     = html;
    this.update_date  = update_date;

    var div = document.getElementById('calDiv');
    if (!div)
    {
        var div = document.createElement('div');
        div.id = 'calDiv';
        div.className = 'calendar-div';
        var body = document.body
        body.insertBefore(div, body.firstChild);

        addEvent(div, 'click', calClick);
    }

    this.div = div;
}

// ------------------------------------------------------------------------------------------------

// clite.write()
function write()
{
    var fields = this.fields;
    document.write('<input class="calendar-input" name="calendar" id="calInput' + this.rnd + '" value="' + this.toString() + '" readonly="yes">&nbsp;');
    document.write('<input class="calendar-button" id="calButton' + this.rnd + '" type="button" value=" " onclick="showCalendar(this, ' + this.rnd + ')">');
    for (field in fields)
    {
        document.write('<input name="' + field + '" id="' + field + '" type="hidden" value="' + this.format(fields[field]) + '">');
    }
    this.update();

    var button = document.getElementById('calButton' + this.rnd);
    addEvent(button, 'click', calClick);
}

function update_date (string)
{
		this.date = string2date(string);
		this.update();
}

// clite.update()
function update()
{
    this.div.innerHTML = this.html();
    var fields = this.fields;
    var myvar;
    for (field in fields)
    {
    	  myvar = this.format(fields[field]);
        document.getElementById(field).value = myvar;
    }
    document.getElementById('calInput' + this.rnd).value = this.toString();
}

// clite.toString()
function date2string()
{
    if (this.empty) { return ''; }

    var date = this.date;
    return  zeroFill(date.getDate()) + ' ' + mShort[date.getMonth()] + ' ' + date.getFullYear();
}

// clite.addField()
function addField(name, format)
{
    this.fields[name] = format;
}

//clite.format()
function format(f)
{
    if (this.empty) { return ''; }

    var fY = this.date.getFullYear()
    f = f.replace(/%Y/g, fY);
    f = f.replace(/%M/g, zeroFill(this.date.getMonth() + 1));
    f = f.replace(/%D/g, zeroFill(this.date.getDate()));
    f = f.replace(/%y/g, zeroFill(fY % 100))
    return f;
}

// ------------------------------------------------------------------------------------------------

function repos(o)
{
    var style = document.getElementById('calDiv').style;
    var pos = getPosition(o);

    style.left = pos.x;
    style.top  = pos.y;
}

function show()
{
    var cal = document.getElementById('calDiv');
    if (cal)
    {
//		hide_selects('show');
        cal.style.visibility = 'visible';
    }
}

function hide()
{
    var cal = document.getElementById('calDiv');
    if (cal)
    {
        cal.style.visibility = 'hidden';
//		hide_selects('hide');
        closeCalendarTimeOut = 0;
    }
}

function visible()
{
    var cal = document.getElementById('calDiv');
    if (cal) { return (cal.style.visibility == 'visible'); }
    return false;
}

function string2date(string)
{
    var re = /(\d+)-(\d+)-(\d+)/;
    var date = re.exec(string);
    if (date) {
        return new Date(date[1], date[2] - 1, date[3]);
    }
}

function zeroFill(value)
{
    return (value < 10 ? '0' : '') + value;
}

function hide_selects(mode)
{
	var selects = document.getElementsByTagName('select');
	for (var i = 0; i < selects.length; i++)
	{
		selects[i].style.visibility = (mode == 'show') ? 'hidden' : 'visible';
	}
}

// ------------------------------------------------------------------------------------------------

function showCalendar(o, id)
{
    repos(o);

    var cal = window['calObj' + id];
    cal.update();

    if (id == currentId && visible())
    {
        currentId = -1;
        hide();
    }
    else {
        currentId = id;
        show();
    }
}

function calSetDate(id, i)
{
    var cal = window['calObj' + id];
    cal.date.setDate(i);
    hide();
    cal.empty = false;
    cal.update();
}

function calSetMonth(id, i)
{
    var cal = window['calObj' + id];
    cal.date.setMonth(i + cal.date.getMonth());
    cal.update();
}

function calSetYear(id, i)
{
    var cal = window['calObj' + id];
    cal.date.setYear(i + cal.date.getFullYear());
    cal.update();
}

function calSetToday(id)
{
    var cal = window['calObj' + id];
    cal.date = new Date();
    hide();
    cal.empty = false;
    cal.update();
}

function calClear(id)
{
    var cal = window['calObj' + id];
    cal.date = new Date();
    hide();
    cal.empty = true;
    cal.update();
}

function calDayOver(o)
{
    o.oldClassName = o.className;
    o.className = o.className + ' over';
}

function calDayOut(o)
{
    o.className = o.oldClassName;
}

// ------------------------------------------------------------------------------------------------

function getPosition(o)
{
    var x = o.offsetLeft;
    var y = o.offsetTop + o.offsetHeight; // + 1
    while (o.offsetParent != null)
    {
        o = o.offsetParent;
        x += o.offsetLeft;
        y += o.offsetTop;
    }
    var pos = new Object();
    pos.x = x;
    pos.y = y;
    return pos;
}

// ------------------------------------------------------------------------------------------------

// clite.html()
function html()
{
    var r = '<table cellpadding="0" cellspacing="0" class="calendar">';

    r += '<tr class="set-year">';
    r += '<td class="prev" onclick="calSetYear(' + this.rnd + ', -1)">&laquo;</td>';
    r += '<td class="current" colspan="5">' + this.date.getFullYear() + '</td>';
    r += '<td class="next" onclick="calSetYear(' + this.rnd + ', 1)">&raquo;</td>';

    r += '<tr class="set-month">';
    r += '<td class="prev" onclick="calSetMonth(' + this.rnd + ', -1)">&laquo;</td>';
    r += '<td class="current" colspan="5">' + mLong[this.date.getMonth()] + '</td>';
    r += '<td class="next" onclick="calSetMonth(' + this.rnd + ', 1)">&raquo;</td>';

    r += '<tr class="dates-head">';
    for (i = 0; i < wShort.length; i++)
    {
        r += '<th class="date">' + wShort[i] + '</th>';
    }

    var m = new Date(this.date);
    m.currentMonth = m.getMonth();
    // m.currentDate = (this.empty) ? -1 : m.getDate();
    m.currentDate = m.getDate();

    var now = new Date();

    var n = 1;

    m.setDate(1);
    var w = m.getDay(); w = (w == 0) ? 7 : w;
    if (w > 1)
    {
        r += '<tr class="dates">';
        for (i = 1; i < w; i++)
        {
            r += '<td class="empty">&nbsp;</td>';
            n++;
        }
    }

    for (i = 1; i <= 31; i++)
    {
        m.setDate(i);
        if (m.getMonth() != m.currentMonth) { break; }

        if (n % 7 == 1) { r += '<tr class="dates">'; }
        if (i == m.currentDate)
        {
            r += ('<td class="current">' + i + '</td>');
        }
        else {
            r += ('<td class="date" onclick="calSetDate(' + this.rnd + ', ' + i + ')" onmouseover="calDayOver(this)" onmouseout="calDayOut(this)">' + i + '</td>');
        }
        n++;
    }

    if (n % 7 > 1)
    {
        for (i = 0; i <= 7 - n % 7; i++)
        {
            r += '<td class="empty">&nbsp;</td>';
        }
    }

    r += '<tr><td class="set-today" colspan="4" onclick="calSetToday(' + this.rnd + ')">Сегодня</a></td><td class="clear" colspan="3" onclick="calClear(' + this.rnd + ')">Очистить</a></td></tr>';
    r += '</table>';

    return r;
}

// ------------------------------------------------------------------------------------------------

function addEvent(element, event, func)
{
    if (element.addEventListener)
    {
        element.addEventListener(event, func, false);
    }
    else if (element.attachEvent)
    {
        element.attachEvent('on' + event, func);
    } else {
        //
    }
}

function calClick(e)
{
    var event = (e) ? e : window.event;
    event.cancelBubble = true;
}

addEvent(window, 'resize', hide);
addEvent(document, 'click', hide);
