﻿/*Date.prototype.stdTimezoneOffset = function () {
    var jan = new Date(this.getFullYear(), 0, 1);
    var jul = new Date(this.getFullYear(), 6, 1);
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}

Date.prototype.dst = function () {
    return this.getTimezoneOffset() < this.stdTimezoneOffset();
}*/

var mzClock = new Class({

    options: {
        width: 51,
        height: 50,
        hour: { centerx: 25, centery: 25, lenght: 40, width: 2, color: "#000000" },
        minute: { centerx: 25, centery: 25, lenght: 40, width: 2, color: "#000000" },
        second: { centerx: 25, centery: 25, lenght: 10, width: 2, color: "#000000" },
        pin: { centerx: 25, centery: 25, width: 1, color: "#000000" },
        timeSpanClass: "timetext",
        timeZoneRegion: "Europe",
        timeZoneOffset: 1,
        useSeconds: true
    },

    initialize: function (element, options) {

        this.setOptions(options);

        this.element = element;
        this.spantime = this.element.getElement("span[class=" + this.options.timeSpanClass + "]");

        this.canvas = Raphael(this.element, this.options.width, this.options.height);

        this.hour_hand = this.canvas.path("M" + this.options.hour.centerx + " " + this.options.hour.centery + "L" + this.options.hour.centerx + " " + this.options.hour.lenght);
        this.hour_hand.attr({ stroke: this.options.hour.color, "stroke-width": this.options.hour.width });
        this.minute_hand = this.canvas.path("M" + this.options.minute.centerx + " " + this.options.minute.centery + "L" + this.options.minute.centerx + " " + this.options.minute.lenght);
        this.minute_hand.attr({ stroke: this.options.minute.color, "stroke-width": this.options.minute.width });
        if (this.options.useSeconds) {
            this.second_hand = this.canvas.path("M" + this.options.second.centerx + " " + this.options.second.centery + "L" + this.options.second.centerx + " " + this.options.second.lenght);
            this.second_hand.attr({ stroke: this.options.second.color, "stroke-width": this.options.second.width });
        }
        this.pin = this.canvas.circle(this.options.pin.centerx, this.options.pin.centerx, this.options.pin.width);
        this.pin.attr("fill", this.options.pin.color);

        this.update();

        window.setTimeout(this.update.bind(this), 1000);

    },

    update: function () {

        var dst = 0
        var time = new Date()
        var gmtTime = new Date(time.getTime() + (time.getTimezoneOffset() * 60000))

        var day = gmtTime.getDate()
        var month = gmtTime.getMonth()
        var year = gmtTime.getYear()
        if (year < 1000) {
            year += 1900
        }

        var hr = gmtTime.getHours() + this.options.timeZoneOffset
        var min = gmtTime.getMinutes()
        var sec = gmtTime.getSeconds()

        if (hr >= 24) {
            hr = hr - 24
        }
        if (hr < 0) {
            hr -= -24
        }

        var startDST = new Date()
        var endDST = new Date()
        var currentTime = new Date()
        currentTime.setMonth(month)
        currentTime.setYear(year)
        currentTime.setDate(day)
        currentTime.setHours(hr)

        switch (this.options.timeZoneRegion) {
            case "NAmerica":
                startDST.setMonth(3)
                startDST.setHours(2)
                startDST.setDate(1)
                var dayDST = startDST.getDay()
                if (dayDST != 0) {
                    startDST.setDate(8 - dayDST)
                }
                else {
                    startDST.setDate(1)
                }
                endDST.setMonth(9)
                endDST.setHours(1)
                endDST.setDate(31)
                dayDST = endDST.getDay()
                endDST.setDate(31 - dayDST)
                if (currentTime >= startDST && currentTime < endDST) {
                    dst = 1
                }
                break;
            case "Europe":
                startDST.setMonth(2)
                startDST.setHours(1)
                startDST.setDate(31)
                var dayDST = startDST.getDay()
                startDST.setDate(31 - dayDST)
                endDST.setMonth(9)
                endDST.setHours(0)
                endDST.setDate(31)
                dayDST = endDST.getDay()
                endDST.setDate(31 - dayDST)
                if (currentTime >= startDST && currentTime < endDST) {
                    dst = 1
                }
                break;
            case "SAmerica":
                startDST.setMonth(9)
                startDST.setHours(0)
                startDST.setDate(1)
                var dayDST = startDST.getDay()
                if (dayDST != 0) {
                    startDST.setDate(22 - dayDST)
                }
                else {
                    startDST.setDate(15)
                }
                endDST.setMonth(1)
                endDST.setHours(11)
                endDST.setDate(1)
                dayDST = endDST.getDay()
                if (dayDST != 0) {
                    endDST.setDate(21 - dayDST)
                }
                else {
                    endDST.setDate(14)
                }
                if (currentTime >= startDST || currentTime < endDST) {
                    dst = 1
                }
                break;
            case "Cairo":
                startDST.setMonth(3)
                startDST.setHours(0)
                startDST.setDate(30)
                var dayDST = startDST.getDay()
                if (dayDST < 5) {
                    startDST.setDate(28 - dayDST)
                }
                else {
                    startDST.setDate(35 - dayDST)
                }
                endDST.setMonth(8)
                endDST.setHours(11)
                endDST.setDate(30)
                dayDST = endDST.getDay()
                if (dayDST < 4) {
                    endDST.setDate(27 - dayDST)
                }
                else {
                    endDST.setDate(34 - dayDST)
                }
                if (currentTime >= startDST && currentTime < endDST) {
                    dst = 1
                }
                break;
            case "Israel":
                startDST.setMonth(3)
                startDST.setHours(2)
                startDST.setDate(1)
                endDST.setMonth(8)
                endDST.setHours(2)
                endDST.setDate(25)
                dayDST = endDST.getDay()
                if (dayDST != 0) {
                    endDST.setDate(32 - dayDST)
                }
                else {
                    endDST.setDate(1)
                    endDST.setMonth(9)
                }
                if (currentTime >= startDST && currentTime < endDST) {
                    dst = 1
                }
                break;
            case "Beirut":
                startDST.setMonth(2)
                startDST.setHours(0)
                startDST.setDate(31)
                var dayDST = startDST.getDay()
                startDST.setDate(31 - dayDST)
                endDST.setMonth(9)
                endDST.setHours(11)
                endDST.setDate(31)
                dayDST = endDST.getDay()
                endDST.setDate(30 - dayDST)
                if (currentTime >= startDST && currentTime < endDST) {
                    dst = 1
                }
                break;
            case "Baghdad":
                startDST.setMonth(3)
                startDST.setHours(3)
                startDST.setDate(1)
                endDST.setMonth(9)
                endDST.setHours(3)
                endDST.setDate(1)
                dayDST = endDST.getDay()
                if (currentTime >= startDST && currentTime < endDST) {
                    dst = 1
                }
                break;
            case "Australia":
                startDST.setMonth(9)
                startDST.setHours(2)
                startDST.setDate(31)
                var dayDST = startDST.getDay()
                startDST.setDate(31 - dayDST)
                endDST.setMonth(2)
                endDST.setHours(2)
                endDST.setDate(31)
                dayDST = endDST.getDay()
                endDST.setDate(31 - dayDST)
                if (currentTime >= startDST || currentTime < endDST) {
                    dst = 1
                }
                break;
        }

        if (dst == 1) hr -= -1;
        if (hr >= 24) {
            hr = hr - 24
        }

        this.hour_hand.rotate(30 * hr + (min / 2.5), this.options.hour.centerx, this.options.hour.centery);
        this.minute_hand.rotate(6 * min, this.options.minute.centerx, this.options.minute.centery);
        if (this.options.useSeconds) this.second_hand.rotate(6 * sec, this.options.second.centerx, this.options.second.centery);

        this.spantime.setHTML(hr + ":" + ((min < 10) ? "0" + min : min) + ":" + ((sec < 10) ? "0" + sec : sec));

        window.setTimeout(this.update.bind(this), 1000);

    }


});

mzClock.implement(new Options);


