/* 
   Filename: datepicker.js
   Author:   Falko Zander, falko@falko-zander.de
   Created:  2007-11-28
   Update:   2007-12-04
   
   Abstract: datapicker dialog control
   
   Notes:
*/

var datepicker_div_ = null;

function datepicker(parentid, callback, forced_lang, auto_close, is_modal) {
    this.parentid_ = parentid || "";
    this.actual_month_ = -1;
    this.actual_year_ = -1;
    this.table_rows_ = 6;
    this.leap_years_ = {};
    this.callback_ = callback || null;
    this.auto_close_ = auto_close || 1;
    this.is_modal_ = is_modal || 0;
    this.forced_lang_ = forced_lang || null;

    var date = new Date();
    this.today = {d: date.getDate(), m: date.getMonth(), y: date.getFullYear()};

    this.fader_ = null;

    this.calc_leapyears_();
}

datepicker.prototype.to_string = function(y, m, d) {
    var sd = (d < 10) ? ("0" + d.toString()) : d.toString();
    var sm = (m < 10) ? ("0" + m.toString()) : m.toString();
    var sy = y.toString();
    
    return this.trans_date_(sy, sm, sd);
}

datepicker.prototype.to_date = function(s) {
    return this.trans_date_(s);
}

datepicker.prototype.compress = function(s1, s2) {
    if (s1 == "") return s2;
    if (s2 == "") return s1;

    var lang = (this.forced_lang_ != null) ? this.forced_lang_ : CONFIG.lang.value;

    var d1 = this.trans_date_(s1);
    var d2 = this.trans_date_(s2);
    
    if (lang == 'de') {
        if (d1.year < d2.year) { return s1 + "-" + s2; } 
        else if (d1.year > d2.year) { return s2 + "-" + s1; }

        if (d1.month < d2.month) { return s1.substr(0, 6) + "-" + s2; }
        else if (d1.month > d2.month) { return s2.substr(0, 6) + "-" + s1; }

        if (d1.day < d2.day) {
            if (d1.day + 1 == d2.day) { return s1.substr(0, 3) + "/" + s2; }
            else { return s1.substr(0, 3) + "-" + s2; }
        } else if (d1.day > d2.day) {
            if (d1.day - 1 == d2.day) { return s2.substr(0, 3) + "/" + s1; } 
            else { return s2.substr(0, 3) + "-" + s1; }
        }
    } else if (lang == 'en') {
        if (d1.year < d2.year) { return s1 + " / " + s2; } 
        else if (d1.year > d2.year) { return s2 + " / " + s1; }

        if (d1.month < d2.month) { return s1 + "/" + s2.substr(5); }
        else if (d1.month > d2.month) { return s2 + "/" + s1.substr(5); }
    
        if (d1.day < d2.day) { return s1 + "/" + s2.substr(8); }
        else if (d1.day > d2.day) { return s2 + "/" + s1.substr(8); }
    } else {
        error("datepicker: wrong language");
    }

    return s1;
}

datepicker.prototype.decompress = function(s) {
    if (typeof s == 'undefined' || s == "") return ["", ""];

    var lang = (this.forced_lang_ != null) ? this.forced_lang_ : CONFIG.lang.value;

    if (lang == 'de') {
        var d = s.split('-');
    
        if (d.length == 2) {
            var s1, s2;
            switch (d[0].length) {
                case 3:
                    s1 = s.substr(0, 3) + s.substr(7);
                    s2 = s.substr(4);
                    break;
                case 6:
                    s1 = s.substr(0, 6) + s.substr(13);
                    s2 = s.substr(7);
                    break;
                case 10:
                    s1 = s.substr(0, 10);
                    s2 = s.substr(11);
                    break;
            }
            return [s1, s2];
        } else {
            if (s.search('/') != -1) {
                var s1 = s.substr(0, 3) + s.substr(7);
                var s2 = s.substr(4);
                return [s1, s2];
            } else {
                return [s, ""];
            }
        }
    } else if (lang == 'en') {
        var d = s.split('/');
        if (d.length == 1) return [s, ""];
        if (d[0].length == d[1].length) return [s.substr(0, 10), s.substr(13)];
        if (d[1].length == 5) return [s.substr(0, 10), s.substr(0, 5) + s.substr(11)];
        return [s.substr(0, 10), s.substr(0, 8) + s.substr(11)];
    } else {
        error("datepicker: wrong language");
    }
}

