﻿


/*

Diese Klasse stellt die Funktionen für den Plan mit dem Balken zur Verfügung.

Greift auf resGrid zu.

*/

var resPlan = new Class({
    Implements: Options,
    options: {
        barsdiv: null,
        hourwidth: 20,
        rowheight: 20,
        starthour: 16,
        endhour: 22,
        deltax: 240,
        deltay: 0,
        gaplevel0: 3,
        date: null,
        timescaleobj: null,
        gridobj: null,
        events: null,
        rooms: null,
        currdate: null
    },
    initialize: function(gridobj, options) {
        this.setOptions(options);

        this.bararray = new Array();

        this.gridobj = gridobj;

        this.mouseIsOnBar = null;
    },

    /* removes all bars from the grid */
    clearBars: function() {

        for (var i = 0; i < this.bararray.length; i++) {
            this.bararray[i].destroy();
        }
        this.bararray.empty();

    },

    /* 
    positioniert die veranstaltung als balken auf jeder raumzeile. findet eine veranstaltung in 
    drei räumen statt werden auch drei balken für diese veranstaltung gezeichnet.
    */
    positionizeEvents: function() {


        // keine events vorhanden oder keine räume vorhanden, dann mach nix
        if (this.options.events == null || this.options.rooms == null)
            return;

        // was sehen wir im plan? setzte start- und endedatum (z.B. 15.08.1981 8:00 - 15.08.1981 19:00)
        this.startdate = new Date(this.currdate.getFullYear(), this.currdate.getMonth(), this.currdate.getDate(), this.options.starthour, 0, 0);
        this.enddate = new Date(this.currdate.getFullYear(), this.currdate.getMonth(), this.currdate.getDate(), this.options.endhour, 0, 0);

        // entferne alle bestehenden balken
        this.clearBars();

        // array mit allen relevanten veranstaltungen
        var relevantevents = new Array();

        // für jede veranstaltung
        for (var i = 0; i < this.options.events.length; i++) {

            var event = this.options.events[i];

            // für jeden raum in der veranstaltung stattfinden
            for (var j = 0; j < event.Rooms.length; j++) {

                var room = event.Rooms[j];

                // erzeuge einen balken
                this.createBar(event, room);
            }
        }

        this.gridobj.setLocked();

    },

    highlightEvent: function(ev) {

        //var e = new Event(ev);
        var eventID = ev.target.rel;

        this.mouseIsOnBar = eventID;
        for (var i = 0; i < this.bararray.length; i++) {

            var bar = this.bararray[i];

            if (bar.rel == eventID) {

                bar.setStyle("background-image", bar.getStyle('background-image').replace("_off", "_on"));


            }
        }

        //this.showEventDetail.bind(this).delay(3000);

    },

    unhighlightEvent: function(ev) {

        this.mouseIsOnBar = null;

        //var e = new Event(ev);
        var eventID = ev.target.rel;


        for (var i = 0; i < this.bararray.length; i++) {

            var bar = this.bararray[i];

            if (bar.rel == eventID) {

                bar.setStyle("background-image", bar.getStyle('background-image').replace("_on", "_off"));


            }
        }

    },

    showEventDetail: function() {

        if (this.mouseIsOnBar != null)
            new mooPopup({ dockelem: ev.target, deltay: -$('plandiv').scrollTop, dockelempos: "center", width: 350, headline: event.Name, content: new PopupHtmlWriter({ eventobj: event }).writeEventDetail() });
    },

    /* stellt eine veranstaltung als balken dar (für den übergebenen raum) */
    createBar: function(event, room) {

        // wenn die zeit ausserhalb ist dann zeige nichts an
        if (event.StartDate.getHours() > this.options.endhour && event.StartDate <= this.date) {
            return;
        }

        // wenn die zeit ausserhalb ist dann zeige nichts an
        if (event.EndDate.getHours() < this.options.starthour && event.StartDate >= this.date)
            return;

        // hole die maximal breite
        this.maxx = ((this.options.endhour - this.options.starthour) * this.options.hourwidth) + this.options.deltax;

        // der standardbalken
        var classname = "balken";

        // wenn anfrage provisorisch dann mache balken grau
        if (event.State < 1)
            classname = "balken_gray";

        // erzeuge div-element
        var div = new Element("div", { "class": classname, "html": event.Name });

        // id des events
        div.title = event.ID;

        // öffentlich oder privat?
        if (event.PublicityState == 0)
            div.innerHTML = "&nbsp;"
        else
            div.title = event.Name;

        // hole die breite und position des balkens....
        var dim = this.getBarDimensions(event);

        // ...und übertrage diese auf das div element

        if (dim.width > 0) {

            // left (startzeit) und top (abhängig von raum)
            div.style.left = dim.x + "px";
            div.style.top = (this.getPosY(room) + this.options.deltay) + "px";
            div.rel = event.ID;

            // breite des balkens (minus padding)
            var w = dim.width - div.getStyle("padding-left").toInt() - div.getStyle("padding-right").toInt();

            // IE ragt am Ende etwas über den Plan
            if (Browser.Engine.trident == true)
                w -= 4;

            // übernahme auf element
            if (w.toString() == 'NaN') // chrome
                div.style.width = dim.width + "px";
            else
                div.style.width = w + "px";


            div.addEvent("mouseenter", this.highlightEvent.bind(this));
            div.addEvent("mouseleave", this.unhighlightEvent.bind(this));
         
            // mausevents für hauptbalken
            div.addEvent("click", function(ev) {
                
                if (event.PublicityState == 1)
                    new mooPopup({ dockelem: ev.target, ydelta: $('plandiv').scrollTop, dockelempos: "center", width: 350, headline: event.Name, content: new PopupHtmlWriter({ eventobj: event }).writeEventDetail() });
                else
                    new mooPopup({ dockelem: ev.target, ydelta: $('plandiv').scrollTop, dockelempos: "center", width: 350, headline: "Private Veranstaltung", content: "Veranstaltung ist privat. Keine Details verfügbar. " });
            });

            // füge in plan ein (absolutes div in relativen div)
            $('plandiv').appendChild(div);

            // füge zu array mit allen balken
            this.bararray.push(div);
        }


        // vorlaufzeit
        if (dim.widthpre > 0) {

            var divpre = new Element("div", { "class": classname + "_pre", "html": "&nbsp;" });
            divpre.style.left = dim.xpre + "px";
            divpre.style.top = (this.getPosY(room) + this.options.deltay) + "px";
            divpre.rel = event.ID;
            divpre.title = "Vorlaufzeit";

            var w = (dim.widthpre - divpre.getStyle("padding-left").toInt() - divpre.getStyle("padding-right").toInt());

            if (w.toString() == 'NaN') // chrome
                divpre.style.width = dim.widthpre + "px";
            else
                divpre.setStyle("width", w);


            $('plandiv').appendChild(divpre);
            this.bararray.push(divpre);

            divpre.addEvent("mouseenter", this.highlightEvent.bind(this));
            divpre.addEvent("mouseleave", this.unhighlightEvent.bind(this));

            //            divpre.addEvent("mouseenter", function(ev) {
            //                ev.target.setStyle("background-image", ev.target.getStyle('background-image').replace("_off", "_on"));
            //            });

            //            divpre.addEvent("mouseleave", function(ev) {
            //                ev.target.setStyle("background-image", ev.target.getStyle('background-image').replace("_on", "_off"));
            //            });

            divpre.addEvent("click", function(ev) {
                if (event.PublicityState == 1)
                    new mooPopup({ dockelem: ev.target, ydelta: $('plandiv').scrollTop, dockelempos: "center", width: 350, headline: event.Name, content: new PopupHtmlWriter({ eventobj: event }).writeEventDetail() });
                else
                    new mooPopup({ dockelem: ev.target, ydelta: $('plandiv').scrollTop, dockelempos: "center", width: 350, headline: "Private Veranstaltung", content: "Vorlaufzeit" });
            });
        }

        // nachlaufzeit
        if (dim.widthpost > 0) {
            var divpost = new Element("div", { "class": classname + "_post", "html": "&nbsp;" });
            divpost.style.left = dim.xpost + "px";
            divpost.style.top = (this.getPosY(room) + this.options.deltay) + "px";
            divpost.rel = event.ID;
            divpost.title = "Nachlaufzeit";

            if (dim.widthpost > 0)
                divpost.style.width = (dim.widthpost) + "px";

            this.bararray.push(divpost);
            $('plandiv').appendChild(divpost);


            divpost.addEvent("mouseenter", this.highlightEvent.bind(this));
            divpost.addEvent("mouseleave", this.unhighlightEvent.bind(this));


            divpost.addEvent("click", function(ev) {
                if (event.PublicityState == 1)
                    new mooPopup({ dockelem: ev.target, ydelta: $('plandiv').scrollTop, dockelempos: "center", width: 350, headline: event.Name, content: new PopupHtmlWriter({ eventobj: event }).writeEventDetail() });
                else
                    new mooPopup({ dockelem: ev.target, ydelta: $('plandiv').scrollTop, dockelempos: "center", width: 350, headline: "Private Veranstaltung", content: "Nachlaufzeit" });
            });
        }




        //        div.addEvent("mouseenter", function(ev) {

        //            if (event.PublicityState == 1)
        //                new mooPopup({ dockelem: ev.target, dockelempos: "center", width: 350, headline: event.Name, content: new PopupHtmlWriter({ eventobj: event }).writeEventDetail() });
        //            else
        //                new mooPopup({ dockelem: ev.target, dockelempos: "center", width: 350, headline: "Private Veranstaltung", content: "Veranstaltung ist privat. Keine Details verfügbar. " });
        //        });



    },

    /*  */
    getBarDimensions: function(event) {

        var dim = new BarDimensions();

        dim.xpre = -1;
        dim.xpost = -1;
        //dim.x = this.getPosX(event);
        //dim.width =  this.getBarWidth(event);

        // wenn event in unserem bereich ist
        if (this.isInRange2(event.StartDate, event.EndDate)) {
            dim.x = this.gridobj.getX(event.StartDate);
            dim.width = this.gridobj.getX(event.EndDate) - dim.x;

        }

        // wenn event inkl. vorlaufzeiten in unserem bereich ist
        if ((event.DatePreStart.getFullYear() != 1 && event.DatePreStart != event.StartDate) && (this.isInRange2(event.DatePreStart, event.StartDate))) {
            dim.xpre = this.gridobj.getX(event.DatePreStart);

            // wenn der start der anwendung ausserhalb des bereiches ist (nachher)
            if (event.StartDate > this.enddate) {
                dim.widthpre = this.gridobj.getX(event.StartDate) - dim.xpre;
            }
            else
                dim.widthpre = dim.x - dim.xpre;
        }

        if ((event.DatePostEnd.getFullYear() != 1 && event.DatePostEnd > event.EndDate) && (this.isInRange2(event.EndDate, event.DatePostEnd))) {

            dim.xpost = dim.x + dim.width;

            if (dim.xpost == 0)
                dim.xpost = this.gridobj.getX(event.DatePreStart);

            dim.widthpost = this.gridobj.getX(event.DatePostEnd) - dim.xpost;
            //alert(dim.widthpost + "=" + this.gridobj.getX(event.DatePostEnd) + "-" + dim.xpost);
        }

        if (dim.xpre < -1)
            dim.xpre = dimxpre * (-1);

        if (dim.widthpre < -1)
            dim.widthpre = dim.widthpre * (-1);

        //        if ((dim.x + dim.width) > this.maxx)
        //            dim.width = this.maxx - dim.x;
        return dim;

    },

    /* definiere die breite des event-balkens */
    getBarWidth: function(event) {

        var x = 0;

        // berechne die dauer (auf viertelstunde genau)

        var dduration = getTimeDiff(event.EndDate, event.StartDate);

        if (event.LastsAllDay == true || (event.StartDate.getDate() < calendar.currdate.getDate() && event.EndDate.getDate() > calendar.currdate.getDate())) {

            var duration = this.options.endhour.toInt() - this.options.starthour.toInt();

            if (duration > 0)
                return duration * this.options.hourwidth;

        } else {

            if (event.EndDate.getHours() > this.options.endhour)
                duration = event.EndDate.getHours() - this.options.endhour;
        }

        var q = 0;

        var hmin = dduration.getMinutes();

        if (hmin >= 15 && hmin < 30)
            q = 0.25;
        else if (hmin >= 30 && hmin < 45)
            q = 0.5;
        else if (hmin >= 45)
            q = 0.75;


        if (dduration.getHours() > 0)
            x = ((dduration.getHours() - 1) + q) * (this.options.hourwidth);


        return x;

    },

    /* definiere die x-position des events */
    getPosX: function(event) {

        var x = 0;

        // hole die anfangstunde des events als dezimal (auf viertelstunde genau)
        var sh = this.getHourDecimal(event.StartDate);

        // berechne die stundenanzahl abhängig von anfang der zeitskala
        var hours = sh.toFloat() - this.options.starthour.toFloat();

        if (hours > 0) {
            // multiplizere stundenanzahl * die breite einer zelle
            x = hours * this.options.hourwidth;
        } else if (hours < 0)
            x = 0;

        //alert("startstunde:" + sh + ";breite:" + this.options.hourwidth + ";x:" + x + ";deltax:" + this.options.deltax + ";fullx:" + (x + this.options.deltax));

        // gib x zurück
        return x + this.options.deltax;

    },

    /* ladet alle events des aktuellen monat und jahres */
    getPosY: function(room) {

        var y = 0;

        return this.options.gridobj.getYPosOfRoom(room.ID);

        var pos = this.options.gridobj.getPositionOfRoom(room.ID);

        if (pos > 0)
            y = pos * this.options.gridobj.options.rowheight;

        return y + this.options.deltay;


    },

    /* ladet alle events des aktuellen monat und jahres */
    fillDropdowns: function() {

        for (var i = 0; i <= 24; i++) {
            this.options.startdropdown.options[i] = new Option(i, i);
            this.options.enddropdown.options[i] = new Option(i, i);
        }

    },

    /* ladet alle events des aktuellen monat und jahres */
    calculateHourWidth: function() {

        this.options.hourwidth = (this.options.w / (this.options.hours + 1)).toInt();
        //this.options.hourwidth -= 1;

    },

    /* ladet alle events des aktuellen monat und jahres */
    getHourDecimal: function(date) {

        var h = date.getHours();


        var hmin = date.getMinutes();

        var q = 0;

        if (hmin >= 15 && hmin < 30)
            q = 0.25;
        else if (hmin >= 30 && hmin < 45)
            q = 0.5;
        else if (hmin >= 45)
            q = 0.75;

        return h + q;

    },

    /* ladet alle events des aktuellen monat und jahres */
    toUnit: function(hours, minutes) {

        var u = (hours / 2).toInt();

        if (minutes >= 30)
            u += 1;

        return h;

    },

    /* True wenn sich der übergebene datumsbereich mit dem angezeigten bereich (this.startdate - this.enddate) überschneidet. */
    isInRange2: function(dfrom, duntil) {

        if (dfrom <= this.startdate && duntil >= this.enddate) {
            return true;
        } else if (this.startdate <= dfrom && this.enddate >= dfrom) {
            return true;
        } else if (this.startdate <= duntil && this.enddate >= duntil) {
            return true;
        }

        return false;

    },

    /* True wenn sich datum im Zeitplan befindet. */
    isInRange: function(date) {

        if (this.startdate < date && this.enddate > date) {
            return true;
        }

        return false;
    },

    OnMainBarMouseEnter: function() {


    }
});



function BarDimensions()
{
    this.y = 0;
    this.x = 0;
    this.width = 0;

    this.xpre = 0;
    this.widthpre = 0;
    this.xpost = 0;
    this.widthpost = 0;
    
}
