Revised version of the resource page + related plugins
[myslice.git] / plugins / scheduler2 / static / js / scheduler2.js
index 10eaa9a..fe8e3e8 100755 (executable)
@@ -26,6 +26,8 @@
 #\r
 */\r
 \r
+// XXX groupid = all slots those that go with a min granularity\r
+\r
 /* some params */\r
 var scheduler2;\r
 var scheduler2Instance;\r
@@ -33,26 +35,40 @@ var scheduler2Instance;
 var schedulerCtrlPressed = false;\r
 //table Id\r
 var schedulerTblId = "scheduler-reservation-table";\r
-var schedulerTblFirstColWidth = 150;\r
-//Some Data\r
+var SCHEDULER_FIRST_COLWIDTH = 150;\r
+\r
+\r
+/* Number of scheduler slots per hour. Used to define granularity. Should be inferred from resources XXX */\r
 var schedulerSlotsPerHour = 6;\r
+var RESOURCE_DEFAULT_GRANULARITY    = 1800 /* s */; // should be computed automatically from resource information\r
+var DEFAULT_GRANULARITY             = 1800 /* s */; // should be computed automatically from resource information. Test with 600\r
+var DEFAULT_PAGE_RANGE = 5;\r
+\r
 var schedulerMaxRows = 12;\r
+\r
+/* All resources */\r
 var SchedulerData = [];\r
+\r
+/* ??? */\r
 var SchedulerSlots = [];\r
+\r
 var SchedulerDateSelected = new Date();\r
+// Round to midnight\r
+SchedulerDateSelected.setHours(0,0,0,0);\r
+\r
+/* Filtered resources */\r
 var SchedulerDataViewData = [];\r
+\r
 var SchedulerSlotsViewData = [];\r
-var SchedulerTotalCells;\r
-var SchedulerTotalVisibleCells;\r
 //Help Variables\r
 var _schedulerCurrentCellPosition = 0;\r
-var _leasesDone = false;\r
-var _resourcesDone = false;\r
 //Enable Debug\r
 var schedulerDebug = true;\r
 //tmp to delete\r
 var tmpSchedulerLeases = [];\r
 \r