datepicker.prototype.open = function() {
    var e = this.open_();
    var d = new Date();
    var t = "";

    t += "<table cellpadding='0' cellspacing='0' align='center'>" +
         "<tr><th id='datepicker_left'>&laquo;</span></th>" +
         "<th colspan='5' id='datepicker_caption'>&nbsp;</th>" +
         "<th id='datepicker_right'>&raquo;</th></tr>" +
         "<tr><th>" + this.trans_day_(0).substr(0, 1) + "</th>" +
         "<th>" + this.trans_day_(1).substr(0, 1) + "</th>" +
         "<th>" + this.trans_day_(2).substr(0, 1) + "</th>" +
         "<th>" + this.trans_day_(3).substr(0, 1) + "</th>" +
         "<th>" + this.trans_day_(4).substr(0, 1) + "</th>" +
         "<th>" + this.trans_day_(5).substr(0, 1) + "</th>" +
         "<th>" + this.trans_day_(6).substr(0, 1) + "</th></tr>";
    for (var i = 0; i < this.table_rows_; i++) {
        t += "<tr><td id='datepicker_" + i + "_0'>&nbsp;</td>" +
             "<td id='datepicker_" + i + "_1'>&nbsp;</td>" +
             "<td id='datepicker_" + i + "_2'>&nbsp;</td>" +
             "<td id='datepicker_" + i + "_3'>&nbsp;</td>" +
             "<td id='datepicker_" + i + "_4'>&nbsp;</td>" +
             "<td id='datepicker_" + i + "_5'>&nbsp;</td>" +
             "<td id='datepicker_" + i + "_6'>&nbsp;</td></tr>";
    }
    e.innerHTML = t;
    
    var THIS = this;
    $('datepicker_left').onclick = function() { THIS.left_() }
    $('datepicker_right').onclick = function() { THIS.right_() }

    this.actual_month_ = d.getMonth();
    this.actual_year_ = d.getFullYear();
    
    this.fill_();
}

datepicker.prototype.close = function() {
    if (datepicker_div_ != null) {
        datepicker_div_.style.display = "none";
    }
    if (this.is_modal_ == 1) {
        this.fader_ = ViewUtils.remove_fader(this.fader_);
    }
}

/* end of public interface */

datepicker.prototype.fill_ = function() {
    $("datepicker_caption").innerHTML = this.trans_month_(this.actual_month_) + "&nbsp;" + this.actual_year_;

    var years = {};
    var months = {};
    years[0] = this.actual_year_;
    months[0] = this.actual_month_;
    var dom = this.days_of_month_(this.actual_month_, this.actual_year_);
    this.left_(1);
    years[-1] = this.actual_year_;
    months[-1] = this.actual_month_;
    var dopm = this.days_of_month_(this.actual_month_, this.actual_year_);
    var sd = Math.floor(dopm - (49 - dom) / 2);
    var d = new Date(this.actual_year_, this.actual_month_, sd);
    this.right_(1);
    this.right_(1);
    years[1] = this.actual_year_;
    months[1] = this.actual_month_;
    this.left_(1);
    var day = this.get_start_(sd, d.getDay(), dopm);
    
    var mode = -1;
    for (var r = 0; r < this.table_rows_; r++) {
        for (var c = 0; c < 7; c++) {
            var e = $('datepicker_' + r + '_' + c);
            e.innerHTML = day;
            this.set_callback_(e, years[mode], months[mode], day);
            day++;
            switch (mode) {
                case -1:
                    if (day > dopm) {
                        day = 1;
                        mode++;
                    }
                case 1:
                    if (c == 5 || c == 6) {
                        e.className = "weekend other";
                    } else {
                        e.className = "other";
                    }
                    break;
                case 0:
                    if (day > dom) {
                        day = 1;
                        mode++;
                    }
                    if (c == 5 || c == 6) {
                        e.className = "weekend month";
                    } else {
                        e.className = "month";
                    }
                    if (day - 1 == this.today.d &&
                        this.actual_month_ == this.today.m &&
                        this.actual_year_ == this.today.y) {
                        e.className += " today";
                    }
                    break;
            }
        }
    }
}

