﻿/// <reference path="../js/controls.js" />
/// <reference path="../js/effects.js" />
/// <reference path="../js/global.js" />

$CS.ctrls.calendar = function (c) {

    c.cType = "calendar"; // тип контрола

    c.downLimit = c.obj.downLimit || $G.GetAttribute(c.obj, "downLimit"); //атрибут
    if (c.downLimit) {
        c.downLimit = $G.Date.TryGetDate(c.downLimit);
    }
    c.upLimit = c.obj.upLimit || $G.GetAttribute(c.obj, "upLimit"); //атрибут
    if (c.upLimit) {
        c.upLimit = $G.Date.TryGetDate(c.upLimit);
    }
    c.value = c.obj.innerHTML.toString().trim();
    c.obj.innerHTML = "";
    c.clearBtn = $G.Append(c.obj, $G.Tag("a", "fr clear-btn db", { href: "javascript://;", title: "Очистить" }));
    $G.Event.Add(c.clearBtn, "click", function () {
        this.set("");
    } .bind(c));
    c.val = $G.Append(c.obj, $G.Tag("span", null, null, c.value));
    c.down = $G.Append(c.obj, $G.Tag("div", "calendar-down"), c.val, true);

    c.w = ((c.obj.offsetWidth || Number(c.obj.inputwidth || $G.GetAttribute(c.obj, "inputwidth"))) - 2);
    c.w = c.w > 200 ? c.w : 200; //Ширина календаря
    c.wd = Math.floor((c.w - 6) / 7); //Ширина ячейки с днем
    c.md = Math.floor((c.w - (c.wd * 7) - 6) / 2); // Отступ слева
    c.hd = c.wd; //Высота дня
    c.hm = Math.floor((c.hd * 6 + 4) / 3); //Высота месяца и года   
    c.wm = Math.floor((c.w - 3) / 4); //Ширина ячейки с месяцем и годом
    c.mm = Math.floor((c.w - (c.wm * 4) - 3) / 2); // Отступ слева
    c.dm = c.w - (c.mm * 2 + c.wm * 4 + 3);
    c.dd = c.w - (c.md * 2 + c.wd * 7 + 6);

    c.down.style.width = c.w + "px";
    c.down.style.marginLeft = (($G.GetStyle(c.obj, "paddingLeft", true) + (($G.Browser.Detect.ie && !$G.Browser.Detect.ie9) ? 1 : 6)) * -1) + "px";
    c.down.style.marginTop = ((c.obj.offsetHeight || Number(c.obj.inputheight || $G.GetAttribute(c.obj, "inputheight"))) - ($G.Browser.Detect.ie ? 2 : 2)) + "px";
    c.down.style.display = "none";
    c.down.style.height = "0px";
    c.down.noInnerClose = true;
    //Заголовок
    c.head = $G.Append(c.down, $G.Tag("div", "head"));
    c.right = $G.Append(c.head, $G.Tag("div", "rarr fr"));
    c.left = $G.Append(c.head, $G.Tag("div", "larr fl"));
    c.right.style.width = c.left.style.width = (c.wd + c.md) + "px";
    c.title = $G.Append(c.head, $G.Tag("div", "tac"));
    c.title.style.marginLeft = (c.wd + c.md + 1) + "px";
    c.title.style.marginRight = (c.wd + c.md + 1) + "px";
    c.right.style.height = c.left.style.height = c.title.style.height = c.title.style.lineHeight = c.hd + "px";
    $G.Append(c.head, $G.Tag("div", "cb"));
    $G.Event.Add(c.title, "click", function () {
        if (this.days.length > 0) {
            var d = new Date();
            d.setFullYear(this.currentYear);
            d.setMonth(this.currentMonth);
            d.setDate(this.currentDate);
            this.fillMonth(d);
        }
    } .bind(c));
    $G.Event.Add(c.left, "click", function () {
        if (this.days.length > 0) {
            var d = new Date();
            d.setFullYear(this.currentMonth == 0 ? this.currentYear - 1 : this.currentYear);
            d.setDate(1);
            d.setMonth(this.currentMonth == 0 ? 11 : this.currentMonth - 1);
            //d.setDate(this.currentDate);
            this.fillDays(d);
        }
        else if (this.month.length > 0) {
            var d = new Date();
            d.setFullYear(this.currentYear - 1);
            d.setMonth(this.currentMonth);
            //d.setDate(1);
            d.setDate(this.currentDate);
            this.fillMonth(d);
        }
    } .bind(c));
    $G.Event.Add(c.right, "click", function () {
        if (this.days.length > 0) {
            var d = new Date();
            d.setFullYear(this.currentMonth == 11 ? this.currentYear + 1 : this.currentYear);
            d.setDate(1);
            d.setMonth(this.currentMonth == 11 ? 0 : this.currentMonth + 1);

            //d.setDate(this.currentDate);
            this.fillDays(d);
        }
        else if (this.month.length > 0) {
            var d = new Date();
            d.setFullYear(this.currentYear + 1);
            d.setMonth(this.currentMonth);

            d.setDate(this.currentDate);
            this.fillMonth(d);
        }
    } .bind(c));
    //сетка
    c.grid = $G.Append(c.down, $G.Tag("div", "grid"));

    c.currentYear = -1;
    c.currentMonth = -1;
    c.currentDay = -1;

    c.buildDays = function () {
        this.days = [];
        this.month = [];
        this.grid.innerHTML = "";
        for (var i = 0; i < 49; i++) {
            var _c = $G.Append(this.grid, $G.Tag("a", "cell fl", { href: "javascript://;" }));
            _c.style.width = (this.wd + ((i % 7 == 0) ? this.md : (i % 7 == 6) ? this.md + this.dd : 0)) + "px";
            _c.style.height = this.hd + "px";
            _c.style.lineHeight = this.hd + "px";
            if (i % 7 == 6)
                $G.ClassName.Replace(_c, "", "nobrdr");
            if (i > 41)
                $G.ClassName.Replace(_c, "", "nobrdb");
            this.days.push(_c);
        }
        for (var i = 0; i < $G.Date.DaysOfWeekShort.length; i++) {
            if (i == 6)
                this.days[i].innerHTML = $G.Date.DaysOfWeekShort[0];
            else
                this.days[i].innerHTML = $G.Date.DaysOfWeekShort[i + 1];
            $G.ClassName.Replace(this.days[i], "", "h-cell");
        }
        $G.Append(this.grid, $G.Tag("div", "cb"));
    } .bind(c);
    c.buildMonths = function () {
        this.days = [];
        this.month = [];
        this.grid.innerHTML = "";
        for (var i = 0; i < 12; i++) {
            var _c = $G.Append(this.grid, $G.Tag("a", "cell fl", { href: "javascript://;" }));
            _c.style.width = (this.wm + ((i % 4 == 0) ? this.mm : (i % 4 == 3) ? this.mm + this.dm : 0)) + "px";
            _c.style.height = this.hm + "px";
            _c.style.lineHeight = this.hm + "px";
            if (i % 4 == 3)
                $G.ClassName.Replace(_c, "", "nobrdr");
            if (i > 7)
                $G.ClassName.Replace(_c, "", "nobrdb");
            this.month.push(_c);
        }
        $G.Append(this.grid, $G.Tag("div", "cb"));
    } .bind(c);

    c.fillDays = function (date) {
        var date = $G.Is(date, Date) ? date : $G.Date.TryGetDate(date);
        this.buildDays();
        var _wd = $G.Date.Clone(date);
        _wd.setDate(1);
        this.currentMonth = date.getMonth();
        this.currentYear = date.getFullYear();
        this.currentDate = date.getDate();
        this.title.innerHTML = $G.Date.MonthEntity[1 + this.currentMonth] + ", " + this.currentYear;
        for (var i = 0; i < 42; i++) {
            var _td = $G.Date.Clone(_wd);
            _td.setDate(i - (_wd.getDay() || 7) + 2);
            this.days[i + 7].innerHTML = _td.getDate();
            if ($G.Date.Compare(_td, date))
                $G.ClassName.Replace(this.days[i + 7], ["selected", "today", "notthis", "no"], "selected");
            if ($G.Date.Compare(_td, (new Date())))
                $G.ClassName.Replace(this.days[i + 7], ["selected", "today", "notthis", "no"], "today");
            if (_td.getMonth() != date.getMonth())
                $G.ClassName.Replace(this.days[i + 7], ["selected", "today", "notthis", "no"], "notthis");
            if (this.downLimit) {
                if (_td.getTime() < this.downLimit.getTime())
                    $G.ClassName.Replace(this.days[i + 7], ["selected", "today", "notthis", "no"], "no");
            }
            if (this.upLimit) {
                if (_td.getTime() > this.upLimit.getTime())
                    $G.ClassName.Replace(this.days[i + 7], ["selected", "today", "notthis", "no"], "no");
            }
            this.days[i + 7].date = _td;
        }
    } .bind(c);
    c.fillMonth = function (date) {
        var date = $G.Is(date, Date) ? date : $G.Date.TryGetDate(date);
        this.buildMonths();
        this.currentMonth = date.getMonth();
        this.currentYear = date.getFullYear();
        this.currentDate = date.getDate();
        this.title.innerHTML = this.currentYear;
        for (var i = 0; i < 12; i++) {
            this.month[i].innerHTML = $G.Date.ShortMonth[1 + i];
            if (i == date.getMonth())
                $G.ClassName.Replace(this.month[i], ["selected", "today"], "selected");
            if (i == (new Date()).getMonth())
                $G.ClassName.Replace(this.month[i], ["selected", "today"], "today");
            this.month[i].date = $G.Date.Clone(date);
            this.month[i].date.setMonth(i);
        }
    } .bind(c);

    c.obj.onclick = function (e) {
        if (!this.disabled()) {
            var t = $G.Event.Target(e);
            if (t) {
                if (!$G.IsChildOf(this.down, t, 5) && t != this.clearBtn) {
                    this.fillDays(this.value);
                    this.disp = (this.hd * 7) + 6;
                    var a = (this.obj.offsetWidth - this.w - 8);
                    this.down.style.marginLeft = (a > 0 ? a : 0) + "px";
                    $CS.SlideSelector(this.down, function (what) {
                        if (what.date && !$G.ClassName.Has(what, "no")) {
                            if (this.days.length > 0) {
                                this.set(what.date);
                                this.down.style.height = "0";
                                this.down.style.display = "none";
                                if (this.down.onClose)
                                    this.down.onClose();
                                this.down.hidden = true;
                            }
                            else {
                                this.fillDays(what.date);
                            }
                        }
                    } .bind(this), null, null, this.disp, null, function () {
                        if ($G.Browser.Detect.webkit) {
                            this.fillDays(this.value);
                        }
                    } .bind(this));
                }
            }
        }
    } .bind(c);

    c.getValue = function () { // получить значение
        return $G.Date.StringFormat("dd.MM.YYYY", this.value);
    } .bind(c);

    c.set = function (value) { // установить значение
        var value = value ? $G.Is(value, Date) ? value : $G.Date.TryGetDate(value) : "";
        this.value = value;
        this.val.innerHTML = $G.Date.StringFormat("dd.MM.YYYY", value);
        if (!value)
            this.clearBtn.style.visibility = "hidden";
        else
            this.clearBtn.style.visibility = "";

    } .bind(c);

    c.set(c.value); // Значение по-умолчанию
}
