
ko.components.register('ko-datepicker', {
    viewModel: function (params) {
        var self = this;
        self.params = params;
        self.dateType = params.dateType;
        self.selectScope = params.selectScope;
        self.randomId = Math.random() * (10000000 - 100) + 100;
        self.id = "input-datepicker-" + self.randomId;
        self.weekDays = [
            { fa: "شنبه", en: "Saturday" },
            { fa: "یکشنبه", en: "Sunday" },
            { fa: "دوشنبه", en: "Monday" },
            { fa: "سه شنبه", en: "Tuesday" },
            { fa: "چهارشنبه", en: "Wednesday" },
            { fa: "پنج شنبه", en: "Thursday" },
            { fa: "جمعه", en: "Friday" }
        ];
        self.months = [
            { faName: "فروردین", name: "Jan", id: 1 },
            { faName: "اردیبهشت", name: "Feb", id: 2 },
            { faName: "خرداد", name: "Mar", id: 3 },
            { faName: "تیر", name: "Apr", id: 4 },
            { faName: "مرداد", name: "May", id: 5 },
            { faName: "شهریور", name: "Jun", id: 6 },
            { faName: "مهر", name: "Jul", id: 7 },
            { faName: "آبان", name: "Aug", id: 8 },
            { faName: "آذر", name: "Sep", id: 9 },
            { faName: "دی", name: "Oct", id: 10 },
            { faName: "بهمن", name: "Nov", id: 11 },
            { faName: "اسفند", name: "Dec", id: 12 }
        ];
        self.years = [
            { fa: 1380, en: 2001 },
            { fa: 1381, en: 2002 },
            { fa: 1382, en: 2003 },
            { fa: 1383, en: 2004 },
            { fa: 1384, en: 2005 },
            { fa: 1385, en: 2006 },
            { fa: 1386, en: 2007 },
            { fa: 1387, en: 2008 },
            { fa: 1388, en: 2009 },
            { fa: 1389, en: 2010 },
            { fa: 1390, en: 2011 },
            { fa: 1391, en: 2012 },
            { fa: 1392, en: 2013 },
            { fa: 1393, en: 2014 },
            { fa: 1394, en: 2015 },
            { fa: 1395, en: 2016 },
            { fa: 1396, en: 2017 },
            { fa: 1397, en: 2018 },
            { fa: 1398, en: 2019 },
            { fa: 1399, en: 2020 },
            { fa: 1400, en: 2021 },
            { fa: 1401, en: 2022 },
            { fa: 1402, en: 2023 },
            { fa: 1403, en: 2024 },
            { fa: 1404, en: 2025 },
            { fa: 1405, en: 2026 },
            { fa: 1406, en: 2027 },
            { fa: 1407, en: 2028 },
            { fa: 1408, en: 2029 },
            { fa: 1409, en: 2030 },
            { fa: 1410, en: 2031 },
            { fa: 1411, en: 2032 },
            { fa: 1412, en: 2033 },
            { fa: 1413, en: 2034 },
            { fa: 1414, en: 2035 },
            { fa: 1415, en: 2036 },
            { fa: 1416, en: 2037 },
            { fa: 1417, en: 2038 },
            { fa: 1418, en: 2039 },
            { fa: 1419, en: 2040 },
            { fa: 1420, en: 2041 }
        ];
        if (params.disable) {
            self.disable = params.disable;
        }
        else {
            self.disable = ko.observable(false);
        }
        self.showMenu = ko.observable(false);
        self.showYearList = ko.observable(false);
        self.bubblePrevent = false;
        self.input = ko.observable();
        self.month = ko.observable();
        self.year = ko.observable();
        self.day = ko.observable();
        self.patterns = {
            fa: { mask: "9999/99/99", placeholder: "----/--/--" },
            en: { mask: "99/99/9999", placeholder: "--/--/----" }
        };
        self.mask = ko.observable(self.patterns[self.dateType].mask);
        self.placeholder = ko.observable(self.patterns[self.dateType].placeholder);
        self.latestDate = function () {
            switch (self.dateType) {
                case "en":
                    break;
                case "fa":
                    return self.year() + "/" + self.month() + "/" + self.day();
            }
        };
        self.onClick = function (model, e) {
            if (self.disable()) {
                return;
            }
            self.showMenu(true);
            self.refreshValues();
            self.buildTableMonth();
        };
        self.input.subscribe(function (newValue) {
            if (!_h.isNullOrEmpty(newValue) && newValue !== "" && newValue.indexOf("-") === -1) {
                var formatDate = dateHelper.fromDatePicker(newValue, self.dateType);
                if (formatDate) {
                    self.bubblePrevent = true;
                    self.params.value(formatDate);
                    self.bubblePrevent = false;
                }
            } else { 
                self.bubblePrevent = true;
                self.params.value(undefined);
                self.bubblePrevent = false;
            }
        });
        self.init = function () {
            self.refreshValues();
            if (self.selectScope === "wide") {
                var currentYear = dateHelper.getCurrentJalaaliYear().jy;
                var date = new Date();
                var currentgYear = date.getFullYear();
                var years = [];
                for (var i = 0; i < 100; i++) {
                    years.push({ fa: currentYear - i, en: currentgYear - i });
                    if (i > 80)
                        years.push({ fa: currentYear + (i - 80), en: currentgYear + (i - 80) });

                }
                years.sort((a, b) => a.fa - b.fa);
                self.years = years;
                self.params.value.subscribe(function(newValue) {
                    if (self.bubblePrevent) {
                        return;
                    }
                    if (!_h.isNullOrEmpty(newValue) && newValue !== "" && newValue.indexOf("-") === -1) {
                        date = dateHelper.toDatePicker(newValue);
                        self.month(date[0].jm);
                        self.year(date[0].jy);
                        self.day(date[0].jd);
                        var nDate = self.year() +
                            "/" +
                            self.fixMonthDayNumber(self.month()) +
                            "/" +
                            self.fixMonthDayNumber(self.day());
                        self.bubblePrevent = true;
                        self.input(nDate);
                        self.bubblePrevent = false;
                    } else {
                        self.input(undefined);
                    }

                });
            } else {
                self.params.value.subscribe(function (newValue) {
                    if (self.bubblePrevent) {
                        return;
                    }
                    if (!_h.isEmpty(newValue)) {
                        var date = dateHelper.toDatePicker(newValue);
                        self.month(date[0].jm);
                        self.year(date[0].jy);
                        self.day(date[0].jd);
                        var nDate = self.year() + "/" +
                            self.fixMonthDayNumber(self.month()) + "/" + self.fixMonthDayNumber(self.day());
                        self.bubblePrevent = true;
                        self.input(nDate);
                        self.bubblePrevent = false;
                    }
                });
            }
        };
        self.fixMonthDayNumber = function (num) {
            var x = num.toString();
            if (x.length === 1)
                return "0" + num;
            return num;
        };
        self.refreshValues = function () {
            var date, nDate;
            if (!_h.isNullOrEmpty(self.params.value()) && self.params.value() !== "") {
                date = dateHelper.toDatePicker(self.params.value());
                self.month(date[0].jm);
                self.year(date[0].jy);
                self.day(date[0].jd);
                nDate = self.year() + "/" +
                    self.fixMonthDayNumber(self.month()) + "/" + self.fixMonthDayNumber(self.day());
                self.input(nDate);
            } else {
                var today = dateHelper.dateNow("fa");
                date = dateHelper.toDatePicker(today);
                self.month(date[0].m);
                self.year(date[0].y);
                self.day(date[0].d);
            }
        };
        self.init();
        self.formatMonth = function (number) {
            if (_h.isNullOrEmpty(number))
                return "";
            var month = self.months[number - 1];
            return month.faName;
        };
        self.onShowMonthList = function () {
            self.showYearList(false);
        };
        self.onShowYearList = function () {
            self.showYearList(true);
        };
        self.onSelectYear = function (item) {
            self.year(item.fa);
            if (!dateHelper.isValidJalaaliDate(self.year(), self.month(), self.day()))
                self.day(1);
            self.buildTableMonth();
        };
        self.onSelectMonth = function (item) {
            self.month(item.id);
            if (!dateHelper.isValidJalaaliDate(self.year(), self.month(), self.day()))
                self.day(1);
            self.buildTableMonth();
        };
        self.onUpdate = function () {
            if (self.showYearList()) {
                if ((self.dateType === "fa" && self.year() >= 1420) ||
                    (self.dateType === "en" && self.year() >= 2041))
                    return;
                self.year(self.year() + 1);
                if (!dateHelper.isValidJalaaliDate(self.year(), self.month(), self.day()))
                    self.day(1);
            }
            else {
                if (self.month() < 12) {
                    self.month(self.month() + 1);
                } else {
                    if ((self.dateType === "fa" && self.year() >= 1420) ||
                        (self.dateType === "en" && self.year() >= 2041))
                        return;
                    self.year(self.year() + 1);
                    self.month(1);
                    if (!dateHelper.isValidJalaaliDate(self.year(), self.month(), self.day()))
                        self.day(1);
                }
            }
            self.buildTableMonth();
        };
        self.onDowndate = function () {
            if (self.showYearList()) {
                if ((self.dateType === "fa" && self.year() <= 1380) ||
                    (self.dateType === "en" && self.year() <= 2001))
                    return;
                self.year(self.year() - 1);
                if (!dateHelper.isValidJalaaliDate(self.year(), self.month(), self.day()))
                    self.day(1);
            }
            else {
                if (self.month() > 1) {
                    self.month(self.month() - 1);
                } else {
                    if ((self.dateType === "fa" && self.year() <= 1380) ||
                        (self.dateType === "en" && self.year() <= 2001))
                        return;
                    self.year(self.year() - 1);
                    self.month(1);
                    if (!dateHelper.isValidJalaaliDate(self.year(), self.month(), self.day()))
                        self.day(1);
                }
            }
            self.buildTableMonth();
        };
        self.setClassName = function (element, className) {
            element.className = className;
        };
        self.setInnerHTML = function (element, html) {
            element.innerHTML = html;
        };
        self.createElement = function (tag, parent) {
            var element = document.createElement(tag);
            if (parent)
                parent.appendChild(element);
            return element;
        };
        self.changeDay = function (date, day) {
            if (_h.isNullOrEmpty(date) || date === "")
                return undefined;
            var splits = date.split("/");
            return splits[0] + "/" + splits[1] + "/" + day;
        }
        self.buildTableMonth = function () {
            var today = dateHelper.dateNow("fa");
            var datePicker = $(".dp-body").get(0);
            var tr, td;
            var date = self.latestDate();
            datePicker.innerHTML = "";
            var table = self.createElement("table", datePicker);
            table.cellSpacing = 0;
            var weekDay = dateHelper.getWeekDay(self.changeDay(date, "01"));
            for (var row = 0; row < 7; row++) {
                tr = table.insertRow(row);
                if (row === 6)
                    self.setClassName(tr, "dp-row-friday ncls");
                else if (dateHelper.mod(row, 2) !== 1)
                    self.setClassName(tr, "dp-row-even ncls");
                else
                    self.setClassName(tr, "dp-row-odd ncls");
                td = self.createElement("td", tr);
                self.setInnerHTML(td, self.weekDays[row].fa);
                self.setClassName(td, "dp-week-day ncls");
                for (var col = 0; col < 6; col++) {
                    var cellValue = col * 7 + row - weekDay + 1;
                    td = self.createElement("td", tr);
                    self.setClassName(td, "ncls");
                    if (cellValue > 0 && cellValue <= dateHelper.getMonthDays(date)) {
                        self.setInnerHTML(td, cellValue);
                        var cellDate = self.changeDay(date, cellValue);
                        var cellClassName = "dp-day ncls";
                        if (cellDate === date)
                            cellClassName = "dp-day dp-selected-day ncls";
                        else if (cellDate === today)
                            cellClassName = "dp-day dp-today ncls";
                        self.setClassName(td, cellClassName);
                        td.onclick = function () {
                            var nDate = self.year() + "/" +
                                self.fixMonthDayNumber(self.month()) + "/" + self.fixMonthDayNumber(this.innerHTML);
                            self.input(nDate);
                            self.showMenu(false);
                            self.day(Number(this.innerHTML));
                        };
                    }
                }
            }
        };
        self.formatValue = ko.computed(function () {
            if (self.dateType === "fa" && !_h.isNullOrEmpty(self.year())) {
                return self.year() + "/" + self.month() + "/" + self.day();
            }
            return "";
        });
    },
    template: '<!-- ko if: !disable() --><div class="input-group"><input type="text" class="form-control text-center key-on" style="direction: ltr;" data-bind="masked: input, ' +
        'placeholder: placeholder, mask: mask" />' +
        '<!-- ko if: showMenu --><div class="datepicker-box drp-menu ncls">' +
        '<div class="dp-left ncls">' +
        '<ul class="dp-month-list ncls" data-bind="visible: !showYearList(), foreach: months">' +
        '<!-- ko if:  $parent.month() === id -->' +
        '<li class="month-select ncls" data-bind="click: $parent.onSelectMonth, text: faName"></li><!-- /ko -->' +
        '<!-- ko ifnot:  $parent.month() === id -->' +
        '<li class="ncls" data-bind="click: $parent.onSelectMonth, text: faName"></li><!-- /ko -->' +
        '</ul>' +
        '<ul class="dp-year-list ncls" data-bind="visible: showYearList, foreach: years">' +
        '<!-- ko if: $parent.year() === fa -->' +
        '<li class="year-select ncls" data-bind="click: $parent.onSelectYear, text: fa"></li><!-- /ko -->' +
        '<!-- ko ifnot: $parent.year() === fa -->' +
        '<li class="ncls" data-bind="click: $parent.onSelectYear, text: fa"></li><!-- /ko -->' +
        '</ul></div>' +
        '<div class="dp-right ncls">' +
        '<div class="dp-head ncls">' +
        '<div class="dp-title-box ncls">' +
        '<span class="dp-title ncls" data-bind="click: onShowMonthList, text: formatMonth(month())"></span>' +
        '<span class="dp-title ncls" data-bind="click: onShowYearList, text: year"></span></div>' +
        '<div class="dp-icon-box ncls"><a class="dp-icon ncls" data-bind="click: onUpdate">' +
        '<i class="fa fa-angle-up ncls"></i>' +
        '</a>' +
        '<a class="dp-icon ncls" data-bind="click: onDowndate">' +
        '<i class="fa fa-angle-down ncls"></i>' +
        '</a></div></div><div class="dp-body ncls"></div></div></div><!-- /ko --> ' +
        '<span class="input-group-btn ncls">' +
        '<img style="margin-top: -11px;margin-left: 10px;" class= "icon-image-small selectable ncls"' +
        'src="/App/src/images/ico/datepicker.png" data-bind="click: onClick" /></span></div><!-- /ko -->' +
        '<!-- ko if: disable --><input type="text" disabled="disabled" class="form-control text-center" data-bind="value: formatValue" />' +
        '<!-- /ko -->'
});