datepicker.prototype.set_callback_ = function(e, y, m, d) {
    if (this.callback_ == null) return;

    var THIS = this;
    if (this.auto_close_ == 1) {
        e.onclick = function() { THIS.do_callback_(y, ++m, d); }
    } else {
        e.onclick = function() { THIS.callback_(y, ++m, d, this.parentid_); }
    }
}

datepicker.prototype.do_callback_ = function(y, m, d) {
    this.close();
    this.callback_(y, m, d, this.parentid_);
}

datepicker.prototype.left_ = function(no_fill) {
    if (this.actual_month_ == -1 || this.actual_year_ == -1) error("datepicker: wrong data");

    if (this.actual_month_ > 0) {
        this.actual_month_--;
    } else {
        this.actual_month_ = 11;
        this.actual_year_--;
    }

    if (no_fill != 1) this.fill_();
}

datepicker.prototype.right_ = function(no_fill) {
    if (this.actual_month_ == -1 || this.actual_year_ == -1) error("datepicker: wrong data");

    if (this.actual_month_ < 11) {
        this.actual_month_++;
    } else {
        this.actual_month_ = 0;
        this.actual_year_++;
    }

    if (no_fill != 1) this.fill_();
}

datepicker.prototype.open_ = function() {
    var e;
    if (datepicker_div_ == null) {
        e = document.createElement("div");
        document.body.appendChild(e);
        e.id = "datepicker";
        datepicker_div_ = e;
    } else {
        e = datepicker_div_;
        e.style.display = "block";
    }
    this.set_position_();

    if (this.is_modal_ == 1) {
        this.fader_ = ViewUtils.show_fader();
    }

    return e;
}

datepicker.prototype.set_position_ = function() {
    var p = $(this.parentid_);
    var e = datepicker_div_;
    if (e == null) error("datepicker: element not defined");

    if (p != null) {
        var d = getAbsoluteDimensions(p);
        e.style.left = d.offsetLeft + 2 + "px";
        e.style.top = d.offsetTop + p.offsetHeight + 2 + "px";
    } else {
        var w = window.innerWidth || document.body.clientWidth;
        var h = window.innerHeight || document.body.clientHeight;
        e.style.left = (w - e.offsetWidth) / 2 + "px";
        e.style.top = (h - e.offsetHeight) / 2 + "px";
    }
}

datepicker.prototype.trans_month_ = function(month) {
    var lang = (this.forced_lang_ != null) ? this.forced_lang_ : CONFIG.lang.value;

    if (lang == "de") {
        switch (month) {
            case 0: return "Januar";
            case 1: return "Februar";
            case 2: return "M&auml;rz";
            case 3: return "April";
            case 4: return "Mai";
            case 5: return "Juni";
            case 6: return "Juli";
            case 7: return "August";
            case 8: return "September";
            case 9: return "Oktober";
            case 10: return "November";
            case 11: return "Dezember";
        }
    } else if (lang == "en") {
        switch (month) {
            case 0: return "January";
            case 1: return "February";
            case 2: return "March";
            case 3: return "April";
            case 4: return "May";
            case 5: return "June";
            case 6: return "July";
            case 7: return "August";
            case 8: return "September";
            case 9: return "October";
            case 10: return "November";
            case 11: return "December";
        }
    } else {
        error("datepicker: wrong language");
    }
}

