summaryrefslogblamecommitdiffstats
path: root/modules-available/locationinfo/frontend/doorsign.html
blob: 6919d2aa51ed5c18502a32cb34da61db83823a52 (plain) (tree)
1
2
3
4
5
6




          
                                              






                                       
                                       
                                                                     
                                                             
                                                                              

                                                                  
                                            
                                                                      
                                                                     
                                                                                                          
 




                                                                                       
























































































































































































































































                                                                                                 
 






































                                                                                                               























                                                                                                      
 
                                                                            








                                                                 

                                    
 





                                                          
 


                                                                 
 
                                         
 
                          

 
                             
 









                                                                                          

 




                                           
 
 





                                                 
 

                                                                               
 

                              
 



                                          
 

                                                       
 
              
 
          
 
 















                                                                                 
 














                                                                                              

                                                   

                                                         
                                                                 

                                              

                                                         
                                                                 

                                              
 











                                                                                                    
 
                                    


                                                                                                                     

























































































                                                                                                                             


                                                                             







                                                                                                               


                                                                             









                                                                                                               


                                                                             






















                                                                                                                           
 

                                               
 




                                                                         

                                               

                            
                                    

                         
          
 
 





                                                                          
 

                                                                                
 
                                 
                               
 

                                            
                                              
                                                                                                                                                                                  
 
                                                                                                      

                                                                                        

                                                                                                                                                                           
                                                                                    
                      
                  

 

                                                       
                  



                                               

 
                                                          
 


                                                               
                                                                                                                       

 

                                                                                                
 


                                                                                 
                                                                                                                                 

                          
 


                                              
 

                                                   

 







                                                       
                         
 





















                                                                   


                                          











                                                             
 
 




















                                                                                                            

                                             
                      
 
                                                                                                     
















                                                                                                                                       
                                         



                                   

                                                                 
                                
                                                                          














                                                                                                               

                                                                                   
                                                                      


                                     
 


                                         
 

                   
 
 




                                                               
 









































































                                                                                                                




                                                                 









                                                                                 
 
 





































                                                                                                 
                                         





















                                                                                                                                

                                                 

              

                                                                                                    





                                                                         
                               
                                                                                                           

 
                               

                             
                                   













                                                          
                                                                  
                                                     


                                                                               
                                              
 









































































                                                                                        
 
 




































































                                                                                       
























                                                                                               
                                                                                                                                                      




                                                                
                                                                                                                                                    

                                                     
                                                                                      









                                                     
                                               




                                                                                                
 
                                                      
 




                                                                                 
 




                                                                                        
 




                                                                                                                          
 




                                                                                          
 





                                                                                          
 
          
 
 






























                                                                                                                  
 
                                                       
 
                                                                                      
 

                               


                                                                                                               

 















                                                                                                                         
 
                                     


                                            

                                               
 
 





                                                                                           
 


                                                                                                                          
 





























                                                                              
 
 



























                                                                                                                                    
 

                                       
 





                                            
 



                                          
 
          
 




                                                             
 
                                                   

                                                 

              
                                                                                                         







                                                                               
 
                                                      
                                                             
 



















                                                                                   
 
 
                                                                                                                           





                                                                                                                                           
 
 






                                                      
 
                                                                                                                
                                                                                                                     
 


                                                                                                                   
                                  
 
                                                              
                                                               












                                                                                                                       

                                                   
                         

                                                                        


                                                                   
 
              
                                   

                        

                                                                                
 
                                 
 
 
          
 
 





                                                                     

                                                        




















                                                                                                 
                                             














                                                                                                                               


























                                                                                                                                    
                                                                                                         

                                                                   

                                                                                              























                                                                                                            
                                                   






                                                                
                                                              





                                                              
                                                         


























                                                                
 


                                                                                                        
                           
 

                                                      
 
                                       
                                         
                                                     
 











































                                                                                       
                                        



























































                                                                                           
                                                    









                                                    
 
 
              

        
        
        
<!--

parameter

required:
    id: [integer] room id, see in admin panel
optional:

    lang:[en,de] set the language
    mode:[1,2,3,4] sets the displaying
        1: Calendar & Room
        2: only Calendar
        3: only Room
        4: Calendar & Room alternately
    daystoshow:[1,2,3,4,5,6,7] sets how many days the calendar shows
    scale:[10-90] scales the calendar and Roomplan in mode 1
    switchtime:[1-120] sets the time between switchen in mode 4  (in seconds)
    calupdate: Time the calender querys for updates,in minutes.
    roomupdate: Time the PCs in the room gets updated,in seconds.
    rotation:[0-3] rotation of the roomplan
    vertical:[true] only mode 1, sets the calendar above the roomplan
    configupdate: Time interval the config gets updated (in minutes)
    scaledaysauto: [true] if true it finds automaticly the daystoshow parameter depending on display size