+var SCHEDULER_COLWIDTH = 50;\r
+\r
 (function($) {\r
         scheduler2 = Plugin.extend({\r
 \r
@@ -67,13 +83,21 @@ var tmpSchedulerLeases = [];
                 this.classname = "scheduler2";\r
                 // Call the parent constructor, see FAQ when forgotten\r
                 this._super(options, element);\r
+\r
+                var scope = this._get_scope()\r
+\r
+                // XXX not needed\r
                 scheduler2Instance = this;\r
+\r
                 // We need to remember the active filter for datatables filtering\r
+                // XXX not needed\r
                 this.filters = Array();\r
 \r
+                // XXX BETTER !!!!\r
+                $(window).delegate('*', 'keypress', function (evt){\r
+                        alert("erm");\r
+                      });\r
 \r
-                SchedulerSlots = schedulerGetSlots(60 / schedulerSlotsPerHour);\r
-                //selection from table \r
                 $(window).keydown(function(evt) {\r
                     if (evt.which == 17) { // ctrl\r
                         schedulerCtrlPressed = true;\r
@@ -83,154 +107,178 @@ var tmpSchedulerLeases = [];
                         schedulerCtrlPressed = false;\r
                     }\r
                 });\r
-                $("#" + schedulerTblId).on('mousedown', 'td', rangeMouseDown).on('mouseup', 'td', rangeMouseUp).on('mousemove', 'td', rangeMouseMove);\r
 \r
-                // Explain this will allow query events to be handled\r
-                // What happens when we don't define some events ?\r
-                // Some can be less efficient\r
+                // XXX naming\r
+                //$("#" + schedulerTblId).on('mousedown', 'td', rangeMouseDown).on('mouseup', 'td', rangeMouseUp).on('mousemove', 'td', rangeMouseMove);\r
 \r
-                if (schedulerDebug) console.time("Listening_to_queries");\r
-                /* Listening to queries */\r
+                this._resources_received = false;\r
+                this._leases_received = false;\r
+                \r
+                scope._leases_by_resource = {};\r
 \r
-                this.listen_query(options.query_uuid);\r
-                //this.listen_query(options.query_all_uuid, 'all');\r
-                this.listen_query(options.query_all_resources_uuid, 'all_resources');\r
-                this.listen_query(options.query_lease_uuid, 'lease');\r
-                this.listen_query(options.query_all_leases_uuid, 'all_leases');\r
-                if (schedulerDebug) console.timeEnd("Listening_to_queries");\r
+                /* Listening to queries */\r
+                this.listen_query(options.query_uuid, 'resources');\r
+                this.listen_query(options.query_lease_uuid, 'leases');\r
+\r
+                /* Generate slots according to the default granularity. Should\r
+                 * be updated when resources arrive.  Should be the pgcd in fact XXX */\r
+                this._granularity = DEFAULT_GRANULARITY;\r
+                scope.granularity = this._granularity;\r
+                this._all_slots = this._generate_all_slots();\r
+\r
+                $('#' + schedulerTblId + ' thead tr th:eq(0)').css("width", SCHEDULER_FIRST_COLWIDTH);\r
+                //this get width might need fix depending on the template \r
+                var tblwidth = $('#scheduler-tab').parent().outerWidth();\r
+\r
+                /* Number of visible cells...*/\r
+                this._num_visible_cells = parseInt((tblwidth - SCHEDULER_FIRST_COLWIDTH) / SCHEDULER_COLWIDTH);\r
+                /* ...should be a multiple of the lcm of all encountered granularities. */\r
+                // XXX Should be updated everytime a new resource is added\r
+                this._lcm_colspan = this._lcm(this._granularity, RESOURCE_DEFAULT_GRANULARITY) / this._granularity;\r
+                this._num_visible_cells = this._num_visible_cells - this._num_visible_cells % this._lcm_colspan;\r
+                /* scope also needs this value */\r
+                scope.num_visible_cells = this._num_visible_cells;\r
+                scope.lcm_colspan = this._lcm_colspan;\r
+\r
+                scope.options = this.options;\r
+                scope.from = 0;\r
+\r
+                // A list of {id, time} dictionaries representing the slots for the given day\r
+                scope.slots = this._all_slots;\r
+                this.scope_resources_by_key = {};\r
+\r
+                this._initUI();\r
 \r
             },\r
 \r
             /* Handlers */\r
 \r
-            /* all_ev QUERY HANDLERS Start */\r
-            on_all_ev_clear_records: function(data) {\r
-                //alert('all_ev clear_records');\r
-            },\r
-            on_all_ev_query_in_progress: function(data) {\r
-                // alert('all_ev query_in_progress');\r
-            },\r
-            on_all_ev_new_record: function(data) {\r
-                //alert('all_ev new_record');\r
-            },\r
-            on_all_ev_query_done: function(data) {\r
-                //alert('all_ev query_done');\r
+            _get_scope : function()\r
+            {\r
+                return angular.element(document.getElementById('SchedulerCtrl')).scope();\r
             },\r
-            //another plugin has modified something, that requires you to update your display. \r
-            on_all_ev_field_state_changed: function(data) {\r
-                //alert('all_ev query_done');\r
-            },\r
-            /* all_ev QUERY HANDLERS End */\r
-            /* all_resources QUERY HANDLERS Start */\r
-            on_all_resources_clear_records: function(data) {\r
-                //data is empty on load\r
-            },\r
-            on_all_resources_query_in_progress: function(data) {\r
-                //data is empty on load\r
+            \r
+            _scope_set_resources : function()\r
+            {\r
+                var self = this;\r
+                var scope = this._get_scope();\r
+\r
+                var records = manifold.query_store.get_records(this.options.query_uuid);\r
+\r
+                scope.resources = [];\r
+\r
+                $.each(records, function(i, record) {\r
+                    if (!record.exclusive)\r
+                        return true; // ~ continue\r
+\r
+                    // copy not to modify original record\r
+                    var resource = jQuery.extend(true, {}, record);\r
+\r
+                    // Fix granularity\r
+                    resource.granularity = typeof(resource.granularity) == "number" ? resource.granularity : RESOURCE_DEFAULT_GRANULARITY;\r
+                    resource.leases = []; // a list of occupied timeslots\r
+\r
+                    self.scope_resources_by_key[resource['urn']] = resource;\r
+                    scope.resources.push(resource);\r
+                });\r
             },\r
-            on_all_resources_new_record: function(data) {\r
-                //alert(data.toSource());\r
-                if (data.exclusive == true) {\r
-                    var tmpGran = schedulerDebug && data.granularity == null ? 1800 : data.granularity;\r
-                    SchedulerData.push({\r
-                        id: data.urn,\r
-                        index: SchedulerData.length,\r
-                        name: data.hrn,\r
-                        granularity: tmpGran,\r
-                        leases: schedulerGetLeases(60 / schedulerSlotsPerHour, tmpGran),\r
-                        type: data.type,\r
-                        org_resource: data\r
-                    });\r
-                    /*if (schedulerDebug && SchedulerData[SchedulerData.length - 1].org_resource.network_hrn == 'omf') {\r
-                        SchedulerData[SchedulerData.length - 1].granularity = 1800;\r
-                    }*/\r
-                }\r
-                //alert(data.toSource());\r
+\r
+            _scope_clear_leases: function()\r
+            {\r
+                var self = this;\r
+                var scope = this._get_scope();\r
+\r
+                // Setup leases with a default free status...\r
+                $.each(this.scope_resources_by_key, function(resource_key, resource) {\r
+                    resource.leases = [];\r
+                    var colspan_lease = resource.granularity / self._granularity; //eg. 3600 / 1800 => 2 cells\r
+                    for (i=0; i < self._all_slots.length / colspan_lease; i++) { // divide by granularity\r
+                        resource.leases.push({\r
+                            id:     'coucou',\r
+                            status: 'free', // 'selected', 'reserved', 'maintenance' XXX pending ??\r
+                        });\r
+                    }\r
+                });\r
 \r
             },\r
-            on_all_resources_query_done: function(data) {\r
-                _resourcesDone = true;\r
-                this._initScheduler();\r
+\r
+            _scope_set_leases: function()\r
+            {\r
+                var self = this;\r
+                var scope = this._get_scope();\r
+            \r
+                var leases = manifold.query_store.get_records(this.options.query_lease_uuid);\r
+                $.each(leases, function(i, lease) {\r
+\r
+                    console.log("SET LEASES", new Date(lease.start_time* 1000));\r
+                    console.log("          ", new Date(lease.end_time* 1000));\r
+                    // XXX We should ensure leases are correctly merged, otherwise our algorithm won't work\r
+\r
+                    // Populate leases by resource array: this will help us merging leases later\r
+                    if (!(lease.resource in scope._leases_by_resource))\r
+                        scope._leases_by_resource[lease.resource] = [];\r
+                    scope._leases_by_resource[lease.resource].push(lease);\r
+\r
+                    var resource = self.scope_resources_by_key[lease.resource];\r
+                    var day_timestamp = SchedulerDateSelected.getTime() / 1000;\r
+\r
+                    var id_start = (lease.start_time - day_timestamp) / resource.granularity;\r
+                    if (id_start < 0) {\r
+                        /* Some leases might be in the past */\r
+                        id_start = 0;\r
+                    }\r
+    \r
+                    var id_end   = (lease.end_time   - day_timestamp) / resource.granularity - 1;\r
+                    var colspan_lease = resource.granularity / self._granularity; //eg. 3600 / 1800 => 2 cells\r
+                    if (id_end >= self._all_slots.length / colspan_lease) {\r
+                        /* Limit the display to the current day */\r
+                        id_end = self._all_slots.length / colspan_lease\r
+                    }\r
+\r
+                    for (i = id_start; i <= id_end; i++)\r
+                        // the same slots might be affected multiple times.\r
+                        // PENDING_IN + PENDING_OUT => IN \r
+                        //\r
+                        // RESERVED vs SELECTED !\r
+                        //\r
+                        // PENDING !!\r
+                        resource.leases[i].status = 'selected'; \r
+                });\r
             },\r
-            //another plugin has modified something, that requires you to update your display. \r
-            on_all_resources_field_state_changed: function(data) {\r
-                //alert('all_resources query_done');\r
+\r
+            on_resources_query_done: function(data)\r
+            {\r
+                this._resources_received = true;\r
+                this._scope_set_resources();\r
+                this._scope_clear_leases();\r
+                if (this._leases_received)\r
+                    this._scope_set_leases();\r
+                    \r
+                this._get_scope().$apply();\r
             },\r
-            /* all_resources QUERY HANDLERS End */\r
-            /* lease QUERY HANDLERS Start */\r
-            on_lease_clear_records: function(data) { console.log('clear_records'); },\r
-            on_lease_query_in_progress: function(data) { console.log('lease_query_in_progress'); },\r
-            on_all_leases_new_record: function(data) {\r
-                if (data.resource.indexOf("nitos") > -1) {\r
-                    tmpSchedulerLeases.push({\r
-                        id: schedulerGetSlotId(data.start_time, data.duration, data.granularity),\r
-                        end_id: schedulerGetSlotId(data.end_time, data.duration, data.granularity),\r
-                        slice: data.slice,\r
-                        status: 'reserved',\r
-                        resource: data.resource,\r
-                        network: data.network,\r
-                        start_time: new Date(data.start_time * 1000),\r
-                        start_time_unixtimestamp: data.start_time,\r
-                        end_time: new Date(data.end_time * 1000),\r
-                        end_time_unixtimestamp: data.end_time,\r
-                        lease_type: data.lease_type,\r
-                        granularity: data.granularity,\r
-                        duration: data.duration\r
-                    });\r
+\r
+            on_leases_query_done: function(data)\r
+            {\r
+                this._leases_received = true;\r
+                if (this._resources_received) {\r
+                    this._scope_set_leases();\r
+                    this._get_scope().$apply();\r
                 }\r
-                //console.log(data.toSource()); console.log('lease_new_record');\r
             },\r
-            on_all_leases_query_done: function(data) {\r
-                _leasesDone = true;\r
-                this._initScheduler();\r
-                // console.log('lease_query_done');\r
-            },\r
-            //another plugin has modified something, that requires you to update your display. \r
-            on_lease_field_state_changed: function(data) { console.log('lease_field_state_changed'); },\r
-            /* lease QUERY HANDLERS End */\r
 \r
+            /* Filters on resources */\r
+            on_resources_filter_added:   function(filter) { this._get_scope().$apply(); },\r
+            on_resources_filter_removed: function(filter) { this._get_scope().$apply(); },\r
+            on_resources_filter_clear:   function()       { this._get_scope().$apply(); },\r
 \r
-            // no prefix\r
-            on_filter_added: function(filter) {\r
-                this.filters.push(filter);\r
-                this._SetFiletredResources(this.filters);\r
-                //angular and UI\r
-                var tmpScope = angular.element(document.getElementById('SchedulerCtrl')).scope();\r
-                if (SchedulerDataViewData.length == 0) {\r
-                    $("#plugin-scheduler").hide();\r
-                    $("#plugin-scheduler-empty").show();\r
-                    tmpScope.clearStuff();\r
-                } else {\r
-                    $("#plugin-scheduler-empty").hide();\r
-                    $("#plugin-scheduler").show();\r
-                    tmpScope.initSchedulerResources(schedulerMaxRows < SchedulerDataViewData.length ? schedulerMaxRows : SchedulerDataViewData.length);\r
-                }\r
-            },\r
+            /* Filters on leases ? */\r
+            on_leases_filter_added:      function(filter) { this._get_scope().$apply(); },\r
+            on_leases_filter_removed:    function(filter) { this._get_scope().$apply(); },\r
+            on_leases_filter_clear:      function()       { this._get_scope().$apply(); },\r
 \r
-            on_filter_removed: function(filter) {\r
-                // Remove corresponding filters\r
-                this.filters = $.grep(this.filters, function(x) {\r
-                    return x == filter;\r
-                });\r
-                this._SetFiletredResources(this.filters);\r
-                //angular and UI\r
-                var tmpScope = angular.element(document.getElementById('SchedulerCtrl')).scope();\r
-                if (SchedulerDataViewData.length == 0) {\r
-                    $("#plugin-scheduler").hide();\r
-                    $("#plugin-scheduler-empty").show();\r
-                    tmpScope.clearStuff();\r
-                } else {\r
-                    $("#plugin-scheduler-empty").hide();\r
-                    $("#plugin-scheduler").show();\r
-                    tmpScope.initSchedulerResources(schedulerMaxRows < SchedulerDataViewData.length ? schedulerMaxRows : SchedulerDataViewData.length);\r
-                }\r
-            },\r
+            /* INTERNAL FUNCTIONS */\r
 \r
-            on_filter_clear: function() {\r
-                this.filters = [];\r
-                this._SetFiletredResources(this.filters);\r
-                //angular and UI\r
-                var tmpScope = angular.element(document.getElementById('SchedulerCtrl')).scope();\r
+/* XXX IN TEMPLATE XXX\r
                 if (SchedulerDataViewData.length == 0) {\r
                     $("#plugin-scheduler").hide();\r
                     $("#plugin-scheduler-empty").show();\r
@@ -238,296 +286,158 @@ var tmpSchedulerLeases = [];
                 } else {\r
                     $("#plugin-scheduler-empty").hide();\r
                     $("#plugin-scheduler").show();\r
+                    // initSchedulerResources\r
                     tmpScope.initSchedulerResources(schedulerMaxRows < SchedulerDataViewData.length ? schedulerMaxRows : SchedulerDataViewData.length);\r
                 }\r
-            },\r
-\r
-            on_all_leases_filter_added: function(filter) {\r
-                console.log("Filter on Leases added !");\r
-            },\r
-\r
-            // ... be sure to list all events here\r
-\r
-            /* RECORD HANDLERS */\r
-            on_all_new_record: function(record) {\r
-                //alert('on_all_new_record');\r
-            },\r
-\r
-            debug: function(logTxt) {\r
-                if (typeof window.console != 'undefined') {\r
-                    console.debug(logTxt);\r
-                }\r
-            },\r
+*/\r
 \r
-            /* INTERNAL FUNCTIONS */\r
-            _initScheduler: function() {\r
-                if (_resourcesDone && _leasesDone) {\r
-                    SchedulerDataViewData = SchedulerData;\r
-                    /* GUI setup and event binding */\r
-                    this._FixLeases();\r
-                    this._initUI();\r
-                }\r
-            },\r
+            /**\r
+             * Initialize the date picker, the table, the slider and the buttons. Once done, display scheduler.\r
+             */\r
+            _initUI: function() \r
+            {\r
+                var self = this;\r
 \r
-            _initUI: function() {\r
-                //alert(1);\r
-                if (schedulerDebug) console.time("_initUI");\r
-                //init DatePicker Start\r
                 $("#DateToRes").datepicker({\r
                     dateFormat: "yy-mm-dd",\r
                     minDate: 0,\r
                     numberOfMonths: 3\r
                 }).change(function() {\r
-                    //Scheduler2.loadWithDate();\r
+                    // the selected date\r
                     SchedulerDateSelected = $("#DateToRes").datepicker("getDate");\r
-                    if (SchedulerDateSelected != null && SchedulerDateSelected != '') {\r
-                        for (var i = 0; i < SchedulerData.length; i++) {\r
-                            SchedulerData[i].leases = schedulerGetLeases(60 / schedulerSlotsPerHour, SchedulerData[i].granularity);\r
-                        }\r
-                        scheduler2Instance._FixLeases();\r
-                        $('#tblSlider').slider('value', 0);\r
-                        var tmpScope = angular.element(document.getElementById('SchedulerCtrl')).scope();\r
-                        tmpScope.initSchedulerResources(schedulerMaxRows < SchedulerDataViewData.length ? schedulerMaxRows : SchedulerDataViewData.length);\r
-\r
-                        //console.log(SchedulerDateSelected);\r
-                        //console.log(SchedulerDateSelected.getTime()/1000);\r
-                        var tomorrow = new Date(SchedulerDateSelected);\r
-                        tomorrow.setDate(SchedulerDateSelected.getDate()+1);\r
-                        //console.log(tomorrow);\r
-                        //console.log(tomorrow.getTime()/1000);\r
-                        \r
-                        // Remove previous date interval\r
-                        manifold.raise_event(scheduler2Instance.options.query_all_leases_uuid, FILTER_REMOVED, ['start_time', '>']);\r
-                        manifold.raise_event(scheduler2Instance.options.query_all_leases_uuid, FILTER_REMOVED, ['start_time', '<']);\r
-\r
-                        // Add new date interval\r
-                        manifold.raise_event(scheduler2Instance.options.query_all_leases_uuid, FILTER_ADDED, ['start_time', '>', SchedulerDateSelected.getTime()/1000]);\r
-                        manifold.raise_event(scheduler2Instance.options.query_all_leases_uuid, FILTER_ADDED, ['start_time', '<', tomorrow.getTime()/1000]);\r
-                    } else {\r
+                    if (SchedulerDateSelected == null || SchedulerDateSelected == '') {\r
                         alert("Please select a date, so the scheduler can reserve leases.");\r
+                        return;\r
                     }\r
+                    // Set slider to origin\r
+                    $('#tblSlider').slider('value', 0);\r
+                    // Refresh leases\r
+                    self._scope_clear_leases();\r
+                    self._scope_set_leases();\r
+                    // Refresh display\r
+                    self._get_scope().$apply();\r
                 }).datepicker('setDate', SchedulerDateSelected);\r
-                /*.click(function () {\r
-                $("#ui-datepicker-div").css("z-index", 5);\r
-            })*/\r
-                //End init DatePicker\r
-\r
-                //init Table\r
-                this._FixTable();\r
-                //End init Table\r
 \r
                 //init Slider\r
                 $('#tblSlider').slider({\r
                     min: 0,\r
-                    max: SchedulerTotalCells - SchedulerTotalVisibleCells,\r
+                    max: (this._all_slots.length - self._num_visible_cells) / self._lcm_colspan,\r
                     value: 0,\r
                     slide: function(event, ui) {\r
-                        //$("#amount").val("$" + ui.values[0] + " - $" + ui.values[1]);\r
-                        //console.log(ui.value);\r
-                        var angScope = angular.element(document.getElementById('SchedulerCtrl')).scope();\r
-                        if (_schedulerCurrentCellPosition > ui.value) {\r
-                            angScope.moveBackSlot(ui.value, ui.value + SchedulerTotalVisibleCells);\r
-                        } else if (_schedulerCurrentCellPosition < ui.value) {\r
-                            angScope.moveFrontSlot(ui.value, ui.value + SchedulerTotalVisibleCells);\r
-                        }\r
-                        _schedulerCurrentCellPosition = ui.value;\r
-                    }\r
+                        var scope = self._get_scope();\r
+                        scope.from = ui.value * self._lcm_colspan;\r
+                        scope.$apply();\r
+                   }\r
                 });\r
-                //End init Slider\r
-\r
-\r
-                //btn Submit leases\r
-                $('#btnSchedulerSubmit').click(function () {\r
-                    console.log("click btnSchedulerSubmit");\r
-                    var leasesForCommit = new Array();\r
-                    var tmpDateTime = SchedulerDateSelected;\r
-                    console.log(SchedulerData);\r
-                    for (var i = 0; i < SchedulerData.length; i++)\r
-                    {\r
-                        var tpmR = SchedulerData[i];\r
-                        //for capturing start and end of the lease\r
-                        var newLeaseStarted = false;\r
-                        for (var j = 0; j < tpmR.leases.length; j++) {\r
-                            var tpmL = tpmR.leases[j];\r
-                            if (newLeaseStarted == false && tpmL.status == 'selected') {\r
-                                //get date of the slot\r
-                                tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
-                                var unixStartTime = tmpDateTime.getTime() / 1000;\r
-                                //add lease object\r
-                                leasesForCommit.push({\r
-                                    resource: tpmR.id,\r
-                                    //granularity: tpmR.granularity,\r
-                                    //lease_type: null,\r
-                                    //slice: null,\r
-                                    start_time: unixStartTime,\r
-                                    end_time: null,\r
-                                    //duration: null\r
-                                });\r
-                                console.log(tpmR.id);\r
-                                newLeaseStarted = true;\r
-                            } else if (newLeaseStarted == true && tpmL.status != 'selected') {\r
-                                //get date of the slot\r
-                                tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
-                                var unixEndTime = tmpDateTime.getTime() / 1000;\r
-                                //upate end_time\r
-                                var tmpCL = leasesForCommit[leasesForCommit.length - 1];\r
-                                tmpCL.end_time = unixEndTime;\r
-                                //tmpCL.duration = schedulerFindDuration(tmpCL.start_time, tmpCL.end_time, tmpCL.granularity);\r
-                                newLeaseStarted = false;\r
-                            }\r
-                        }\r
-                    }\r
-                    console.log(leasesForCommit);\r
-                    for (var i = 0; i < leasesForCommit.length; i++) {\r
-                        manifold.raise_event(scheduler2Instance.options.query_lease_uuid, SET_ADD, leasesForCommit[i]);\r
-                    }\r
-                });\r
-                //\r
-\r
 \r
-                //End btn Submit leases\r
+                $('#btnSchedulerSubmit').click(this._on_submit);\r
 \r
-                //other stuff\r
                 $("#plugin-scheduler-loader").hide();\r
                 $("#plugin-scheduler").show();\r
-                //fixOddEvenClasses();\r
-                //$("#" + schedulerTblId + " td:not([class])").addClass("free");\r
-                if (schedulerDebug) console.timeEnd("_initUI");\r
             },\r
 \r
-        _FixLeases  : function () {\r
-            for (var i = 0; i < tmpSchedulerLeases.length; i++) {\r
-                var tmpLea = tmpSchedulerLeases[i];\r
-                if ((schedulerCompareOnDay(tmpLea.start_time, SchedulerDateSelected) == 0) ||\r
-                                (tmpLea.start_time <= SchedulerDateSelected && SchedulerDateSelected <= tmpLea.end_time) || \r
-                                (schedulerCompareOnDay(tmpLea.end_time, SchedulerDateSelected) == 0)) {\r
-                    var tmpRes = schedulerFindResourceById(SchedulerData, tmpLea.resource);\r
-                    if (tmpRes != null) {\r
-                        //Replace Lease with current lease from the manifold\r
-                        var orgLease = tmpRes.leases[tmpLea.id];\r
-                        tmpLea['groupid'] = orgLease.groupid;\r
-                        tmpLea['groupIndex'] = orgLease.groupIndex;\r
-                        if (orgLease.groupIndex != 0) {\r
-                            if (!window.console) {\r
-                                console.warn('there is an error with the leases of the resource :' + tmpRes.name + '\n The lease start in the middle of the granularity!' + '\n The Scheduler plugin might not work!');\r
-                            }\r
-                        }\r
-                        tmpRes.leases[tmpLea.id] = tmpLea;\r
-                        this._ExtractLeaseSlots(tmpRes, tmpRes.leases[tmpLea.id]);\r
+        // GUI EVENTS\r
+\r
+        // TO BE REMOVED\r
+        _on_submit : function()\r
+        {\r
+            var leasesForCommit = new Array();\r
+            var tmpDateTime = SchedulerDateSelected;\r
+            for (var i = 0; i < SchedulerData.length; i++)\r
+            {\r
+                var tpmR = SchedulerData[i];\r
+                //for capturing start and end of the lease\r
+                var newLeaseStarted = false;\r
+                for (var j = 0; j < tpmR.leases.length; j++) {\r
+                    var tpmL = tpmR.leases[j];\r
+                    if (newLeaseStarted == false && tpmL.status == 'selected') {\r
+                        //get date of the slot\r
+                        tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
+                        var unixStartTime = tmpDateTime.getTime() / 1000;\r
+                        //add lease object\r
+                        leasesForCommit.push({\r
+                            resource: tpmR.id,\r
+                            //granularity: tpmR.granularity,\r
+                            //lease_type: null,\r
+                            //slice: null,\r
+                            start_time: unixStartTime,\r
+                            end_time: null,\r
+                            //duration: null\r
+                        });\r
+                        console.log(tpmR.id);\r
+                        newLeaseStarted = true;\r
+                    } else if (newLeaseStarted == true && tpmL.status != 'selected') {\r
+                        //get date of the slot\r
+                        tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
+                        var unixEndTime = tmpDateTime.getTime() / 1000;\r
+                        //upate end_time\r
+                        var tmpCL = leasesForCommit[leasesForCommit.length - 1];\r
+                        tmpCL.end_time = unixEndTime;\r
+                        //tmpCL.duration = schedulerFindDuration(tmpCL.start_time, tmpCL.end_time, tmpCL.granularity);\r
+                        newLeaseStarted = false;\r
                     }\r
                 }\r
             }\r
-        },\r
-\r
-        _ExtractLeaseSlots: function (tmpRes, lease) {\r
-            var tmpStartDate = lease.start_time;\r
-            var tmpEndDate = lease.end_time;\r
-            var startLoop; var toLoop;\r
-            if (schedulerCompareOnDay(lease.start_time,lease.end_time) == 0) {\r
-                //in the same date\r
-                startLoop = lease.id;\r
-                toLoop = lease.end_id;\r
-            } else if (lease.start_time < SchedulerDateSelected && SchedulerDateSelected < lease.end_time) {\r
-                //one hole day (more than 3days)\r
-                startLoop = 0;\r
-                toLoop = tmpRes.leases.length;\r
-            } else if (schedulerCompareOnDay(lease.start_time, SchedulerDateSelected) == 0) {\r
-                //the same day and extends\r
-                startLoop = lease.id;\r
-                toLoop = tmpRes.leases.length;\r
-            } else if (schedulerCompareOnDay(lease.end_time, SchedulerDateSelected) == 0) {\r
-                //extends to the last say\r
-                startLoop = 0;\r
-                toLoop = lease.end_id;\r
-            }\r
-            //var minutGran = tmpRes.granularity * 60;\r
-            for (var li = lease.id; li < toLoop; li++) {\r
-                tmpRes.leases[li].status = 'reserved';\r
+            console.log(leasesForCommit);\r
+            for (var i = 0; i < leasesForCommit.length; i++) {\r
+                manifold.raise_event(scheduler2Instance.options.query_lease_uuid, SET_ADD, leasesForCommit[i]);\r
             }\r
-            \r
-            //reserved\r
-            //tmpRes.leases[tmpLea.id\r
         },\r
+        \r
+        // PRIVATE METHODS\r
 \r
-        _FixTable: function () {\r
-            var colWidth = 50;\r
-            SchedulerTotalCells = SchedulerSlots.length;\r
-            $('#' + schedulerTblId + ' thead tr th:eq(0)').css("width", schedulerTblFirstColWidth); //.css("display", "block");\r
-            //this get width might need fix depending on the template \r
-            var tblwidth = $('#scheduler-tab').parent().outerWidth();\r
-            SchedulerTotalVisibleCells = parseInt((tblwidth - schedulerTblFirstColWidth) / colWidth);\r
-\r
-            //if (SchedulerData.length == 0) {\r
-            //    //puth some test data\r
-            //    SchedulerData.push({ name: 'xyz+aaa', leases: schedulerGetLeases(60 / schedulerSlotsPerHour), urn: 'xyz+aaa', type: 'node' });\r
-            //    SchedulerData.push({ name: 'xyz+bbb', leases: schedulerGetLeases(60 / schedulerSlotsPerHour), urn: 'xyz+bbb', type: 'node' });\r
-            //    SchedulerData.push({ name: 'xyz+ccc', leases: schedulerGetLeases(60 / schedulerSlotsPerHour), urn: 'xyz+ccc', type: 'node' });\r
-            //    SchedulerData.push({ name: 'nitos1', leases: schedulerGetLeases(60 / schedulerSlotsPerHour), urn: 'nitos1', type: 'node' });\r
-            //}\r
-            var tmpScope = angular.element(document.getElementById('SchedulerCtrl')).scope();\r
-            tmpScope.initSchedulerResources(schedulerMaxRows < SchedulerDataViewData.length ? schedulerMaxRows : SchedulerDataViewData.length);\r
-\r
+        /**\r
+         * Greatest common divisor\r
+         */\r
+        _gcd : function(x, y)\r
+        {\r
+            return (y==0) ? x : this._gcd(y, x % y);\r
         },\r
 \r
-        _SetFiletredResources : function (filters) {\r
-            if (filters.length > 0) {\r
-                SchedulerDataViewData = new Array();\r
-                var tmpAddIt = true;\r
-                for (var i = 0; i < SchedulerData.length; i++) {\r
-                    loopfilters:\r
-                    for (var f = 0; f < filters.length; f++) {\r
-                        tmpAddIt = this._FilterResource(SchedulerData[i], filters[f]);\r
-                        if (tmpAddIt == false) break loopfilters;\r
-                    }\r
-                    if (tmpAddIt) {\r
-                        SchedulerDataViewData.push(SchedulerData[i]);\r
-                    }\r
-                }\r
-            } else {\r
-                SchedulerDataViewData = SchedulerData;\r
-            }\r
+        /**\r
+         * Least common multiple\r
+         */\r
+        _lcm : function(x, y)\r
+        {\r
+            return x * y / this._gcd(x, y);\r
+        },\r
+    \r
+        _pad_str : function(i)\r
+        {\r
+            return (i < 10) ? "0" + i : "" + i;\r
         },\r
 \r
-        _FilterResource: function (resource, filter) {\r
-            var key = filter[0];\r
-            var op = filter[1];\r
-            var value = filter[2];\r
-            var colValue = resource.org_resource[key];\r
-            var ret = true;\r
-            if (schedulerDebug &&  colValue == 'omf') colValue = 'nitos';\r
-\r
-            if (op == '=' || op == '==') {\r
-                if (colValue != value || colValue == null || colValue == "" || colValue == "n/a")\r
-                    ret = false;\r
-            } else if (op == 'included') {\r
-                $.each(value, function (i, x) {\r
-                    if (x == colValue) {\r
-                        ret = true;\r
-                        return false;\r
-                    } else {\r
-                        ret = false;\r
-                    }\r
-                });\r
-            } else if (op == '!=') {\r
-                if (colValue == value || colValue == null || colValue == "" || colValue == "n/a")\r
-                    ret = false;\r
+        /**\r
+         * Member variables used:\r
+         *   _granularity\r
+         * \r
+         * Returns:\r
+         *   A list of {id, time} dictionaries.\r
+         */\r
+        _generate_all_slots: function()\r
+        {\r
+            var slots = [];\r
+            // Start with a random date (a first of a month), only time will matter\r
+            var d = new Date(2014, 1, 1, 0, 0, 0, 0);\r
+            var i = 0;\r
+            // Loop until we change the day\r
+            while (d.getDate() == 1) {\r
+                // Nicely format the time...\r
+                var tmpTime = this._pad_str(d.getHours()) + ':' + this._pad_str(d.getMinutes());\r
+                /// ...and add the slot to the list of results\r
+                slots.push({ id: i, time: tmpTime });\r
+                // Increment the date with the granularity\r
+                d = new Date(d.getTime() + this._granularity * 1000);\r
+                i++;\r
             }\r
+            return slots;\r
 \r
-            return ret;\r
         },\r
-\r
-        _SetPeriodInPage: function (start, end) {\r
-        }\r
     });\r
 \r
-    //Sched2 = new Scheduler2();\r
-\r
     /* Plugin registration */\r
     $.plugin('Scheduler2', scheduler2);\r
 \r
-    // TODO Here use cases for instanciating plugins in different ways like in the pastie.\r
-\r
-\r
 })(jQuery);\r
 \r
 \r