datepicker.prototype.trans_day_ = function(day) {
    var lang = (this.forced_lang_ != null) ? this.forced_lang_ : CONFIG.lang.value;

    if (lang == "de") {
        switch (day) {
            case 0: return "Montag";
            case 1: return "Dienstag";
            case 2: return "Mittwoch";
            case 3: return "Donnerstag";
            case 4: return "Freitag";
            case 5: return "Samstag";
            case 6: return "Sonntag";
        }
    } else if (lang == "en") {
        switch (day) {
            case 0: return "Monday";
            case 1: return "Tuesday";
            case 2: return "Wednesday";
            case 3: return "Thursday";
            case 4: return "Friday";
            case 5: return "Saturday";
            case 6: return "Sunday";
        }
    } else {
        error("datepicker: wrong language");
    }
}

datepicker.prototype.trans_date_ = function(sy, sm, sd) {
    var lang = (this.forced_lang_ != null) ? this.forced_lang_ : CONFIG.lang.value;

    if (typeof sm == 'undefined' && typeof sd == 'undefined') {
        if (lang == "de") {
            var d = sy.split(".");
            if (d.length != 3) { error("datepicker: wrong date format"); }
            d[0]=d[0].replace (/^0+/,"");
            d[1]=d[1].replace (/^0+/,"");
            d[2]=d[2].replace (/^0+/,"");
            return { day: parseInt(d[0]), month: parseInt(d[1]), year: parseInt(d[2]) }
        } else if (lang == "en") {
            var d = sy.split("-");
            if (d.length != 3) error("datepicker: wrong date format");
            d[0]=d[0].replace (/^0+/,"");
            d[1]=d[1].replace (/^0+/,"");
            d[2]=d[2].replace (/^0+/,"");
            return {day: parseInt(d[2]), month: parseInt(d[1]), year: parseInt(d[0]) }
        } else {
            error("datepicker: wrong language");
        }
    } else {
        if (lang == "de") {
            return sd + "." + sm + "." + sy;
        } else if (lang == "en") {
            return sy + "-" + sm + "-" + sd;
        } else {
            error("datepicker: wrong language");
        }
    }
}

datepicker.prototype.calc_leapyears_ = function() {
    for (var i = 1904; i < 2100; i+=4) {
        this.leap_years_[i] = 1;
    }
    for (var i = 2104; i < 2200; i+=4) {
        this.leap_years_[i] = 1;
    }
    for (var i = 2204; i < 2300; i+=4) {
        this.leap_years_[i] = 1;
    }
    for (var i = 2304; i <= 2400; i+=4) {
        this.leap_years_[i] = 1;
    }
}

datepicker.prototype.is_leapyear_ = function(year) {
    return (year in this.leap_years_);
}

datepicker.prototype.days_of_month_ = function(month, year) {
    switch (month) {
        case 0:
        case 2:
        case 4:
        case 6:
        case 7:
        case 9:
        case 11:
            return 31;
        case 1:
            return this.is_leapyear_(year) ? 29 : 28;
        case 3:
        case 5:
        case 8:
        case 10:
            return 30;
    }
}

datepicker.prototype.get_start_ = function(day, weekday, days_of_month) {
    var d;
    switch(weekday) {
        case 0: d = day + 1; break;
        case 1: d = day; break;
        case 2: d = day - 1; break;
        case 3: d = day - 2; break;
        case 4: d = day + 4; break;
        case 5: d = day + 3; break;
        case 6: d = day + 2; break;
    }
    return (d + 7 < days_of_month) ? (d + 7) : d;
}

/*
   Copyright Notice:
  
   Copyright 2007, Falko Zander
   ALL RIGHTS RESERVED
   
   UNPUBLISHED -- Use of a copyright notice is precautionary only and
   does not imply publication or disclosure.
   
   THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
   INFORMATION OF FALKO ZANDER. ANY DUPLICATION, MODIFICATION,
   DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS
   STRICTLY PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF
   FALKO ZANDER.
*/