-->
<!DOCTYPE html>
<html lang="de">
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8">
<head>
    <title>DoorSign</title>
    <script type='text/javascript' src='../../../script/jquery.js'></script>
    <script type='text/javascript' src='../../js_jqueryui/clientscript.js'></script>
    <link rel='stylesheet' type='text/css' href='../../js_jqueryui/style.css'/>
    <link rel='stylesheet' type='text/css' href='jquery-week-calendar/jquery.weekcalendar.css'/>

    <script type='text/javascript' src="jquery-week-calendar/jquery.weekcalendar.js"></script>
    <style type='text/css'>

        body {
            font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
            margin: 0;
            width: 100%;
            height: 100%;
            float: left;
            box-sizing: border-box;

            background-color: #cacaca;
            overflow: hidden;
            position: absolute;
            display: table;

        }

        .row {
            background-color: #404040;
            box-shadow: 0 0.1875rem 0.375rem rgba(0, 0, 0, 0.25);
            margin-bottom: 4px;

            width: 100%;

        }

        .header {
            display: table;
            color: white;
            padding: 0;
            height: 8vw;

        }

        .progressbar {
            width: 0px;
            height: 2px;
            position: absolute;
            background-color: red;
            bottom: 2px;
            z-index: 1;
        }

        .font {
            display: table-cell;
            vertical-align: middle;
            font-size: 3vw;
            font-weight: bold
        }

        .courseText {
            text-align: center;
        }

        .row::after {
            content: "";
            clear: both;
            display: block;
        }

        [class*="col-"] {
            float: left;;
            padding: 0;
            box-sizing: border-box;
        }

        .col-1 {
            width: 33%;
        }

        .col-2 {
            width: 33%;
        }

        .roomLayoutDesign {
            position: relative;
            float: left;
            boxSizing: border-box;
        }

        .roompadding {
            float: left;
            position: relative;
        }

        .room {
            position: relative;
            background-color: white;
            width: 100%;
            height: 100%;
            overflow: hidden;
            border-width: 1px;
            border-color: darkgrey;
            border-style: solid;

        }

        .calendar {
            float: left;
            padding: 0;
            dboxSizing: border-box;
            background: linear-gradient(#cccccc, white);

        }

        .free-busy-busy {
            background: grey;
        }

        .ui-widget-content {
            color: white;
        }

        .wc-header {
            background-color: #404040;
            font-weight: bold;
        }

        .ui-state-default {
            text-shadow: none;
        }

        .square {
            display: table;
            float: right;
            padding: 0;
            width: 8vw;
            height: 8vw;
        }

        .FreeSeatsFont {
            display: table-cell;
            vertical-align: middle;
            font-size: 6vw;
            color: white;
            top: 0;
            margin: 0 auto;
            position: relative;
            text-align: center;
            font-weight: bold;
            overflow: visible;
        }

        .PCImgDiv {
            position: absolute;
            left: 0;
            bottom: 0;
            display: inline-block;

        }

        .OverlayDiv {
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 100%;
            display: table;
        }

        .pcImg {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;

        }

        .overlay {
            position: relative;
            width: 50%;
            height: 50%;
            opacity: 0.5;
            float: left;
            z-index: 5;
        }

        .overlay-rollstuhl {
            width: 25%;
            height: 50%;
            background-color: white;
            opacity: 0.5;
            float: left;
        }

        .wc-scrollable-grid {

        }

        .ui-widget-content .ui-state-active {
            font-weight: bold;
            color: black;
        }

        .wc-container {
            font-weight: bold;
        }

        .wc-today {
            background-color: white;
        }

        .wc-time-header-cell {
            background-color: #eeeeee;
            border: none;
        }

        .ui-corner-all {
            moz-border-radius-bottomright: 0;
            webkit-border-bottom-right-radius: 0;
            -khtml-border-bottom-right-radius: 0;
            border-bottom-right-radius: 0;

            moz-border-radius-topright: 0;
            webkit-border-top-right-radius: 0;
            -khtml-border-top-right-radius: 0;
            border-top-right-radius: 0;

            moz-border-radius-bottomleft: 0;
            webkit-border-bottom-left-radius: 0;
            -khtml-border-bottom-left-radius: 0;
            border-bottom-left-radius: 0;

            moz-border-radius-topleft: 0;
            webkit-border-left-right-radius: 0;
            -khtml-border-left-right-radius: 0;
            border-top-left-radius: 0;
        }

        .wc-scrollable-grid .wc-day-column-first {
            border-style: solid;

        }

        [class*="wc-day-"] {
            border-color: grey;
        }


    </style>
    <script type='text/javascript'>

        var rooms = {};
        var lastSwitchTime;
        var roomsToshow = 0;
        var roomIds;
        //Todo change these
        var date;
        var supportSvg = typeof SVGRect != "undefined";
        var calendarQueryUrl;
        var translation = {
            "en": {
                "room": "Room",
                "closed": "Closed",
                "free": "Free",
                "shortDays": ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
                "longDays": ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
                "to": "to"

            },
            "de": {
                "room": "Raum",
                "closed": "Geschlossen",
                "free": "Frei",
                "shortDays": ["Son", "Mon", "Die", "Mit", "Don", "Frei", "Sam"],
                "longDays": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
                "to": "bis"
            },
            "pt": {
                "room": "Quarto",
                "closed": "Fechado",
                "free": "Livre",
                "shortDays": ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Se', 'Sáb'],
                "longDays": ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira',
                    'Sexta-feira', 'Sábado'],
                "to": "para"

            }
        };


        $(document).ready(function () {
            if (!getId()) {

            }
        });


        /**
         * Downloads the config of a room, also reloads the page if the config hase changed over time
         * @param id ID of the room
         * @param room Room Object, only needed if it already exists
         */

        function getConfig(id, room) {
            $.ajax({
                url: "../../../api.php?do=locationinfo&action=config&id=" + id,
                dataType: 'json',
                cache: false,
                timeout: 30000,
                success: function (result) {

                    if (room == null) {

                        if (result.room == null) {

                            for (var i = roomIds.length - 1; i >= 0; i--) {
                                if (roomIds[i] === id) {
                                    roomIds.splice(i, 1);
                                }
                            }
                            if (roomsToshow == roomIds.length) {

                                initRooms();

                            }
                            return;
                        }

                        var time = new Date(result.time);
                        if (isNaN(time.getTime())) {
                            time = new Date();
                        }
                        SetUpDate(time);
                        delete result.time;

                        room = addRoom(id, result.room, result);
                        roomsToshow++;
                        if (roomsToshow == roomIds.length) {

                            initRooms();

                        }


                    } else {

                        delete result.time;
                        if (JSON.stringify(rooms[id].config) != JSON.stringify(result)) {
                            // reload Page if someone changed config
                            location.reload(true);
                        }
                    }
                    // check for config changes from time to time
                    setTimeout(function () {
                        getConfig(id, room);
                    }, room.config.configupdate);


                }, error: function () {
                    //Todo Error handling:
                }
            })
        }


        /**
         *  gets the Parameter IDs from the Urls
         */
        function getId() {
            roomIds = getUrlParameter("id");
            if (roomIds == null) {

                var text = "<h1>Error: No Room Id's given in parameter </h1>";
                $("body").append(text);

                return false;
            }

            roomIds = roomIds.split(',');
            if (roomIds.length > 4) {
                roomIds.length = 4;
            }

            for (var i = 0; i < roomIds.length; i++) {
                getConfig(roomIds[i], null);

            }

        }


        /**
         * gets Additional Parameters from the URL, and from the
         * downloaded json.
         * also makes sure parameters are in a given range
         * @param room Room Object
         */

        function getParamerter(room) {


            if (room.config != null) {
                room.config.switchtime = room.config.switchtime * 1000;
                room.config.calupdate = room.config.calupdate * 60 * 1000;
                room.config.roomupdate = room.config.roomupdate * 1000;
                room.config.configupdate = room.config.configupdate * 60 * 1000;
            }

            if (getUrlParameter("mode") != null) {
                room.config.mode = parseInt(getUrlParameter("mode"));
            }
            if (getUrlParameter("calupdate") != null) {
                room.config.calupdate = (parseInt(getUrlParameter("calupdate")) * 60 * 1000);
            }
            if (getUrlParameter("roomupdate") != null) {
                room.config.roomupdate = (parseInt(getUrlParameter("roomupdate")) * 1000);
            }
            if (getUrlParameter("daystoshow") != null) {
                room.config.daystoshow = parseInt(getUrlParameter("daystoshow"));
            }
            if (getUrlParameter("scaledaysauto") == "true") {
                room.config.scaledaysauto = true;
            } else if (getUrlParameter("scaledaysauto") == "false") {
                room.config.scaledaysauto = false;
            }
            if (getUrlParameter("vertical") == "true") {
                room.config.vertical = true;
            } else if (getUrlParameter("vertical") == "false") {
                room.config.vertical = false;
            }
            if (getUrlParameter("einkmode") == "true") {
                room.config.einkmode = true;
            } else if (getUrlParameter("einkmode") == "false") {
                room.config.einkmode = false;
            }

            if (getUrlParameter("scale") != null) {
                room.config.scale = parseInt(getUrlParameter("scale"));
            }
            if (getUrlParameter("rotation") != null) {
                room.config.rotation = parseInt(getUrlParameter("rotation"));
            }
            if (getUrlParameter("switchtime") != null) {
                room.config.switchtime = (parseInt(getUrlParameter("switchtime")) * 1000);
            }
            if (getUrlParameter("configupdate") != null) {
                room.config.configupdate = (parseInt(getUrlParameter("configupdate")) * 60 * 1000);
            }

            // parameter validation
            if (room.config.switchtime == null || isNaN(room.config.switchtime) || room.config.switchtime > 120*1000
                || room.config.switchtime < 1*1000) {
                room.config.switchtime = 5*1000;
            }
            if (room.config.scale == null || isNaN(room.config.scale) || room.config.scale > 90 || room.config.scale < 10) {
                room.config.scale = 50;
            }
            if (room.config.vertical == null) {
                room.config.vertical = false;
            }
            if (room.config.daystoshow == null || isNaN(room.config.daystoshow) || room.config.daystoshow > 7
                || room.config.daystoshow < 1) {
                room.config.daystoshow = 7;
            }

            if (room.config.roomupdate == null || isNaN(room.config.roomupdate) || room.config.roomupdate < 1000) {
                room.config.roomupdate = 20 * 1000;
            }
            if (room.config.configupdate == null || isNaN(room.config.configupdate) || (room.config.configupdate < 1)) {
                room.config.configupdate = 30 * 60 * 1000;
            }

            if (room.config.calupdate == null || isNaN(room.config.calupdate) || room.config.calupdate < 60 * 1000) {
                room.config.calupdate = 30 * 60 * 1000;
            }
            if (room.config.mode == null || isNaN(room.config.mode) || room.config.mode > 4 || room.config.mode < 1) {
                room.config.mode = 1;
            }
            if (room.config.rotation == null || isNaN(room.config.rotation) || room.config.rotation < 0
                || room.config.rotation > 4) {
                room.config.rotation = 0;
            }

            if (getUrlParameter("lang") != null && getUrlParameter("lang") in translation) {
                room.config.language = getUrlParameter("lang");
            }
            $('html').attr('lang', room.config.language);
        }

        /**
         * generates the Room divs and calls the needed functions depending on the rooms mode
         */
        function initRooms() {

            var width = "100%";
            var height = "100%";
            if (roomsToshow == 2 || roomsToshow == 4) {
                width = "50%";
            }
            if (roomsToshow == 3) {
                width = "33%";
            }
            if (roomsToshow == 4) {
                height = "50%";
            }
            var i = 0;
            for (var t = 0; t < roomIds.length; t++) {
                var property = roomIds[t];
                var text = "<div class='roompadding'   id ='roompadding_" + rooms[property].id + "'></div>";
                $("body").append(text);


                var obj = document.getElementById("roompadding_" + rooms[property].id);
                obj.style.height = height;
                obj.style.width = width;
                text = "<div class='room'   id ='room_" + rooms[property].id + "'></div>";

                $("#roompadding_" + rooms[property].id).append(text);


                text = "<div id='header_" + rooms[property].id + "' class='row'>" +
                    "<div class='header col-2'>" +
                    "<div class='font' id='roomHeader_" + rooms[property].id + "'></div>" +
                    "</div>" +
                    "<div class='col-1 courseText header'>" +
                    "<div class='font' id='courseHeading_" + rooms[property].id + "'></div>" +
                    "</div>" +
                    "<div class='square .col-2' id='square_" + rooms[property].id + "'>" +
                    "<div class='FreeSeatsFont' id='freeSeatsHeader_" + rooms[property].id + "'></div>" +
                    "</div>" +
                    "</div>";
                $("#room_" + rooms[property].id).append(text);

                if (rooms[property].name != null) {
                    $("#roomHeader_" + rooms[property].id).text(rooms[property].name);
                }

                if (roomsToshow == 2) {
                    document.getElementById("square_" + rooms[property].id).style.width = "6vw";
                    document.getElementById("square_" + rooms[property].id).style.height = "6vw";
                    document.getElementById("roomHeader_" + rooms[property].id).style.fontSize = "1.8vw";
                    document.getElementById("freeSeatsHeader_" + rooms[property].id).style.fontSize = "4.5vw";
                    document.getElementById("courseHeading_" + rooms[property].id).style.fontSize = "1.8vw";
                    var headers = document.getElementsByClassName('header');
                    for (var j = 0; j < headers.length; j++) {
                        headers[j].style.height = "6vw";
                    }
                }
                if (roomsToshow == 3) {
                    document.getElementById("square_" + rooms[property].id).style.width = "4vw";
                    document.getElementById("square_" + rooms[property].id).style.height = "4vw";
                    document.getElementById("roomHeader_" + rooms[property].id).style.fontSize = "1.2vw";
                    document.getElementById("freeSeatsHeader_" + rooms[property].id).style.fontSize = "2.5vw";
                    document.getElementById("courseHeading_" + rooms[property].id).style.fontSize = "1.2vw";
                    var headers = document.getElementsByClassName('header');
                    for (var j = 0; j < headers.length; j++) {
                        headers[j].style.height = "4vw";
                    }

                }
                if (roomsToshow == 4) {
                    document.getElementById("square_" + rooms[property].id).style.width = "4vw";
                    document.getElementById("square_" + rooms[property].id).style.height = "4vw";
                    document.getElementById("roomHeader_" + rooms[property].id).style.fontSize = "1.5vw";
                    document.getElementById("freeSeatsHeader_" + rooms[property].id).style.fontSize = "2.5vw";
                    document.getElementById("courseHeading_" + rooms[property].id).style.fontSize = "1.5vw";

                    var headers = document.getElementsByClassName('header');
                    for (var j = 0; j < headers.length; j++) {
                        headers[j].style.height = "4vw";
                    }
                }


                if (rooms[property].config.mode == 1) {
                    setUpCalendar(rooms[property].config.scale + "%", rooms[property].config.daystoshow, rooms[property]);
                    preInitRoom(rooms[property]);

                } else if (rooms[property].config.mode == 2) {
                    setUpCalendar("100%", rooms[property].config.daystoshow, rooms[property]);

                } else if (rooms[property].config.mode == 3) {
                    preInitRoom(rooms[property]);
                    getOpeningTimes(rooms[property]);
                } else if (rooms[property].config.mode == 4) {

                    setUpCalendar("100%", rooms[property].config.daystoshow, rooms[property]);
                    preInitRoom(rooms[property]);
                    generateProgressBar(rooms[property].id);
                }

                i++;
            }

            setInterval(mainUpdateLoop, 1000);
        }

        /**
         * Helper function to generate id string used in query functions
         * @param list A string, wicht contains ids or not(for now)
         * @param id An ID which should be added to the list
         */
        function addIdToUpdateList(list, id) {
            if (list == "") {
                list += id;
            } else {
                list += ("," + id);
            }
            return list;
        }


        var timeSteps = 10;
        /**
         * Main Update loop, this loop runs every 1 seconds and calls all
         * function which should be called periodically
         */
        function mainUpdateLoop() {

            // check ervery 10 sec if rooms need new calendar data or room data
            // groups request

            if (timeSteps > 9) {
                timeSteps = 0;

                var calendarUpdateIds = "";
                var rommUpdateIds = "";
                for (var property in rooms) {
                    if (rooms[property].config.lastCalendarUpdate == null || rooms[property].config.lastCalendarUpdate + rooms[property].config.calupdate < MyDate().getTime()) {

                        calendarUpdateIds = addIdToUpdateList(calendarUpdateIds, rooms[property].id);
                        rooms[property].config.lastCalendarUpdate = MyDate().getTime();
                    }
                    if (rooms[property].config.lastRoomUpdate == null || rooms[property].config.lastRoomUpdate + rooms[property].config.roomupdate < MyDate().getTime()) {
                        rommUpdateIds = addIdToUpdateList(rommUpdateIds, rooms[property].id);
                        rooms[property].config.lastRoomUpdate = MyDate().getTime();
                    }
                }


                if (calendarUpdateIds != "") {
                    queryCalendars(calendarUpdateIds);
                }
                if (rommUpdateIds != "") {
                    queryRooms(rommUpdateIds);
                }
            }


            // switches calendar and roomlayout in mode 4

            for (var property in rooms) {
                if (rooms[property].config.mode == 4) {
                    if (rooms[property].lastSwitchTime == null
                        || rooms[property].lastSwitchTime + rooms[property].config.switchtime  < MyDate().getTime()) {


                        switchLayout(rooms[property]);
                        MoveProgressBar(rooms[property].id, rooms[property].config.switchtime);

                        if (rooms[property].lastSwitchTime == null) {
                            rooms[property].lastSwitchTime = MyDate().getTime();
                        } else {
                            rooms[property].lastSwitchTime = rooms[property].lastSwitchTime + rooms[property].config.switchtime;
                        }
                    }

                    //
                }
                // Updateing All room Headers

                UpdateRoomHeader(rooms[property]);
            }


            // reload site at midnight
            var now = new MyDate();
            if (date != null) {
                if (date.getDate() != now.getDate()) {
                    location.reload(true);
                }
            }
            date = now;
            timeSteps++;

        }

        /**
         *  Generates a room Object and adds it to the rooms array
         *  @param id ID of the room
         *  @param name Name of the room
         *  @param config Config Json of the room
         */
        function addRoom(id, name, config) {
            var room = {
                id: id,
                name: name,
                timetable: null,
                currentEvent: null,
                nextEventEnd: null,
                timeTilFree: null,
                state: null,
                openingTimes: null,
                config: config,
                currentfreePcs: 0,
                layout: null,
                freePcs: 0,
                resized: true,
                lastCalendarUpdate: null,
                lastRoomUpdate: null,
                getState: function () {
                    if (this.state == null) {
                        ComputeCurrentState(this);
                        return this.state;
                    }
                    if (this.state.end != "") {
                        if (this.state.end < new MyDate()) {
                            ComputeCurrentState(this);
                        }
                    }
                    return this.state;
                }


            };
            getParamerter(room);
            rooms[id] = room;
            return room;

        }

        /**
         *  inilizes the Calendar for an room
         *  @param percent Percentages of how mucht width the Calendar div should get (only used in mode 1)
         *  @param daysToShow How many days the calendar should show
         *  @param room Room Object
         */
        function setUpCalendar(percent, daysToShow, room) {
            generateCalendarDiv(percent, room);
            var $calendar = $("#calendar_" + room.id).weekCalendar({
                timeslotsPerHour: 1,
                timeslotHeight: 30,
                daysToShow: daysToShow,
                height: function ($calendar) {
                    var height = $(window).height();
                    if (roomsToshow == 4) {
                        height = height / 2;
                    }

                    height = height - document.getElementById('header_' + room.id).clientHeight - 5;
                    if (room.config.mode == 1 && room.config.vertical) {
                        height = height * (room.config.scale / 100)
                    }
                    return height;
                },
                eventRender: function (calEvent, $event) {
                    if (calEvent.end.getTime() < new MyDate().getTime()) {
                        $event.css("backgroundColor", "#aaa");
                        $event.find(".time").css({"backgroundColor": "#999", "border": "1px solid #888"});
                    } else if (calEvent.end.getTime() > new MyDate().getTime() && calEvent.start.getTime() < new MyDate().getTime()) {
                        $event.css("backgroundColor", "#25B002");
                        $event.find(".time").css({"backgroundColor": "#25B002", "border": "1px solid #888"});
                    }
                },
                date: MyDate(),
                dateFormat: "j.n",
                timeFormat: "G:i",
                scrollToHourMillis: 500,
                use24Hour: true,
                readonly: true,
                showHeader: false,
                hourLine: true,
                shortDays: t("shortDays", room.config.language),
                longDays: t("longDays", room.config.language),
                buttons: false,
                timeSeparator: " " + t("to", room.config.language) + " ",
                startOnFirstDayOfWeek: false,
                displayFreeBusys: true,
                defaultFreeBusy: {free: false}
            });
            getOpeningTimes(room);


        }

        /**
         * downloads openingTimes for an room
         * @param room Room Object
         */
        function getOpeningTimes(room) {
            $.getJSON("../../../api.php?do=locationinfo&action=openingtime&id=" + room.id, function (result) {
                if (Object.prototype.toString.call(result) === '[object Array]') {
                    if (result.length > 0) {
                        SetOpeningTimes(result[0].openingtime, room);
                    }
                }
                scaleCalendar(room);

            })
                .error(function () {
                    scaleCalendar(room);

                })
        }


        /**
         * Generates the Calendar Div, depending on it's width
         * @param width width of the Calendar Div
         * @param room Room Object
         */

        function generateCalendarDiv(width, room) {
            var div = document.createElement("div");
            div.id = "calendar_" + room.id;
            div.className = "calendar";
            if (room.config.vertical && room.config.mode == 1) {
                width = 100 + "%";
                div.float = "Top";
            }
            div.style.width = width;
            //document.body.appendChild(div);
            $("#room_" + room.id).append(div);

        }

        /**
         * sets the opening Time in the calendar plugin and saves it in the room object
         * @param parsedOpenings Dictonary of Opening times.
         * @param room Room Object
         */

        function SetOpeningTimes(parsedOpenings, room) {
            var opening = 24;
            var close = 0;
            room.openingTimesCalendar = [];
            room.openingTimes = [parsedOpenings['Sunday'], parsedOpenings['Monday'], parsedOpenings['Tuesday'],
                parsedOpenings['Wednesday'], parsedOpenings['Thursday'],
                parsedOpenings['Friday'], parsedOpenings['Saturday']];
            if (room.config.mode == 3) {
                return;
            }
            for (var i = 0; i < 7; i++) {
                var tmp = room.openingTimes[i];
                if (tmp != null) {
                    for (var d = 0; d < tmp.length; d++) {
                        var day = getNextDayOfWeek(new MyDate(), i);
                        room.openingTimesCalendar.push({
                            "start": new Date(day.getFullYear(), day.getMonth(), day.getDate(),
                                tmp[d]['HourOpen'], tmp[d]['MinutesOpen']),
                            "end": new Date(day.getFullYear(), day.getMonth(),
                                day.getDate(), tmp[d]['HourClose'], tmp[d]['MinutesClose']),
                            "free": true
                        });
                        if (parseInt(tmp[d]['HourOpen']) < opening) {
                            opening = tmp[d]['HourOpen'];
                        }
                        if (parseInt(tmp[d]['HourClose']) > close) {
                            close = tmp[d]['HourClose'];
                            if (parseInt(tmp[d]['MinutesClose']) != 0) {
                                close++;
                            }
                        }
                    }
                }
            }
            if (parsedOpenings.length == 0) {
                opening = 0;
                close = 24;
            }
            room.openTimes = close - opening;
            $('#calendar_' + room.id).weekCalendar("option", "businessHours", {
                start: parseInt(opening),
                end: parseInt(close),
                limitDisplay: true
            });
        }

        /**
         * querys the Calendar data
         * @param ids ID'S of rooms to query as string, for e.g.: "5,17,8" or "5"
         */
        function queryCalendars(ids) {
            var url = "../../../api.php?do=locationinfo&action=calendar&id=" + ids;

            // Todo reimplement Frontend methode if needed
            /*
             if(!(room.config.calendarqueryurl === undefined)) {
             url = room.config.calendarqueryurl;
             }
             */
            $.ajax({
                url: url,
                dataType: 'json',
                cache: false,
                timeout: 30000,
                success: function (result) {
                    var l = result.length;
                    for (var i = 0; i < l; i++) {
                        updateCalendar(result[i].calendar, rooms[result[i].id]);
                    }


                }, error: function () {

                }
            });
        }

        /**
         * applays new calendar data to the calendar plugin and also saves it to the room object
         * @param json Calendar data JSON
         * @param room Room Object
         */
        function updateCalendar(json, room) {

            if (json == "") {
                console.log("Error: Calendar data was an empty string.");
                return;
            }
            try {
                room.timetable = json;
                if (room.config.mode != 3) {
                    var cal = $('#calendar_' + room.id);
                    cal.weekCalendar("option", "data", json);
                    cal.weekCalendar("refresh");
                    cal.weekCalendar("option", "defaultFreeBusy", {free: false});
                    cal.weekCalendar("updateFreeBusy", room.openingTimesCalendar);
                }
                ComputeCurrentState(room);
            } catch (e) {
                console.log("Error: Couldnt add calendar data");
                console.log(e);
            }
        }

        /**
         * scales calendar, called once on create and on window resize
         * @param room Room Object
         */
        function scaleCalendar(room) {
            if (room.config.mode == 3) {
                return;
            }
            if (room.openTimes == null) {
                room.openTimes = 24;
            }
            var cal = $('#calendar_' + room.id);
            var columnWidth = document.getElementById("calendar_" + room.id).getElementsByClassName("wc-day-1")[0].clientWidth;

            if (room.config.scaledaysauto) {
                var result = (cal.weekCalendar("option", "daysToShow") * columnWidth) / 100;
                result = parseInt(Math.min(Math.max(Math.abs(result), 1), 7));
                if (result != parseInt(cal.weekCalendar("option", "daysToShow"))) {

                    cal.weekCalendar("option", "daysToShow", Math.abs(result));
                }
            }
            if (((!room.config.scaledaysauto) || cal.weekCalendar("option", "daysToShow") == 1) && columnWidth < 85) {
                cal.weekCalendar("option", "useShortDayNames", true);
            } else {
                cal.weekCalendar("option", "useShortDayNames", false);
            }
            var clientHeight = $(window).height();
            if (roomsToshow == 4) {
                clientHeight = clientHeight / 2;
            }

            clientHeight = clientHeight - document.getElementById('header_' + room.id).clientHeight
                - document.getElementsByClassName("wc-time-column-header")[0].clientHeight - 2;

            if (room.config.mode == 1 && room.config.vertical) {

                clientHeight = clientHeight * (room.config.scale / 100);
                clientHeight -= 22;
            }
            clientHeight -= 6;
            var height = clientHeight / (room.openTimes * cal.weekCalendar("option", "timeslotsPerHour"));


            if (height < 30) {
                height = 30;
            }
            // Scale calendar font
            if(height > 120){
                cal.weekCalendar("option","textSize",28);
            }
            else if(height > 100){
                cal.weekCalendar("option","textSize",24);
            } else if(height > 80) {
                cal.weekCalendar("option","textSize",22);
            } else if(height > 70) {
                cal.weekCalendar("option","textSize",20);
            } else if (height > 60) {
                cal.weekCalendar("option","textSize",14);
            } else {
                cal.weekCalendar("option","textSize",13);
            }
            cal.weekCalendar("option", "timeslotHeight", height);
            if (room.openingTimesCalendar != null) {
                cal.weekCalendar("updateFreeBusy", room.openingTimesCalendar);
            }
            cal.weekCalendar("resizeCalendar");
            cal.weekCalendar("scrollToHour");

        }

        /**
         *  used for countdown
         * computes the time difference between 2 Date objects
         * @param a Date Object
         * @param b Date Object
         * @param room Room Object
         * @returns time string
         */
        function GetTimeDiferenceAsString(a, b, room) {
            if (a == null || b == null) {
                return "";
            }
            var milliseconds = a.getTime() - b.getTime();
            var seconds = Math.floor((milliseconds / 1000) % 60);
            milliseconds -= seconds * 1000;
            var minutes = Math.floor((milliseconds / (1000 * 60)) % 60);
            milliseconds -= minutes * 1000 * 60;
            var hours = Math.floor((milliseconds / (1000 * 60 * 60)) % 24);

            var days = Math.floor((milliseconds / (1000 * 60 * 60 * 24)) % 31);
            if (seconds < 10) {
                seconds = "0" + seconds;
            }
            if (minutes < 10) {
                minutes = "0" + minutes;
            }
            if (days != 0) {
                // dont show?
                return "";
            }
            if (room.config.einkmode) {
                return hours + ":" + minutes;
            }
            return hours + ":" + minutes + ":" + seconds;
        }

        /**
         * returns next closing time of a given room
         * @param room
         * @returns Date Object of next closing
         */
        function GetNextClosing(room) {
            var now = new MyDate();
            var day = now.getDay();
            var offset = 0;
            var bestdate;
            for (var a = 0; a < 7; a++) {
                var tmp = room.openingTimes[day];
                if (tmp != null) {
                    for (var i = 0; i < tmp.length; i++) {
                        var closeDate = new MyDate();
                        closeDate.setDate(now.getDate() + offset);
                        closeDate.setHours(tmp[i].HourClose);
                        closeDate.setMinutes(tmp[i].MinutesClose);
                        closeDate.setSeconds(0);
                        if (closeDate > now) {
                            if (!IsOpen(new Date(closeDate.getTime() + 60000), room)) {
                                if (bestdate == null || bestdate > closeDate) {
                                    bestdate = closeDate;
                                }
                            }
                        }
                    }
                }
                offset++;
                day++;
                if (day > 6) {
                    day = 0;
                }
            }
            return bestdate;
        }


        /**
         * checks if a room is on a given date/time open
         * @param date Date Object
         * @param room Room object
         * @returns bool for open or not
         */
        function IsOpen(date, room) {
            if (room.openingTimes == null) {
                return false;
            }
            var tmp = room.openingTimes[date.getDay()];
            if (tmp == null) {
                return false;
            }
            for (var i = 0; i < tmp.length; i++) {
                var openDate = new MyDate();
                openDate.setHours(tmp[i].HourOpen);
                openDate.setMinutes(tmp[i].MinutesOpen);
                var closeDate = new MyDate();
                closeDate.setHours(tmp[i].HourClose);
                closeDate.setMinutes(tmp[i].MinutesClose);
                if (openDate < date && closeDate > date) {
                    return true;
                }
            }
            return false;
        }


        /**
         * Retruns next Opening
         * @param room Room Object
         * @returns bestdate Date Object of next opening
         */
        function GetNextOpening(room) {
            var now = new MyDate();
            var day = now.getDay();
            var offset = 0;
            var bestdate;
            for (var a = 0; a < 7; a++) {
                if (room.openingTimes == null) {
                    return null;
                }
                var tmp = room.openingTimes[day];
                if (tmp != null) {
                    for (var i = 0; i < tmp.length; i++) {
                        var openDate = new MyDate();
                        openDate.setDate(now.getDate() + offset);
                        openDate.setHours(tmp[i].HourOpen);
                        openDate.setMinutes(tmp[i].MinutesOpen);
                        if (openDate > now) {
                            if (!IsOpen(new Date(openDate.getTime() - 60000), room)) {
                                if (bestdate == null || bestdate > openDate) {
                                    bestdate = openDate;
                                }
                            }
                        }
                    }
                }
                offset++;
                day++;
                if (day > 6) {
                    day = 0;
                }
            }
            return bestdate;
        }


        /**
         * Sets the free PCs number in the right corner and updates the sqare color acordingly
         * @param id Room id
         * @param seats Number of free PC's in the room
         */
        function SetFreeSeats(id, seats) {
            if (seats > 0) {
                $("#freeSeatsHeader_" + id).text(seats);
                $("#square_" + id).css('background-color', '#00dd10');
            } else if (seats == -1) {
                $("#freeSeatsHeader_" + id).text("");
                $("#square_" + id).css('background-color', 'red');
            } else {
                $("#freeSeatsHeader_" + id).text("0");
                $("#square_" + id).css('background-color', 'red');
            }
        }

        /**
         * Updates the Header of an Room
         * @param room Room Object
         */
        function UpdateRoomHeader(room) {
            var tmp = room.getState();
            if (tmp.state == "closed") {
                $("#courseHeading_" + room.id).text(t("closed", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, new MyDate(), room));
                SetFreeSeats(room.id, room.freePcs);
            } else if (tmp.state == "ClaendarEvent") {
                $("#courseHeading_" + room.id).text(tmp.title);
                SetFreeSeats(room.id, -1);
            } else if (tmp.state == "Free") {
                $("#courseHeading_" + room.id).text(t("free", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, new MyDate(), room));
                SetFreeSeats(room.id, room.freePcs);
            } else if (tmp.state == "FreeNoEnd") {
                $("#courseHeading_" + room.id).text(t("free", room.config.language));
                SetFreeSeats(room.id, room.freePcs);
            }
        }

        /**
         * computes state of a room, states are:
         * closed, FreeNoEnd, Free, ClaendarEvent.
         * @param Room Object
         */
        function ComputeCurrentState(room) {
            if (!IsOpen(new MyDate(), room)) {
                room.state = {state: "closed", end: GetNextOpening(room), title: "", next: ""};

                return;
            }
            var closing = GetNextClosing(room);

            var event = getNextEvent(room.timetable);

            // no event and no closing
            if (closing == null && event == null) {
                room.state = {state: "FreeNoEnd", end: "", title: "", next: ""};
                return;
            }

            // no event so closing is next
            if (event == null) {
                room.state = {state: "Free", end: closing, title: "", next: "closing"};
                return;
            }

            // event is at the moment
            if ((closing == null || event.start.getTime() < closing.getTime()) && event.start.getTime() < new MyDate()) {
                room.state = {state: "ClaendarEvent", end: event.end, title: event.title, next: ""};
                return;
            }

            // no closing so event is next
            if (closing == null) {
                room.state = {state: "Free", end: event.start, title: "", next: "event"};
                return;
            }

            // event sooner then closing
            if (event.start.getTime() < closing) {
                room.state = {state: "Free", end: event.start, title: "", next: "event"};
            } else if (event.start.getTime() > closing) {
                room.state = {state: "Free", end: closing, title: "", next: "closing"};
            }

        }


        /**
         * returns next event from a given json of events
         * @param json Json which contains the calendar data.
         * @returns event next Carlendar Event
         */
        function getNextEvent(json) {
            var event;
            var now = new MyDate();
            if (json == null) {
                return;
            }
            for (var i = 0; i < json.length; i++) {
                //event is now active
                if (json[i].start.getTime() < now.getTime() && json[i].end.getTime() > now.getTime()) {
                    return json[i];
                }
                //first element to consider
                if (event == null) {
                    if (json[i].start.getTime() > now.getTime()) {
                        event = json[i];
                    }
                }
                if (json[i].start.getTime() > now.getTime() && event.start.getTime() > json[i].start.getTime()) {
                    event = json[i];
                }
            }
            return event;
        }

        function getNextDayOfWeek(date, dayOfWeek) {
            // Code to check that date and dayOfWeek are valid left as an exercise ;)

            var resultDate = new Date(date.getTime());

            resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7);

            return resultDate;
        }
        /*
         /========================================== Room Layout =============================================
         */


        var picSizeX = 3.8;
        var picSizeY = 3;

        /**
         * Generates the RoomLayout Div
         * @param width The width the RoomLayout should have (in percent).
         * @param room Room Object
         */
        function generateRoomLayoutDiv(width, room) {
            var div = document.createElement("div");
            div.id = "roomLayout_" + room.id;
            div.className = "roomLayoutDesign";
            if ((room.config.vertical && room.config.mode == 1) || (room.config.mode == 3) || (room.config.mode == 4)) {
                width = 100 + "%";
                div.float = "Top";
            }

            div.style.width = width;
            if(room.config.mode == 4){
                div.style.display = "none";
            }
            //document.body.appendChild(div);
            $("#room_" + room.id).append(div);


        }
        /**
         * Donwloads Room Layout Json (which contains the pc information for a given room)
         * @param room Room Object
         */
        function preInitRoom(room) {

            $.getJSON("../../../api.php?do=locationinfo&action=roominfo&id=" + room.id + "&coords=1", function (result) {
                generateRoomLayoutDiv((100 - room.config.scale) + "%", room);
                if (result[0] == null) {

                    return;
                }
                initRoom(result[0].computer, room);

            }).error(function () {

                generateRoomLayoutDiv((100 - room.config.scale) + "%", room);
            })
        }


        /**
         * Main funciton for generating the Room Layout
         * @param layout Layout Json
         * @param room Room Object
         */
        function initRoom(layout, room) {
            var maxX;
            var maxY;
            var minY;
            var minX;
            var xDifference;
            var yDifference;
            room.layout = layout;
            if (layout == null || layout.length == 0) {
                return;
            }
            if (room.config.rotation != 0) {
                rotateRoom(room.config.rotation, layout);
            }


            for (var i = 0; i < layout.length; i++) {
                if (!isNaN(parseInt(layout[i].x)) && !isNaN(parseInt(layout[i].y)) && layout[i].y != null && layout[i].y != null) {
                    if (minX === undefined) {
                        minX = parseInt(layout[i].x);
                    }
                    if (minY === undefined) {
                        minY = parseInt(layout[i].y);
                    }
                    if (maxX === undefined) {
                        maxX = parseInt(layout[i].x);
                    }
                    if (maxY === undefined) {
                        maxY = parseInt(layout[i].y);
                    }
                    if (parseInt(layout[i].x) < parseInt(minX)) {
                        minX = parseInt(layout[i].x);
                    }
                    if (parseInt(layout[i].y) < parseInt(minY)) {
                        minY = parseInt(layout[i].y);
                    }
                    if (parseInt(layout[i].x) > parseInt(maxX)) {
                        maxX = parseInt(layout[i].x);
                    }
                    if (parseInt(layout[i].y) > parseInt(maxY)) {
                        maxY = parseInt(layout[i].y);
                    }
                }
            }

            xDifference = maxX - minX;
            yDifference = maxY - minY;

            room.xDifference = xDifference;
            room.yDifference = yDifference;
            room.minX = minX;
            room.minY = minY;
            room.maxX = maxX;
            room.maxY = maxY;

            generateOffsetAndScale(room);
            setUpRoom(room, layout);
            scaleRoom(room);
            UpdatePc(layout, room);

        }

        /**
         * Computes offsets and scaling's for the RoomLayout
         * @param room Room Object
         */
        function generateOffsetAndScale(room) {

            var clientHeight = $(window).height();
            if (roomsToshow == 4) {
                clientHeight = clientHeight / 2;
            }

            clientHeight = clientHeight - document.getElementById('header_' + room.id).clientHeight - 5;

            if (roomsToshow > 1) {
                clientHeight -= 5;
            }
            if (room.config.vertical && room.config.mode == 1) {
                clientHeight = clientHeight * (1 - (room.config.scale / 100));
            }
            var roomLayout = document.getElementById('roomLayout_' + room.id);

            var clientWidth = roomLayout.clientWidth;
            //roomLayout.style.height = clientHeight + "px";

            var scaleX;
            if (room.xDifference != 0) {
                scaleX = clientWidth / room.xDifference;
            } else {
                scaleX = clientWidth;
            }
            var scaleY;
            if (room.yDifference != 0) {
                scaleY = clientHeight / room.yDifference;
            } else {
                scaleY = clientHeight;
            }
            var scaleYs = (clientHeight - (picSizeY * scaleY)) / room.yDifference;
            var scaleXs = (clientWidth - (picSizeX * scaleX)) / room.xDifference;
            if (scaleYs <= 0) {
                scaleYs = 9999;
            }
            if (scaleXs <= 0) {
                scaleXs = 9999;
            }


            var tmp = [scaleYs, scaleY, scaleXs, scaleX, (clientHeight * 0.9) / picSizeY, (clientWidth * 0.9) / picSizeX];
            room.scale = Math.min.apply(Math, tmp);
            room.xOffset = 0 - room.minX;
            room.yOffset = 0 - room.minY;
            room.xOffset += ((1 / 2 * (clientWidth - (((room.maxX + room.xOffset) * room.scale) + picSizeX * room.scale))) / room.scale);
            room.yOffset += ((1 / 2 * (clientHeight - (((room.maxY + room.yOffset) * room.scale) + picSizeY * room.scale))) / room.scale);
        }


        /**
         * adds images for each pc to Room Layout
         * @param room Room Object
         * @param layout Layout json
         */
        function setUpRoom(room, layout) {
            for (var i = 0; i < layout.length; i++) {

                if (layout[i].y != null && layout[i].x != null && !isNaN(layout[i].y) && !isNaN(layout[i].x)) {
                    var text = "<div class= 'PCImgDiv'  id ='layout_PC_div_" + room.id + "_" + layout[i].id + "'>" +

                        "<div class= 'OverlayDiv' id ='layout_PC_overlay_" + room.id + "_" + layout[i].id + "'>" +
                        "</div>" +
                        "<img class= 'pcImg' id ='layout_PC_" + room.id + "_" + layout[i].id + "'> </img>" +
                        "</div>";

                    $('#roomLayout_' + room.id).append(text);
                    if (layout[i].hasOwnProperty('overlay')) {
                        for (var a = 0; a < layout[i].overlay.length; a++) {
                            addOverlay($('#layout_PC_overlay_' + room.id + "_" + layout[i].id), layout[i].overlay[a]);
                        }
                    }
                }
            }
        }

        /**
         * Adds an overlay to an div(here the PC's shown in the RoomLayout).
         * @param object Object where the overlay should be added
         * @param overlayName name of the overlay (image name without ending)
         */
        function addOverlay(object, overlayName) {
            var a = [".svg", ".png", "jpg"];
            var imgname;
            for (var i = 0; i < a.length; a++) {
                if (imageExists("img/overlay/" + overlayName + a[i])) {
                    imgname = "img/overlay/" + overlayName + a[i];
                    break;
                }

            }
            if (imgname == null) {
                return;
            }
            var text = $("<img class='overlay'  src='" + imgname + "'></img>");
            text.addClass("overlay-" + overlayName);

            object.append(text);


        }


        var imgExists = {};

        /**
         * checks if images exists on the webserver(chaches it also)
         * @param image_url Path to the image
         */
        function imageExists(image_url) {
            if (!imgExists.hasOwnProperty(image_url)) {
                var http = new XMLHttpRequest();
                http.open('HEAD', image_url, false);
                http.send();
                imgExists[image_url] = http.status != 404;
            }
            return imgExists[image_url];

        }

        /**
         * Querys Pc states
         * @param ids Room ID's which should be queried. Format for e.g.: "20,5,6"
         */
        function queryRooms(ids) {
            $.ajax({
                url: "../../../api.php?do=locationinfo&action=roominfo&id=" + ids + "&coords=0",
                dataType: 'json',
                cache: false,
                timeout: 30000,
                success: function (result) {
                    var l = result.length;
                    if (result[0] == null) {
                        console.log("Error: Backend reported null back for RoomUpdate, this might happend if the room isn't" +
                            "configurated.");
                        return;
                    }
                    for (var i = 0; i < l; i++) {

                        UpdatePc(result[i].computer, rooms[result[i].id]);
                    }
                }, error: function () {

                }
            })
        }


        /**
         * Adjust pc coordinate depending on room rotation
         * @param r Rotation, from 0 - 3 (int)
         * @param layout Layout json
         */
        function rotateRoom(r, layout) {
            for (var z = 0; z < r; z++) {
                for (var i = 0; i < layout.length; i++) {
                    var x = parseInt(layout[i].x);
                    var y = parseInt(layout[i].y);
                    layout[i].x = y;
                    layout[i].y = -x;
                }
            }
        }

        /**
         * Positions the computer images in the roomLayout div accoring to ther potion and div size
         * @param room Room object
         */
        function scaleRoom(room) {
            if (room.layout == null) {
                return;
            }
            for (var i = 0; i < room.layout.length; i++) {
                if (room.layout[i].y != null && room.layout[i].x != null && !isNaN(room.layout[i].y) && !isNaN(room.layout[i].x)) {
                    var tmp = document.getElementById("layout_PC_div_" + room.id + "_" + room.layout[i].id);
                    var img = document.getElementById("layout_PC_" + room.id + "_" + room.layout[i].id);
                    if (tmp != null) {
                        tmp.style.width = (picSizeX * room.scale);
                        tmp.setAttribute("style", "width:" + (picSizeX * room.scale) + "px");
                        tmp.style.height = (picSizeY * room.scale) + "px";
                        tmp.style.left = ((parseInt(room.layout[i].x) + room.xOffset) * room.scale) + "px";
                        tmp.style.top = ((parseInt(room.layout[i].y) + room.yOffset) * room.scale ) + "px";
                    }
                }
            }
        }


        /**
         * Updates the PC's (images) in the room layout. Also Updates how many pc's are free.
         * @param update Update Json from query for one(!) room
         * @param room Room object
         */
        function UpdatePc(update, room) {
            if (update === undefined || update == null) {
                return;
            }
            var freePcs = 0;
            for (var i = 0; i < update.length; i++) {
                var imgobj = document.getElementById("layout_PC_" + room.id + "_" + update[i].id);


                var img;
                // Pc free
                if (update[i].pcState == "IDLE") {
                    if (supportSvg) {
                        img = "img/pc_free";
                    } else {
                        imgobj.style.backgroundColor = "green";
                    }
                    freePcs++;
                    // Pc in use
                } else if (update[i].pcState == "OCCUPIED") {
                    if (supportSvg) {
                        img = "img/pc_used";
                    } else {
                        imgobj.style.backgroundColor = "red";
                    }
                    // PC off
                } else if (update[i].pcState == "OFF") {
                    if (supportSvg) {
                        img = "img/pc_off";
                    } else {
                        imgobj.style.backgroundColor = "black";
                    }
                    freePcs++;
                } else {
                    if (supportSvg) {
                        img = "img/pc_defect";
                    } else {
                        imgobj.style.backgroundColor = "black";
                    }
                }

                if (imgobj != null && supportSvg) {
                    if (room.config.einkmode) {
                        img = img + "_eink";
                    }
                    imgobj.src = img + ".svg";
                }

            }

            room.freePcs = freePcs;


        }

        /*
         /========================================== Misc =============================================
         */
        var resizeTimeout;

        // called when browser window changes size
        // scales calendar and room layout acordingly

        $(window).resize(function () {
            clearTimeout(resizeTimeout);
            resizeTimeout = setTimeout(function () {

                for (var property in rooms) {

                    rooms[property].resized = true;
                    if (rooms[property].config.mode != null) {
                        if (rooms[property].config.mode != 3) {
                            scaleCalendar(rooms[property]);

                        }
                        if (rooms[property].config.mode != 2) {
                            generateOffsetAndScale(rooms[property]);
                            scaleRoom(rooms[property]);
                        }
                    }
                }
            }, 50);
        });


        /**
         * returns parameter value from the url
         *  @param sParam
         *  @returns value for given parameter
         */
        var getUrlParameter = function getUrlParameter(sParam) {
            var sPageURL = decodeURIComponent(window.location.search.substring(1)),
                sURLVariables = sPageURL.split('&'),
                sParameterName,
                i;

            for (i = 0; i < sURLVariables.length; i++) {
                sParameterName = sURLVariables[i].split('=');

                if (sParameterName[0] === sParam) {
                    return sParameterName[1] === undefined ? true : sParameterName[1];
                }
            }
        };

        /**
         * Function for translation
         * @param toTranslate key which we wan't to translate
         * @param lang languages in which should be translated
         * @returns r translated string
         */
        function t(toTranslate, lang) {

            var r;
            if (lang === undefined) {
                r = translation['en'][toTranslate];
            } else {
                r = translation[lang][toTranslate];
            }
            return r;
        }


        /**
         * Used in Mode 4, switches given room from Timetable to Roomlayout and vice versa
         * @param room
         */
        function switchLayout(room) {
            var car = document.getElementById("calendar_" + room.id);
            var roomLayout = document.getElementById("roomLayout_" + room.id);

            if (car.style.display == "none") {
                roomLayout.style.display = "none";
                car.style.display = "block";
                if (room.resized) {
                    scaleCalendar(room);
                    room.resized = false;
                }
            } else {
                car.style.display = "none";
                roomLayout.style.display = "block";
                if (room.resized) {
                    generateOffsetAndScale(room);
                    scaleRoom(room);
                    room.resized = false;
                }
            }
        }


        /**
         * adds a progressbar to a given room (id) used in mode 4
         * @param id room id
         */
        function generateProgressBar(id) {

            var div = document.createElement("div");
            div.id = "progressBar_" + id;
            div.classList.add("progressbar");
            //document.body.appendChild(div);
            $("#room_" + id).append(div);

        }
        /**
         * Animates the progressbar used in mode 4
         * @param roomId
         * @param time
         * @constructor
         */
        function MoveProgressBar(roomId, time) {
            var elem = document.getElementById("progressBar_" + roomId);
            var width = 1;
            var id = setInterval(frame, time /100);

            function frame() {
                if (width >= 100) {
                    clearInterval(id);
                } else {
                    width++;
                    elem.style.width = width + '%';
                }
            }
        }


    </script>
</head>
<body>
</body>
</html>