function getCursorPosition(e){
    var x;
    var y;
    if (!e) 
        var e = window.event;
    if (e.pageX || e.pageY) {
        x = e.pageX;
        y = e.pageY;
    }
    else 
        if (e.clientX || e.clientY) {
            x = e.clientX + document.body.scrollLeft +
            document.documentElement.scrollLeft;
            y = e.clientY + document.body.scrollTop +
            document.documentElement.scrollTop;
        }
    return {
        x: x,
        y: y
    };
};
Date.fullYearStart = '20';
(function(){
    function add(name, method){
        if (!Date.prototype[name]) {
            Date.prototype[name] = method;
        }
    };
    add("isLeapYear", function(){
        var y = this.getFullYear();
        return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
    });
    add("isWeekend", function(){
        return this.getDay() == 0 || this.getDay() == 6;
    });
    add("isWeekDay", function(){
        return !this.isWeekend();
    });
    add("getDaysInMonth", function(){
        return [31, (this.isLeapYear() ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][this.getMonth()];
    });
    add("getDayName", function(abbreviated){
        return abbreviated ? Date.abbrDayNames[this.getDay()] : Date.dayNames[this.getDay()];
    });
    add("getMonthName", function(abbreviated){
        return abbreviated ? Date.abbrMonthNames[this.getMonth()] : Date.monthNames[this.getMonth()];
    });
    add("getDayOfYear", function(){
        var tmpdtm = new Date("1/1/" + this.getFullYear());
        return Math.floor((this.getTime() - tmpdtm.getTime()) / 86400000);
    });
    add("getWeekOfYear", function(){
        return Math.ceil(this.getDayOfYear() / 7);
    });
    add("setDayOfYear", function(day){
        this.setMonth(0);
        this.setDate(day);
        return this;
    });
    add("addYears", function(num){
        this.setFullYear(this.getFullYear() + num);
        return this;
    });
    add("addMonths", function(num){
        var tmpdtm = this.getDate();
        this.setMonth(this.getMonth() + num);
        if (tmpdtm > this.getDate()) 
            this.addDays(-this.getDate());
        return this;
    });
    add("addDays", function(num){
        this.setDate(this.getDate() + num);
        return this;
    });
    add("addHours", function(num){
        this.setHours(this.getHours() + num);
        return this;
    });
    add("addMinutes", function(num){
        this.setMinutes(this.getMinutes() + num);
        return this;
    });
    add("addSeconds", function(num){
        this.setSeconds(this.getSeconds() + num);
        return this;
    });
    add("zeroTime", function(){
        this.setMilliseconds(0);
        this.setSeconds(0);
        this.setMinutes(0);
        this.setHours(0);
        return this;
    });
    add("asString", function(){
        var r = Date.format;
        var r = "rrrr-mm-dd";
        return r.replace(/(yyyy|rrrr)/i, this.getFullYear()).replace(/(yy|rr)/i, (this.getFullYear() + '').substring(2)).replace(/mmm/i, this.getMonthName(true)).replace(/mm/i, _zeroPad(this.getMonth() + 1)).replace(/dd/i, _zeroPad(this.getDate()));
    });
    Date.fromString = function(s){
        if (!s) 
            return new Date();
        var f = Date.format;
        var d = new Date('1977/01/01');
        var iY = f.indexOf('rrrr');
        if (iY > -1) {
            d.setFullYear(Number(s.substr(iY, 4)));
        }
        else {
            d.setFullYear(Number(Date.fullYearStart + s.substr(f.indexOf('rr'), 2)));
        }
        var iM = f.indexOf('mmm');
        if (iM > -1) {
            var mStr = s.substr(iM, 3);
            for (var i = 0; i < Date.abbrMonthNames.length; i++) {
                if (Date.abbrMonthNames[i] == mStr) 
                    break;
            }
            d.setMonth(i);
        }
        else {
            d.setMonth(Number(s.substr(f.indexOf('mm'), 2)) - 1);
        }
        d.setDate(Number(s.substr(f.indexOf('dd'), 2)));
        if (isNaN(d.getTime())) {
            return false;
        }
        return d;
    };
    var _zeroPad = function(num){
        var s = '0' + num;
        return s.substring(s.length - 2);
    };
})();
function isDate(string){
    var re = new RegExp("^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$", "i");
    if (re.test(string) == false || string == '') {
        return false;
    }
    return true;
}

function Calendar(selectedStr){
    this.date = new Date();
    this.html = '';
    this.selectedStr = (selectedStr);
}

Calendar.prototype.setDate = function(o){
    var n = new Date();
    this.month = (isNaN(o.month) || o.month == null) ? n.getMonth() : o.month;
    this.year = (isNaN(o.year) || o.year == null) ? n.getFullYear() : o.year;
    return {
        month: this.month,
        year: this.year
    };
}
Calendar.prototype.setLinkedDate = function(o){
    this.linkedDate = o;
}
Calendar.prototype.dateToObject = function(string){
    var s = Date.fromString(string);
    if (!s || s.getFullYear() < 0) 
        var s = new Date();
    return {
        day: s.getDate(),
        month: s.getMonth(),
        year: s.getFullYear()
    };
}
Calendar.prototype.go = function(go){
    var o = {
        month: this.month,
        year: this.year
    };
    if (go == "next" && o.month++ >= 11) {
        o.month = 0;
        o.year++;
    }
    if (go == "prev" && o.month-- <= 0) {
        o.month = 11;
        o.year--;
    }
    return o;
}
Calendar.prototype.build = function(p){
    this.generateMonth(this.selectedStr, p);
    for (i = 1; i < p.loop; i++) {
        this.setDate(this.go("next"));
        this.generateMonth(this.selectedStr, p);
    }
    return this.html;
}
Calendar.prototype.generateMonth = function(selectedStr, p){
    if (!this.month && !this.year) 
        this.setDate();
    var fd = new Date(this.year, this.month).getDay() - Date.firstDayOfWeek;
    var monthLength = new Date(this.year, this.month).getDaysInMonth();
    var monthName = Date.monthNames[this.month];
    var selected = new Date.fromString(selectedStr);
    var today = new Date().zeroTime();
    var maxOutDate = p.outBlock;
    var maxRetDate = p.inBlock;
    var blocked = new Date().zeroTime().addDays(p.blockedDays);
    var linked = (this.linkedDate) ? new Date(this.linkedDate.year, this.linkedDate.month, this.linkedDate.day).zeroTime() : false;
    var html = '<table class="calendar-table" cellpadding="0" cellspacing="0">';
    html += '<tr><th colspan="7">' + monthName + "&nbsp;" + this.year + '</th></tr>';
    html += '<tr class="calendar-header">';
    for (var i = Date.firstDayOfWeek, j = 0; i <= 12; i++) {
        html += '<td class="calendar-header-day">' + Date.abbrDayNames[(i > 6) ? i - 7 : i] + '</td>';
        if (j++ >= 6) 
            break;
    }
    html += '</tr><tr>';
    var day = 1;
    for (var i = 0; i < 9; i++) {
        for (var j = 0; j <= 6; j++) {
            html += '<td class="calendar-day">';
            if (day <= monthLength && (i > 0 || j >= ((fd >= 0) ? fd : 7 + fd))) {
                var calDay = new Date(this.year, this.month, day).zeroTime();
                css = 'month-day';
                css += (calDay - today == 0) ? ' is-today' : '';
                css += (calDay.isWeekend()) ? ' is-weekend' : '';
                css += (calDay < blocked) ? ' is-blocked' : '';
                css += (calDay < today) ? ' is-disabled' : '';
                css += (calDay - selected == 0) ? ' is-selected' : '';
                css += (linked && calDay < linked) ? ' is-linked-disabled' : '';
                css += (calDay < new Date().zeroTime().addDays(3) && calDay > new Date().zeroTime()) ? ' only-cc-payment' : '';
                css += (linked && calDay - linked == 0) ? ' is-linked' : '';
                css += (!linked && calDay > maxOutDate || linked && calDay > maxRetDate) ? ' is-out-of-range' : '';
                html += '<a class="' + css + '" rel="' + calDay.asString() + '">' + day + '</a>';
                day++;
            }
            else {
                html += '&nbsp;';
            }
            html += '</td>';
        }
        if (day > monthLength) {
            break;
        }
        else {
            html += '</tr><tr>';
        }
    }
    html += '</tr></table>';
    this.html += html;
    return this.html;
}
Calendar.prototype.buildEC = function(p){
    this.generateECMonth(this.selectedStr, p);
    for (i = 1; i < p.loop; i++) {
        this.setDate(this.go("next"));
        this.generateECMonth(this.selectedStr, p);
    }
    return this.html;
}
Calendar.prototype.generateECMonth = function(selectedStr, p){
    if (!this.month && !this.year) 
        this.setDate();
    var fd = new Date(this.year, this.month).getDay() - Date.firstDayOfWeek;
    var monthLength = new Date(this.year, this.month).getDaysInMonth();
    var monthName = Date.monthNames[this.month];
    var selected = new Date.fromString(selectedStr);
    var today = new Date().zeroTime();
    var eventDates = p.eventDates;
    var html = '<table class="calendar-table" cellpadding="0" cellspacing="0">';
    html += '<tr><th colspan="7">' + monthName + "&nbsp;" + this.year + '</th></tr>';
    html += '<tr class="calendar-header">';
    for (var i = Date.firstDayOfWeek, j = 0; i <= 12; i++) {
        html += '<td class="calendar-header-day">' + Date.abbrDayNames[(i > 6) ? i - 7 : i] + '</td>';
        if (j++ >= 6) 
            break;
    }
    html += '</tr><tr>';
    var day = 1;
    for (var i = 0; i < 9; i++) {
        for (var j = 0; j <= 6; j++) {
            html += '<td class="calendar-day">';
            if (day <= monthLength && (i > 0 || j >= ((fd >= 0) ? fd : 7 + fd))) {
                var calDay = new Date(this.year, this.month, day).zeroTime();
                css = 'month-day';
                css += (eventDates.indexOf(calDay.asString()) == -1) ? ' is-disabled' : ' has-event';
                css += (calDay - today == 0) ? ' is-today' : '';
                css += (calDay.isWeekend()) ? ' is-weekend' : '';
                css += (calDay - selected == 0) ? ' is-selected' : '';
                html += '<a class="' + css + '" rel="' + calDay.asString() + '">' + day + '</a>';
                day++;
            }
            else {
                html += '&nbsp;';
            }
            html += '</td>';
        }
        if (day > monthLength) {
            break;
        }
        else {
            html += '</tr><tr>';
        }
    }
    html += '</tr></table>';
    this.html += html;
    return this.html;
}
jQuery.extend({
    esky_calender_translate: {
        'OutGreaterThenReturn': 'Out date is greater then in date.',
        'OutDateToClose': 'Out date is to close to current date.',
        'DateOutOfRange': 'Selected date is out of range.'
    }
});
jQuery.fn.extend({
    esky_calendar_render: function(parameters){
        $this = $(this);
        var defaults = {
            thisInput: false,
            linkedInput: false,
            month: null,
            year: null,
            loop: 1,
            go: false,
            fade: false,
            outBlock: new Date().zeroTime().addDays(364),
            inBlock: new Date().zeroTime().addDays(363),
            blockedDays: 0,
            allowSameDay: false
        };
        var p = $.extend({}, defaults, parameters);
        var tI = document.getElementById(p.thisInput).value;
        var c = new Calendar(tI);
        if (p.linkedInput != false) {
            var lI = document.getElementById(p.linkedInput).value;
            if (p.thisInput != p.linkedInput && (!p.month && !p.year)) {
                $.extend(p, c.dateToObject(lI));
                c.setLinkedDate(c.dateToObject(lI));
            }
            if (p.thisInput != p.linkedInput && ((!p.month && !p.year) || p.go != false)) {
                c.setLinkedDate(c.dateToObject(lI));
            }
        }
        var d = (!p.month && !p.year) ? c.dateToObject(tI) : p;
        c.setDate(d);
        var pv = $.extend({}, p, c.go("prev"), {
            go: "prev"
        });
        var px = $.extend({}, p, c.go("next"), {
            go: "next"
        });
        var cd = new Date();
        var pc = $.extend({}, p, {
            month: cd.getMonth(),
            year: cd.getFullYear(),
            go: true
        });
        $this.html(c.build(p)).prepend($('<div class="calendar-navigation"></div>').prepend($('<a href="javascript:void(0);" class="calendar-button calendar-next" title="' + cal_text.NEXT + '">&raquo;</a>').click(function(e){
            $this.esky_calendar_render(px);
            e.stopPropagation();
        })).prepend($('<a href="javascript:void(0);" class="calendar-button calendar-current">' + cal_text.THISMONTH + '</a>').click(function(){
            $this.esky_calendar_render(pc)
        })).prepend($('<a href="javascript:void(0);" class="calendar-button calendar-previous" title="' + cal_text.PREV + '">&laquo;</a>').click(function(e){
            $this.esky_calendar_render(pv);
            e.stopPropagation();
        }))).append($('<div class="calendar-navigation"></div>').prepend($('<a href="javascript:void(0);" class="calendar-button calendar-close">' + cal_text.CLOSE + '</a>').click(function(){
            $this.remove()
        })));
        $('a.month-day').not('.is-disabled,.is-blocked').click(function(){
            $('#' + p.thisInput).not(':disabled').val($(this).attr('rel')).removeClass('virgin').blur();
            if (typeof(calculateCheckoutDate) == 'function') 
                calculateCheckoutDate(p.thisInput);
            $this.remove();
        }).mouseover(function(){
            $(this).addClass('is-hover');
        }).mouseout(function(){
            $(this).removeClass('is-hover');
        });
        if (p.allowSameDay == false) {
            $('a.is-linked').not('.is-disabled').unbind().click(function(){
                return false;
            });
        }
        $('a.is-blocked').not('.is-disabled,.is-linked,.is-linked-disabled').unbind().click(function(){
            return false;
        });
        $('a.is-out-of-range').unbind().click(function(){
            return false;
        });
        $('a.is-disabled,a.is-linked-disabled').unbind().click(function(){
            return false;
        });
        $this.bgIframe();
        return $this;
    },
    esky_calendar: function(parameters){
        if ($('#esky_calendar').size() > 0) {
            $('#esky_calendar').remove();
            return false;
        }
        var $this = $(this);
        var input = $('#' + $this.attr('rel'));
        var xy = input.offset();
        $('body').append($('<div></div>').attr('id', 'esky_calendar').css({
            position: 'absolute',
            top: xy.top + input.height() + 8,
            left: xy.left
        }).hide());
        if (parameters.fade > 0) {
            $('#esky_calendar').esky_calendar_render(parameters).fadeIn(parameters.fade);
        }
        else {
            $('#esky_calendar').esky_calendar_render(parameters).show();
        }
        return $this;
    },
    event_calendar_render: function(parameters){
        $this = $(this);
        var defaults = {
            month: null,
            year: null,
            loop: 1,
            go: false,
            blockedDays: 0,
            eventDates: null
        };
        var p = $.extend({}, defaults, parameters);
        var today = new Date();
        var tI = today.asString();
        var c = new Calendar($this.attr('title'));
        var d = (!p.month && !p.year) ? c.dateToObject(tI) : p;
        c.setDate(d);
        var pv = $.extend({}, p, c.go("prev"), {
            go: "prev"
        });
        var px = $.extend({}, p, c.go("next"), {
            go: "next"
        });
        var cd = new Date();
        var pc = $.extend({}, p, {
            month: cd.getMonth(),
            year: cd.getFullYear(),
            go: true
        });
        $this.html(c.buildEC(p)).prepend($('<div class="calendar-navigation"></div>').prepend($('<a href="javascript:void(0);" class="calendar-button calendar-next" title="' + cal_text.NEXT + '">&raquo;</a>').click(function(e){
            $this.event_calendar_render(px);
            e.stopPropagation();
        })).prepend($('<a href="javascript:void(0);" class="calendar-button calendar-previous" title="' + cal_text.PREV + '">&laquo;</a>').click(function(e){
            $this.event_calendar_render(pv);
            e.stopPropagation();
        })));
        $this.slideDown('normal');
    },
    event_calendar: function(){
        var $this = $(this);
        $.post(ibeConfig.pressCalendar, null, function(data){
            $this.event_calendar_render({
                eventDates: data
            });
        });
        return $this;
    }
});

