﻿/*
    Diese Klasse erzeugt das Raster.
*/

var resGrid = new Class({
    Implements: Options,
    options: {
        tablediv: null,         // das element, welches die tabelle enthält
        tableid: 'gridtable',   // id der tabelle
        colwidth: 20,           // breite der tabellenspalten
        rowheight: 20,          // höhe der tabellenzeilen
        starthour: 16,          // start der skala (uhrzeit stunde)
        endhour: 22,            // ende der skala (uhrzeit stunde) 
        timescaleobj: null,     // referenz auf das zeitskalaobjekt, das die zeitskala verwaltet
        planobj: null,          // referenz auf das planobjekt, das die balken zeichnet
        nrOfLines: 4,           // anzahl der zeilen/veranstaltungsstaetten
        nrOfCols: 12,           // anzahl der zeilen/stunden
        rooms: null             // die raumobjekte welche dargestellt werden sollen
    },
    /* initialisierung */
    initialize: function(options) {
        this.setOptions(options);

        this.table = $(this.options.tableid);

        if (this.options.rooms != null)
            this.options.nrOfLines = this.options.rooms.length;

        this.lastClickedCell = null;

    },

    /* gibt die Position eines Raumes in der Tabelle an */
    getPositionOfRoom: function(roomid) {

        var count = 0;

        var next = this.table.firstChild.firstChild.getNext();

        while (next != null) {

            var roomobj = next.retrieve('roomobj');

            if (roomobj != null) {

                count++;
                if (roomobj.ID == roomid) {
                    return count;
                }
            }

            next = next.getNext();
        }


        return count;

    },

    /* gibt die Y-Position eines Raumes in der Tabelle an. */
    getYPosOfRoom: function(roomid) {

        var y = 0;

        var next = null;

        if (this.table.childNodes.length == 1)
            next = this.table.firstChild.firstChild.getNext();
        else
            next = this.table.childNodes[1].firstChild.getNext();

        while (next != null) {

            y += next.getSize().y;

            var roomobj = next.retrieve('roomobj');

            if (roomobj != null) {
                if (roomobj.ID == roomid) {
                    return y;
                }
            }

            next = next.getNext();
        }


        return y;

    },

    /*  
    Erzeugt das Raster. Es wird eine Tabelle erzeugt mit den entsprechenden Bordern. 
    Jede Zelle ist klickbar.
    */
    createGrid: function(rooms) {

        // entferne alle zeilen mit den räumen
        this.table.getFirst().empty();

        // falls keine räume übergeben dann nimm diese von den optionen
        if (rooms == null)
            rooms = this.options.rooms;

        // für jeden raum...
        for (var i = 0; i < rooms.length; i++) {

            var r = rooms[i];

            // ...erzeuge eine zeile
            var tr = new Element("tr", { id: "row" + r.ID, "class": "gridrow" });

            // merke das raumobjekt für später
            tr.store('roomobj', r);

            // fülle die zeile mit der spalte, die den  namen des raumes enthält. und mit den Stundenspalten.
            this.fillRow(tr, r);

            // füge zeile zur tabelle
            this.table.getFirst().grab(tr);

            // mache dies mit allen unterräumen dieses raumes auch
            this.parseRoom(r);

            // falls der raum in der ersten ebene ist
            // füge im anschluss eine zeile hinzu, die etwas abstand macht zum nächsten raum der ebene 1
            if (r.Level == 0) {

                var gaprow = new Element("tr", { id: "rowgap" + r.ID, "class": "gaprow" });

                gaprow.appendChild(new Element("td", { html: "&nbsp;", "class": "roomcell" }));
                gaprow.appendChild(new Element("td", { html: "&nbsp;", "class": "gapcell" }));
                gaprow.appendChild(new Element("td", { html: "&nbsp;", "colspan": this.options.nrOfCols + 2 }));

                this.table.getFirst().appendChild(gaprow);
            }

        }
    },

    /* Fügt eine Zeile zum Raster. */
    parseRoom: function(room) {


        for (var i = 0; i < room.SubRooms.length; i++) {

            var subroom = room.SubRooms[i];

            var tr = new Element("tr", { id: "row" + subroom.ID, "class": "gridrow", "level": subroom.Level });
            tr.store('roomobj', subroom);

            this.fillRow(tr, subroom);

            this.table.getFirst().grab(tr);

            if (subroom.SubRooms.length > 0)
                parseRoom(subroom);
        }
    },

    /* füllt eine Zeile (Raum) mit Spalten (Stunden) */
    fillRow: function(tr, room) {


        var tdroom = new Element("td", { "class": "roomcell" + room.Level });

        var divname = new Element("div", { "class": "roomname", "html": this.cut(room.Name) });
        tdroom.appendChild(divname);
        var infoicon = new Element("img", { "class": "infoicon", "src": "../grafik/icons/btn_info_off.gif" });
        tdroom.appendChild(infoicon);

        divname.addEvent("click", function(e) {

            var tr = new Event(e).target.parentNode;

            var ownlevel = tr.retrieve('roomobj').Level;

            var next = tr.getNext();

            while (next != null) {

                var roomobj = next.retrieve('roomobj');

                if (roomobj != null) {

                    if (roomobj.Level == ownlevel) {
                        break;
                    } else {
                        if (next.style.display.length == 0 || next.style.display == 'block')
                            next.style.display = 'none';
                        else
                            next.style.display = 'block';
                    }
                }
                next = next.getNext();
            }
        });

        infoicon.addEvent("click", function(e) {
            var html = new PopupHtmlWriter().writeRoomDetail(room) + "<br/><a class=link href=\"../pluginRooms/roomdescription.aspx?roomid=" + room.ID + "\">Weitere Informationen</a>";
            new mooPopup({ dockelem: e.target, dockelempos: "center", headline: room.Name, content: html });
        });

        tr.grab(tdroom);

        //        tr.addEvent("mouseenter", function(ev) {
        //            td.parentNode.style.backgroundColor = "#E5E5E5";
        //            td.parentNode.firstChild.lastChild.style.visibility = "visible";
        //        });

        //        tr.addEvent("mouseleave", function(ev) {
        //            td.parentNode.style.backgroundColor = "white";
        //            td.parentNode.firstChild.lastChild.style.visibility = "hidden";


        //        });

        var tdgap = new Element("td", { "class": "gapcell", "html": "&nbsp;" });

        tr.grab(tdgap);

        var css = "gridcell";

        //        if (this.getLocked(room) != null)
        //            css += "_locked";

        for (var i = this.options.starthour; i <= (this.options.endhour - 1); i++) {

            var td = new Element("td", { "id": "td" + i, "class": css, "html": "&nbsp;" });
            td.innerHTML = "&nbsp;";
            td.setStyle("width", this.options.colwidth + "px");
            td.store("hour", i);
            tr.grab(td);

            // jede zweite spalte hat eine dunklere farbe
            if (i % 2 == 0)
                td.style.backgroundColor = "#F9F9F9";

            // wenn mit der maus über eine stunden-spalte gefahren wird
            td.addEvent("mouseenter", function(ev) {
                timescale.highlightHour(ev.target.id.replace("td", ""));
            });

            // wenn mit der maus stunden-spalte verlassen wird
            td.addEvent("mouseleave", function(ev) {
                timescale.unhighlightHour(ev.target.id.replace("td", ""));
            });

            // wenn auf eine zelle geklickt wird
            td.addEvent("click", this.onCellClicked.bind(this));
        }
    },

    getX: function(date) {


        var x = 0;

        var firstrow = this.table.getFirst().getFirst();

        if (date < this.options.planobj.startdate /*|| date > this.options.planobj.enddate*/)
            return x + firstrow.childNodes[0].getSize().x + firstrow.childNodes[1].getSize().x;

        // wenn das datum nach dem angezeigten bereich ist dann ist die position am ende
        if (date > this.options.planobj.enddate) {
            //date = this.options.planobj.enddate;

            return firstrow.getSize().x;
        }

        var hour = date.getHours();



        for (var i = 2; i < firstrow.childNodes.length; i++) {


            var td = firstrow.childNodes[i];

            var ih = i - 2;

            var h = this.options.starthour + ih;

            if (h < hour) {
                x += td.getSize().x;

            } else if (h == hour) {

                x += (td.getSize().x * this.getQ(date.getMinutes()));

            } else if (h > hour)
                break;
        }


        return x + firstrow.childNodes[0].getSize().x + firstrow.childNodes[1].getSize().x;

    },

    getQ: function(hmin) {

        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 q;

    },

    cut: function(word) {
        if (word.length > 17)
            return word.substring(0, 17) + "...";
        else
            return word;
    },

    /* gibt eine raumsperrung des raumes zurück, falls diese an dem aktuell gezeigten tag stattfindet   */
    getLocked: function(roomobj) {

        if (roomobj == null)
            return null;

        for (var i = 0; i < roomobj.RoomLocks.length; i++) {
            if (calendar.currdate >= roomobj.RoomLocks[i].DateFrom && calendar.currdate <= roomobj.RoomLocks[i].DateUntil)
                return roomobj.RoomLocks[i];
        }

        if (roomobj.ParentRoomID != "0")
            return this.getLocked(this.getRoom(roomobj.ParentRoomID));

        return null;
    },

    /* zeichnet die raumsperrungen der einzelnen räume in die tabelle ein */
    setLocked: function(rooms) {

        if (rooms == null)
            rooms = this.options.rooms;

        for (var i = 0; i < rooms.length; i++) {

            var room = rooms[i];

            var rl = this.getLocked(room);


            if (rl != null) {
                var tr = this.getRoomRow(room.ID);

                if (tr != null) {
                    if (room.ParentRoomID != "0")
                        tr.childNodes[0].getFirst().setStyle("color", "#c4c4c4"); // = "White";
                    else
                        for (var x = 2; x < tr.childNodes.length; x++)
                        tr.childNodes[x].className = "gridcell_locked";
                }
            } else {
                var tr = this.getRoomRow(room.ID);

                if (tr != null) {

                    if (room.ParentRoomID != "0")
                        tr.childNodes[0].getFirst().setStyle("color", "Black");

                    if (tr.childNodes[2].className.indexOf('locked') >= 0)
                        for (var x = 2; x < tr.childNodes.length; x++)
                        tr.childNodes[x].className = "gridcell";
                }
            }

            if (room.SubRooms.length > 0)
                this.setLocked(room.SubRooms);
        }
    },

    getRoomRow: function(roomID) {

        var trcontainer = this.table.getFirst();

        for (var i = 0; i < trcontainer.childNodes.length; i++) {
            var tr = trcontainer.childNodes[i];

            if (tr.id.replace("row", "") == roomID) {
                return tr;
            }
        }

        return null;
    },

    onCellClicked: function(ev) {

        if (this.lastClickedCell != null)
            this.lastClickedCell.className = "gridcell";

        var roomobj = ev.target.parentNode.retrieve("roomobj");

        if (roomobj != null) {


            ev.target.className = "gridcell_sel";
            this.lastClickedCell = ev.target;

            var bookable = true;
            var lockroom = this.getLocked(roomobj);

            if (lockroom != null) {

                // nicht reservierbar
                var msg = "Der Raum ist <br/>vom " + formatDate(lockroom.DateFrom, true) + " bis " + formatDate(lockroom.DateUntil, true) + "<br/>nicht reservierbar.";

                if (roomobj.isBookingDateRestricted == true) {

                    if (roomobj.DateBookable > calendar.currdate) {
                        msg += "<br/> bis zum " + formatDate(roomobj.DateBookable);
                    }
                    else {
                        bookable = true;
                    }

                }

                if (lockroom.Reason.length > 0) {
                    msg += "<br/><br/><b>Grund</b><br/>" + lockroom.Reason;
                }

                new mooPopup({ dockelem: ev.target, dockelempos: "center", headline: 'Nicht reservierbar', content: "<div style=\"text-align:center\">" + msg + "</div>" });


                //new ConfirmationPopup(ev.target, { headline: 'Nicht reservierbar', question: msg });
            }


            if (lockroom == null) {
               
                // erzeuge neues abfragefenster
                new ConfirmationPopup(ev.target, { headline: 'Anfrage stellen', ydelta: this.options.tablediv.scrollTop, question: "Möchten Sie eine Anfrage für den Raum <br/><b>" + ev.target.parentNode.retrieve("roomobj").Name + "</b> <br/> am " + formatDate(calendar.currdate, true) + " <br/> um " + ev.target.id.replace("td", "") + ":00 Uhr durchführen?", onYesClick: function(elem) {

                    // wenn "JA" geklickt wird und benutzer eingeloggt ist, gehe zum reservierungsformular
                    if (isUserLoggedIn()) {
                        var link = '../pluginForm/executereservation.aspx?roomid=' + elem.parentNode.retrieve("roomobj").ID + "&date=" + formatDate(calendar.currdate) + " " + ev.target.id.replace("td", "") + ":00:00";

                        // alert(link); return;
                        location.href = link;
                    } else {
                        alert("Sie können keine Reservierung durchführen, da Sie nicht angemeldet sind. Bitte melden Sie sich zuerst an.");

                        new MainLogin(ev.target, { headline: 'Login', question: 'Bitte melden Sie sich an um eine Anfrage durchführen zu können.' }).addEvent("OnLoginPassed", function() {

                            var link = '../pluginForm/executereservation.aspx?roomid=' + elem.parentNode.retrieve("roomobj").ID + "&date=" + formatDate(calendar.currdate) + " " + ev.target.id.replace("td", "") + ":00:00";

                            // alert(link); return;
                            location.href = link;

                        });

                        // new mooPopup({ dockelem: ev.target, dockelempos: "center", headline: 'Jetzt einloggen', content: "<table" });

                    }

                }, onNoClick: this.clearLastClickedCell.bind(this)
                });
            }
        }

    },

    clearLastClickedCell: function(e) {
        this.lastClickedCell.className = "gridcell";
    },

    getRoom: function(roomID) {

        for (var i = 0; i < this.options.rooms.length; i++)
            if (this.options.rooms[i].ID == roomID)
            return this.options.rooms[i];

        return null;
    }

});
