﻿/**********************************************************************
*          Calendar JavaScript [DOM] v3.09 by Michael Loesler          *
************************************************************************
* Copyright (C) 2005-08 by Michael Loesler, http//derletztekick.com    *
*                                                                      *
*                                                                      *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or    *
* (at your option) any later version.                                  *
*                                                                      *
* This program is distributed in the hope that it will be useful,      *
* but WITHOUT ANY WARRANTY; without even the implied warranty of       *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
* GNU General Public License for more details.                         *
*                                                                      *
* You should have received a copy of the GNU General Public License    *
* along with this program; if not, see <http://www.gnu.org/licenses/>  *
* or write to the                                                      *
* Free Software Foundation, Inc.,                                      *
* 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.            *
*                                                                      *
 **********************************************************************/

function CalendarJS() {
    this.now = new Date();
    this.dayname = ["Mo","Di","Mi","Do","Fr","Sa","So"];
    this.monthname = ["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"];	
    this.tooltip = ["vorheriger Monat","nächster Monat","aktuelles Datum"];
    this.monthCell = document.createElement("th");
    this.tableHead = null;
    this.parEl = null;
    
    this.init = function( elem ) {
        this.date = this.now.getDate();
        this.month = this.mm = this.now.getMonth();
        this.year = this.yy = this.now.getFullYear();
        this.elem = $(elem);
        this.monthCell.colSpan = 5;
        this.monthCell.appendChild(document.createTextNode( this.monthname[this.mm]+" "+this.yy ));
        this.tableHead = this.createTableHead();
        this.parEl = this.newElement("calendar");
        this.show();
        this.checkDate();
    },   

    this.newElement = function( id ){
        var elem            = document.createElement("div");
        
        document.body.appendChild(elem);

        elem.id             = id;

        coords              = this.elem.getCoordinates();

        elem.style.display  = "none";
        elem.style.position = "absolute";
        elem.style.width    = "174px";
        elem.style.left     = ((Browser  &&  Browser.Engine  &&  Browser.Engine.gecko)  ?  coords.left  :  0) + "px";
        elem.style.top      = (coords.top + coords.height) + "px";

        return elem;
    }

    this.checkDate = function() {
        var self = this;
        var today = new Date();
        if (this.date != today.getDate()) {
            this.date  = today.getDate();
            if (this.mm == this.month && this.yy == this.year)
                this.switchMonth("current");
            this.month = today.getMonth();
            if (this.mm == this.month && this.yy == this.year)
                this.switchMonth("current");
            this.year  = today.getFullYear();
            if (this.mm == this.month && this.yy == this.year)
                this.switchMonth("current");

        }
        window.setTimeout(function() { self.checkDate(); }, Math.abs(new Date(this.year, this.month, this.date, 24, 0, 0)-this.now));
    },
    
    this.removeElements = function( Obj ) {
        for (var i=0; i<Obj.childNodes.length; i++)
            Obj.removeChild(Obj.childNodes[i]);
        return Obj;
    },
        
    this.show = function() {
        this.parEl = this.removeElements( this.parEl );
        this.monthCell.firstChild.replaceData(0, this.monthCell.firstChild.nodeValue.length, this.monthname[this.mm]+" "+this.yy);
        var table = document.createElement("table");
        table.appendChild( this.createTableBody() );
        table.appendChild( this.tableHead );
        this.parEl.appendChild( table );
        this.parEl.style.display = "block";
    },
            
    this.createTableHead = function() {
        var thead = document.createElement("thead");
        var tr = document.createElement("tr");
        var th = this.getCell( "th", "\u00AB", "last_month" )
        th.Instanz = this;
        th.onclick = function() { this.Instanz.switchMonth("prev"); };
        th.title = this.tooltip[0];
        try { th.style.cursor = "pointer"; } catch(e){ th.style.cursor = "hand"; }
        tr.appendChild( th );
        this.monthCell.Instanz = this;
        this.monthCell.onclick = function() { this.Instanz.switchMonth("current"); };
        this.monthCell.title = this.tooltip[2];
        try { this.monthCell.style.cursor = "pointer"; } catch(e){ this.monthCell.style.cursor = "hand"; }
        tr.appendChild( this.monthCell );			
        th = this.getCell( "th", "\u00BB", "next_month" )
        th.Instanz = this;
        th.onclick = function() { this.Instanz.switchMonth("next"); };
        th.title = this.tooltip[1];
        try { th.style.cursor = "pointer"; } catch(e){ th.style.cursor = "hand"; }
        tr.appendChild( th );
        thead.appendChild( tr );
        tr = document.createElement('tr');
        for (var i=0; i<this.dayname.length; i++)
            tr.appendChild( this.getCell("th", this.dayname[i], "weekday" ) );
        thead.appendChild( tr );
        return thead;
    },
    
    this.createTableBody = function() {
        var dayspermonth = [31,28,31,30,31,30,31,31,30,31,30,31];
        var sevendaysaweek = 0;
        var begin = new Date(this.yy, this.mm, 1);
        var firstday = begin.getDay()-1;
        if (firstday < 0)
            firstday = 6;
        if ((this.yy%4==0) && ((this.yy%100!=0) || (this.yy%400==0)))
            dayspermonth[1] = 29;
        var tbody = document.createElement("tbody");
        var tr = document.createElement('tr');
        if (firstday == 0) {
            for (var i=0; i<this.dayname.length; i++) {
                var prevMonth = (this.mm == 0)?11:this.mm-1;
                tr.appendChild( this.getCell( "td", dayspermonth[prevMonth]-6+i, "last_month" ) );
            }
            tbody.appendChild( tr );
            tr = document.createElement('tr');
        }
        
        for (var i=0; i<firstday; i++, sevendaysaweek++) {
            var prevMonth = (this.mm == 0)?11:this.mm-1;
            tr.appendChild( this.getCell( "td", dayspermonth[prevMonth]-firstday+i+1, "last_month" ) );
            
        }

        for (var i=1; i<=dayspermonth[this.mm]; i++, sevendaysaweek++){
            if (this.dayname.length == sevendaysaweek){
                tbody.appendChild( tr );
                tr = document.createElement('tr');
                sevendaysaweek = 0;
            }
            if (i==this.date && this.mm==this.month && this.yy==this.year && (sevendaysaweek == 5 || sevendaysaweek == 6))
                tr.appendChild( this.getCell( "td", i, "today weekend", true ) );
            else if (i==this.date && this.mm==this.month && this.yy==this.year)
                tr.appendChild( this.getCell( "td", i, "today", true ) );
            else if (sevendaysaweek == 5)
                tr.appendChild( this.getCell( "td", i, "saturday weekend", true ) );
            else if (sevendaysaweek == 6)
                tr.appendChild( this.getCell( "td", i, "sunday weekend", true ) );
            else
                tr.appendChild( this.getCell( "td", i, null, true ) );
        }

        var daysNextMonth = 1;
        for (var i=sevendaysaweek; i<this.dayname.length; i++) 
            tr.appendChild( this.getCell( "td", daysNextMonth++, "next_month"  ) );
            
        tbody.appendChild( tr );
        
        while (tbody.getElementsByTagName("tr").length<6) {
            tr = document.createElement('tr');
            for (var i=0; i<this.dayname.length; i++) 
                tr.appendChild( this.getCell( "td", daysNextMonth++, "next_month"  ) );
            tbody.appendChild( tr );
        }
    
        var tr = document.createElement('tr');
        var td = document.createElement('td');

        td.setAttribute("colspan", "7");
        td.style.textAlign = "center";
        td.style.cursor = "pointer";
        td.onclick = this.destroy.bind(this);
        td.appendChild( document.createTextNode( "Kalender schliessen" ) );
        
        tr.appendChild( td );
        tbody.appendChild( tr );
        
        return tbody;
        
    },
    
    this.getCell = function(tag, str, cssClass, clickable) {
        var El = document.createElement( tag );
        El.appendChild(document.createTextNode( str ));
        if (cssClass != null) {
            El.className = cssClass;
        }

        if (clickable)
        {
            El.style.cursor = "pointer";
            El.className    = El.className + " hlable";

            El.onclick = function()
            {
                d = str;
                m = this.mm + 1;
                y = this.yy;
                
                d = (d < 10 ? '0'+d : d);
                m = (m < 10 ? '0'+m : m);
                y = y;
                
                this.elem.value = d+'.'+m+'.'+y;

                this.destroy();
            }.bind(this);
        }
        
        return El;
    },
    
    this.switchMonth = function( s ){
        switch (s) {
            case "prev": 
                this.yy = (this.mm == 0)?this.yy-1:this.yy;
                this.mm = (this.mm == 0)?11:this.mm-1;
            break;
            
            case "next":
                this.yy = (this.mm == 11)?this.yy+1:this.yy;
                this.mm = (this.mm == 11)?0:this.mm+1;
            break;
            
            case "current":
                this.yy = this.year;
                this.mm = this.month;
            break;
        }
        this.show();
    }

    this.destroy = function(){
        this.parEl.parentNode.removeChild(this.parEl);
    }
}
