odoo.define('web_scheduler.SchedulerView', function (require) {
    "use strict";

    var core = require('web.core');
    var data_manager = require('web.data_manager');
    var formats = require('web.formats');
    var Model = require('web.Model');
    var time = require('web.time');
    var View = require('web.View');
    var form_common = require('web.form_common');
    var Dialog = require('web.Dialog');

    var _t = core._t;
    var _lt = core._lt;
    var QWeb = core.qweb;


    var SchedulerView = View.extend({
        display_name: _lt('Scheduler'),
        events: {

        },
        icon: 'fa-calendar-check-o',
        require_fields: true,
        template: 'SchedulerView',

        init: function () {
            var self = this;
            self.flag =false;
            self.rooms_stop_sales=[];
            self.rooms_blocked=[];
            console.log("INIT");
            self.userUid=arguments[1].context.uid
            console.log("UID: ",this.userUid);

            this.main_domain=arguments[1].domain.slice(0);
            this._super.apply(this, arguments);
            this.has_been_loaded = $.Deferred();
            this.chart_id = _.uniqueId();
            this.focus_date = moment();  // main date displayed on the gantt chart
            this.dimenssions={};
            this.gantt_events = [];

            // The type of the view:
            // gantt = classic gantt view (default)
            // consolidate = values of the first children are consolidated in the gantt's task
            // planning = children are displayed in the gantt's task
            this.type = this.fields_view.arch.attrs.type || 'gantt';

            // Use scale_zoom attribute in xml file to specify zoom timeline (day,week,month,year),
            // by default month.
            var scale = this.fields_view.arch.attrs.scale_zoom;
            if (!_.contains(['week_timeline', 'two_week_timeline', 'month_timeline'], scale)) {
                this.scale = "month_timeline";
            }else{
                this.scale = this.fields_view.arch.attrs.scale_zoom;
            }

            // gather the fields to get
            var fields_to_gather = [
                "date_start",
                "date_delay",
                "date_stop",
                "consolidation",
                "progress",
                "y_object",
                "y_model",
                "y_property"
            ];
            var fields = _.compact(_.map(fields_to_gather, function(key) {
                return self.fields_view.arch.attrs[key] || '';
            }));
            fields.push("name");

            // consolidation exclude, get the related fields
            if (this.fields_view.arch.attrs.consolidation_exclude) {
                fields = fields.concat(this.fields_view.arch.attrs.consolidation_exclude);
            }
            this.fields_to_fetch = fields;  //FIXME: useless?
            console.log("this.fields_to_fetch: ",this.fields_to_fetch);
            //////////////////////////////////////////////
            this.dataset_events = [];
            this.COLOR_PALETTE = ['#f57900', '#cc0000', '#d400a8', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400',
                '#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f',
                '#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
                '#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900' ];
            this.color_map = {};
            this.last_search = [];
            this.range_start = null;
            this.range_stop = null;
            window.range_start=this.range_start;
            window.range_stop=this.range_stop;
            this.update_range_dates(this.focus_date);
            this.selected_filters = [];

            this.calendar_fields = {};
            this.ids = this.dataset.ids;
            this.color_values = [];
            this.info_fields = [];

            this.name = this.fields_view.name || this.fields_view.arch.attrs.string;
            this.view_id = this.fields_view.view_id;

            // mode, one of month, week or day
            this.mode = this.fields_view.arch.attrs.mode;

            // date_start is mandatory, date_delay and date_stop are optional
            this.date_start = this.fields_view.arch.attrs.date_start;
            this.date_delay = this.fields_view.arch.attrs.date_delay;
            this.date_stop = this.fields_view.arch.attrs.date_stop;

            //////////////////////////////////////////////
        },

        willStart: function () {
            console.log("WILL START");
            var self = this;
            var defs = [];
            defs.push(this._super());
            defs.push(data_manager.load_fields(this.dataset).then(function (fields) {
                self.fields = fields;
                if(self.fields.color) {
                    self.fields_to_fetch.push('color');
                }
                if(self.fields.active) {
                    self.fields_to_fetch.push('active');
                }
            }));

            return $.when.apply($, defs);
        },
        findObjectByKey: function (array, key, value) {
            for (var i = 0; i < array.length; i++) {
                if (array[i][key] === value) {
                    return array[i];
                }
            }
            return null;
        },
        start: function () {
            var self = this;
            console.log("START");
            console.log()
            this.$el.addClass(this.fields_view.arch.attrs.class);
            var dim = []
            var sucess=function (results) {
               _.map(results, function(result) {
                    result['key'] = result['id'];
                    result['label'] = result[self.fields_view.arch.attrs.y_label]
                    delete result[self.fields_view.arch.attrs.y_label];
                    delete result['id'];
                   return result;
                });

                results = results.reduce(function(acc, item) {
                  var key = item.room_type_id;
                  delete item.room_type_id;
                  acc[key] = acc[key] || [];
                  acc[key].push(item);
                  return acc;
                }, {});

                Object.keys(results).forEach(function(key) {
                    var key_label = key.split(',')
                    dim.push({
                        key : key_label[0],
                        label : key_label[1],
                        children : results[key]
                    })
                });

                dim =dim.sort(function(a, b){
                    if(a.label < b.label) return -1;
                    if(a.label > b.label) return 1;
                    return 0;
                });

                console.log("Dimenssions: ",dim)

                self.dimenssions[self.fields_view.arch.attrs.y_object]=dim;
                 self.load_scheduler();
                self.has_been_loaded.resolve();

            };

            self.fetch_data('res.users',['enterprise_id'],[['id', '=', self.userUid]],0,function (r) {

                    self.enterprise_id=r[0].enterprise_id[0];
                    console.log("RESULTS: ",self.enterprise_id);
                    self.fetch_data(self.fields_view.arch.attrs.y_model,['name','room_type_id','status','start_date','end_date'],[["enterprise_id", "=", self.enterprise_id]],0,sucess);

            });

            self.fetch_data('res.users',['enterprise_id'],[['id', '=', self.userUid]],0,function (r) {
                self.enterprise_id=r[0].enterprise_id[0];
                console.log("res.users RESULTS enterpr_id: ",self.enterprise_id);
                self.fetch_data('view.rooms.status',['room_id','name','room_type_id','status','unavailable_start_date','unavailable_end_date','stop_sale_start_date','stop_sale_end_date'],[["enterprise_id", "=", self.enterprise_id]],0,function (r) {
                    console.log("RESULT ROOMS STATUS 1: ",JSON.stringify(r));

                    var ss = r.reduce(function(acc, item) {

                        if(item.stop_sale_start_date){
                            var key = item.stop_sale_start_date+","+item.stop_sale_end_date;
                            acc[key] = acc[key] || [];
                            acc[key].push(item);
                        }
                      return acc;
                    }, {});
                    self.rooms_stop_sales=ss;

                    var blc = r.reduce(function(acc, item) {

                        if(item.unavailable_start_date && item.status=='Unvailable' ){
                            var key = item.unavailable_start_date+","+item.unavailable_end_date;
                            acc[key] = acc[key] || [];
                            acc[key].push(item);
                        }
                        return acc;
                    }, {});
                    self.rooms_blocked=blc;
                    // A $( document ).ready() block.
                    $( document ).ready(function() {
                       self.addMarker();
                    })

                });
            });


            //self.fetch_data(self.fields_view.arch.attrs.y_model,['name','room_type_id'],[["enterprise_id", "=", self.enterprise_id]],0,sucess);

            document.onkeydown = function(evt) {
                evt = evt || window.event;
                if (evt.keyCode == 27 && self.flag  ) {
                    self.ranged_search();
                }
            };
            return self._super();
        },
        // configure templates for dhtmlXGantt
        load_scheduler: function () {
            console.log("LOAD GANTT");
            var self = this;
            console.log("self.fields_view: ",self.fields_view);
            scheduler.clearAll();
            scheduler.config.xml_date="%Y-%m-%d %H:%i";
            scheduler.config.time_step = 60;
            scheduler.config.fix_tab_position = false;
            scheduler.xy.scale_height = 38;
            scheduler.config.limit_drag_out = true;
            scheduler.config.container_autoresize = true;
            scheduler.config.drag_resize= false;
            scheduler.config.drag_move = false;
            scheduler.config.lightbox.sections = [
                { name:"Contact details",   type:"textarea", map_to:"text",          height:42, focus:true },
                { name:"Note",              type:"textarea", map_to:"description",   height:63},
                { name:"Car Brand",         type:"select",   map_to:"car",           options:scheduler.serverList("currentCars")},
                { name:"Pick up location",  type:"textarea", map_to:"pick_location", height:30},
                { name:"Drop off location", type:"textarea", map_to:"drop_location", height:30},
                { name:"time",              type:"time",     map_to:"auto",          height:72}
            ];


            scheduler.locale.labels.new_event = "Nova Reserva";
            scheduler.locale.labels.dhx_cal_today_button = "HOJE";

            scheduler.locale.labels.week_timeline_tab = "WEEK";
            scheduler.locale.labels.two_week_timeline_tab = "2 WEEKS";
            scheduler.locale.labels.month_timeline_tab = "MONTH";
            scheduler.locale.labels.refresh_tab = "REFRESH";

            scheduler.createTimelineView({
                fit_events: true,
                name: "week_timeline",
                y_property: this.fields_view.arch.attrs.y_object,
                render: "tree",
                x_unit: "day",
                x_date: "%D %j",
                x_step: 1,
                x_size: 7,
                x_length: 7,
                dx: 75,
                dy: 30,
                event_dy: 32,
                section_autoheight: false,
                full_event__dy: true,
                y_unit: self.dimenssions[self.fields_view.arch.attrs.y_object]
            });

            scheduler.createTimelineView({
                fit_events: true,
                name: "two_week_timeline",
                y_property: this.fields_view.arch.attrs.y_object,
                render: "tree",
                x_unit: "day",
                x_date: "%D %j",
                x_step: 1,
                x_size: 14,
                x_length: 7,
                dx: 75,
                dy: 30,
                event_dy: 32,
                section_autoheight: false,
                full_event__dy: true,
                y_unit: self.dimenssions[self.fields_view.arch.attrs.y_object]
            });

            scheduler.createTimelineView({
                fit_events: true,
                name: "month_timeline",
                y_property: this.fields_view.arch.attrs.y_object,
                render: "tree",
                x_unit: "day",
                x_date: "%D %j",
                x_step: 1,
                x_size: 24,
                dx: 75,
                dy: 30,
                event_dy: 32,
                section_autoheight: false,
                full_event__dy: true,
                y_unit: self.dimenssions[self.fields_view.arch.attrs.y_object]
            });

            //console.log("Y_UNIT: ",self.dimenssions[self.fields_view.arch.attrs.y_object])
            console.log("Y_PROPERTY: ",this.fields_view.arch.attrs.y_object)
            scheduler.date.week_timeline_start = scheduler.date.two_week_timeline_start = scheduler.date.week_start;
            scheduler.date.month_timeline_start = scheduler.date.month_start;
            scheduler.date.add_month_timeline = function(date, inc){
                return scheduler.date.add(date, inc, "month");
            };



            var weekDateFormat = scheduler.date.date_to_str("%D %j");
            scheduler.templates.week_timeline_scale_date =
                scheduler.templates.two_week_timeline_scale_date = function(date){
                    return "<br/>" + weekDateFormat(date);
                };
            scheduler.templates.month_timeline_scale_date = function(date) {

                return self.getShortDayName(date) + "<br/>" + date.getDate();
            };

            scheduler.templates.week_timeline_scale_label =
                scheduler.templates.two_week_timeline_scale_label =
                    scheduler.templates.month_timeline_scale_label = function(key, label, section){

                    var cl =""
                    if(section.children){
                        cl='car_brand_root'
                    }
                        return "<div style=\"width:100%\">\

		  <div title='"+label+"' class='car_brand cut-text "+cl+"' >"+label+"</div></div>";
                    };

            scheduler.templates.week_timeline_cell_class =
                scheduler.templates.two_week_timeline_cell_class =
                    scheduler.templates.month_timeline_cell_class = function(evs, date, section) {

                        var day = date.getDay();
                        return day == 0 || day == 6 ? "dhx_cell_holiday" : "";
                    };

            scheduler.templates.tooltip_date_format = scheduler.date.date_to_str("%j %M %Y");

            scheduler.templates.tooltip_text = function (start, end, event) {
                var status = event.text  || null;
                var days=self.get_duration(moment(start), moment(end))
                var days_string=days >1 ? "Days" :"Day";
                return "Booked for " + days +" "+days_string+"<br/>" +
                    "<b>Status:</b> " + status + "<br/>" +
                    "<b>Check-in:</b> " + scheduler.templates.tooltip_date_format(start) + "<br/>" +
                    "<b>Check-out:</b> " + scheduler.templates.tooltip_date_format(end);

            };



            scheduler.templates.event_class = function (start, end, event) {
                if (event.text == "request") {
                    return "dhx_rent_request";
                }
                else if(event.text == "pending") {
                    return "dhx_rent_pending";
                }
                 else if(event.text == "confirmed") {
                    return "dhx_rent_confirmed";
                }
                 else if(event.text == "no_show") {
                    return "dhx_rent_no_show";
                }
                 else if(event.text == "cancelled") {
                    return "dhx_rent_cancelled";
                }
                 else if(event.text == "hosted") {
                    return "dhx_rent_hosted";
                }
                 else if(event.text == "checkout") {
                    return "dhx_rent_checkout";
                }

                return "";
            };

            scheduler.pickerDateFormat = "%d/%m/%Y";
            scheduler.currentCal = null;

            scheduler.showLightbox = function(id) {
                var ev = scheduler.getEvent(id);
                var end_date=ev.end_date;
                 console.log("DURATION: ",self.get_duration(ev.start_date,ev.end_date));
                if(!self.get_duration(ev.start_date,ev.end_date)){
                    console.log("DATES ARE EQUALS");
                    ev.end_date = new Date(moment(end_date).add(1, 'days'));
                }

                //if(!scheduler.checkCollision(ev)) return;

                 self.create_on_click(id);

            };

            const actual_date= self.focus_date.clone();

            scheduler.config.collision_limit = 1; //allows creating 1 event per time slot

            // Initialize the gantt chart
            scheduler.init(this.$el.find('.oe_calendar')[0],new Date(actual_date),self.scale);
            self.initLightboxBgCancel();
            //scheduler.detachAllEvents();

            scheduler.attachEvent("onBeforeViewChange", function(old_mode,old_date,mode,date) {
                if (mode == "month_timeline") {
                    var days = self.getMonthDays(date);
                    scheduler.matrix['month_timeline'].x_size = days;
                    scheduler.matrix['month_timeline'].x_length = days;

                }
                return true;
            });

            scheduler.attachEvent("onYScaleClick", function (index, section, e){
                console.log("onYScaleClick")
                console.log(index, section, e)
            });

            scheduler.attachEvent("onEventCollision", function (ev, evs) {
                console.log("COLISION");
              for (var i = 0; i < evs.length; i++) {
                if (ev[scheduler.matrix[self.scale].y_property] != evs[i][scheduler.matrix[self.scale].y_property]) continue;
                dhtmlx.message({
                  type: "error",
                  text: "This Room is already booked for this date."
                });
              }
              return true;
            });
            scheduler.attachEvent("onXLE", function (){
                console.log("onXLE");
                //document.getElementById("lightboxStatus").innerHTML = statusesHtml.join("<br>");

            });
            scheduler.attachEvent('onViewChange', this.proxy('view_changed'));

            this.refresh_scheduler();

            // Remove hard coded style attributes from dhtmlx scheduler
            this.$el.find(".dhx_cal_navline").removeAttr('style');


        },
        refresh_scheduler: function() {
            console.log("REFRESH SCHEDULER");
            scheduler.setCurrentView(scheduler._date);
        },

        destroy: function () {
        console.log("destroy");
            while (this.gantt_events.length)
                //gantt.detachEvent(this.gantt_events.pop());

                this._super.apply(this, arguments);
        },
        do_show: function () {
        console.log("do_show");
            this.do_push_state({});
            return this._super.apply(this, arguments);
        },
        fetch_data:function(model_name,fields,domain,limit,sucess){
            console.log("fetch_data");
            var self = this;
           var model = new Model(model_name);
            model.query(fields)
                 .filter(domain)
                 .limit(limit)
                 .all().then(sucess);
        },
        do_search: function (domains, contexts, group_bys) {
            console.log("do_search");
            var self = this;
            self.last_domains = domains;
            self.last_contexts = contexts;
            self.last_group_bys = group_bys;
            this.last_search = arguments;

            this.ranged_search();
        },
        ranged_search: function() {
            console.log("ranged_search");
            var self = this;
            scheduler.clearAll();

            var sucess=function (results) {
                var dim = []
                _.map(results, function(result) {
                    result['key'] = result['id'];
                    result['label'] = result[self.fields_view.arch.attrs.y_label]
                    delete result[self.fields_view.arch.attrs.y_label];
                    delete result['id'];
                    delete result['status'];
                   return result;
                });

                results = results.reduce(function(acc, item) {
                  var key = item.room_type_id;
                  delete item.room_type_id;
                  acc[key] = acc[key] || [];
                  acc[key].push(item);
                  return acc;
                }, {});

                Object.keys(results).forEach(function(key) {
                    var key_label = key.split(',')
                    dim.push({
                        key : key_label[0],
                        label : key_label[1],
                        children : results[key]
                    })
                });
                 dim =dim.sort(function(a, b){
                    if(a.label < b.label) return -1;
                    if(a.label > b.label) return 1;
                    return 0;
                });

                console.log("SORTED: ",dim)
                self.dimenssions[self.fields_view.arch.attrs.y_object]=dim;
                scheduler.matrix[self.scale].y_unit = self.dimenssions[self.fields_view.arch.attrs.y_object]
                console.log("OPEN SECTION: ",self.dimenssions[self.fields_view.arch.attrs.y_object][0].key)
            scheduler.openSection(self.dimenssions[self.fields_view.arch.attrs.y_object][0].key);
            };



            $.when(this.has_been_loaded, this.ready).done(function() {
                console.log("self.get_range_domain(): ",self.get_range_domain());
                console.log("self.last_search[1]: ",self.last_search[1]);
                console.log("self.fields: ",_.values(self.fields_view.arch.attrs));
                self.dataset.read_slice([], {
                    offset: 0,
                    domain: self.get_range_domain(),
                    context: [["enterprise_id", "=", self.enterprise_id]]
                }).done(function(events) {
                    console.log("EVENTS: ",events);
                    self.dataset_events = events;
                    self.fetch_data(self.fields_view.arch.attrs.y_model,['name','room_type_id','status'],[["enterprise_id", "=", self.enterprise_id]],0,sucess);


                    self.fetch_data('res.users',['enterprise_id'],[['id', '=', self.userUid]],0,function (r) {
                        self.enterprise_id=r[0].enterprise_id[0];
                        console.log("res.users RESULTS enterpr_id: ",self.enterprise_id);
                        self.fetch_data('view.rooms.status',['room_id','name','room_type_id','status','unavailable_start_date','unavailable_end_date','stop_sale_start_date','stop_sale_end_date'],[["enterprise_id", "=", self.enterprise_id]],0,function (r) {
                            console.log("RESULT ROOMS STATUS: ",r)

                            var ss = r.reduce(function(acc, item) {

                                if(item.stop_sale_start_date){
                                    var key = item.stop_sale_start_date+","+item.stop_sale_end_date;
                                    acc[key] = acc[key] || [];
                                    acc[key].push(item);
                                }
                              return acc;
                            }, {});
                            self.rooms_stop_sales=ss;

                            var blc = r.reduce(function(acc, item) {

                                if(item.unavailable_start_date && item.status=='Unvailable' ){
                                    var key = item.unavailable_start_date+","+item.unavailable_end_date;
                                    acc[key] = acc[key] || [];
                                    acc[key].push(item);
                                }
                                return acc;
                            }, {});
                            self.rooms_blocked=blc;
                            // A $( document ).ready() block.
                            $( document ).ready(function() {
                               self.addMarker();
                            })
                        });
                    });
                    self.events_loaded(events);
                });
            });
        },
        events_loaded: function(events, fn_filter, no_filter_reload) {
            console.log("events_loaded");
            var self = this;

            //To parse Events we have to convert date Format
            var res_events = [],
                sidebar_items = {};
            var selection_label = {};
            for (var e = 0; e < events.length; e++) {
                var evt = events[e];

                if (!evt[this.date_start]) {
                    break;
                }

                evt.color = "red";
                evt.textColor = '#000000';

                if (this.fields[this.date_start]['type'] == 'datetime') {
                    evt[this.date_start] =moment(evt[this.date_start]).hours(14).format('YYYY-MM-DD HH:mm:ss');
                }
                if (this.date_stop && evt[this.date_stop] && this.fields[this.date_stop]['type'] == 'datetime') {

                    evt[this.date_stop] =moment(evt[this.date_stop]).hours(12).format('YYYY-MM-DD HH:mm:ss');
                }

                res_events.push(this.convert_event(evt));
            }
            console.log("res_events: ",res_events);
            scheduler.parse(res_events, 'json');
            this.refresh_scheduler();
            if (!no_filter_reload && this.sidebar) {
                this.sidebar.filter.events_loaded(sidebar_items);
            }


            var date_moment=moment();
            console.log("LAST SEARCH: ",[self.scale, date_moment.format("YYYY-MM-DD"),self.range_start.format("YYYY-MM-DD"),self.range_stop.format("YYYY-MM-DD")])
            console.log("ROOMS STOP SALES: ",self.rooms_stop_sales)
            console.log("ROOMS BLOCKED: ",self.rooms_blocked)

        },
        addMarker: function(){
            const self = this;
            //alert("deleting markers in 653");
            scheduler.deleteMarkedTimespan()
            if(self.rooms_blocked){
                //alert("adding rooms blocked");
                Object.keys(self.rooms_blocked).forEach(function(key) {
                    var date_range = key.split(',')
                    console.log("DATE RANGE: ",date_range)
                    for (let i = 0; i < date_range.length; i++){
                        date_range[i] =moment(date_range[i])
                    }
                    //console.log("DATE RANGE NEW: ",date_range)
                    //console.log("DATES : ",self.rooms_blocked[key]);

                    date_range = self.dateRange([self.range_start,self.range_stop],date_range)
                    if(date_range){
                        var room_list = self.rooms_blocked[key].map(a => a.room_id[0]);
                        console.log("ROOMS IN RANGE: ",room_list)

                        var config ={
                            start_date: new Date(moment(date_range[0]).format('MM/DD/YYYY')),
                            end_date:   new Date(moment(date_range[1]).add(1, 'day').format('MM/DD/YYYY')),
                            zones: "fullday",
                            css:   "gray_section",
                            html:"<b>Blocked</b>",
                            type:  "dhx_time_block", //the hardcoded value
                            sections:{
                                "month_timeline":room_list,
                                'week_timeline':room_list,
                                'two_week_timeline':room_list
                            }
                        };
                        console.log("MARKER CONFIG BLOCKED: ",config);
                        //marks and blocks dates
                        scheduler.addMarkedTimespan(config);
                    }

                });
            }


            if(self.rooms_stop_sales){
                //alert("adding stop sale");
                Object.keys(self.rooms_stop_sales).forEach(function(key) {
                    var date_range = key.split(',')
                    //console.log("DATE RANGE: ",date_range)
                    for (let i = 0; i < date_range.length; i++){
                        date_range[i] =moment(date_range[i])
                    }
                    //console.log("DATE RANGE NEW: ",date_range)
                    //console.log("DATES : ",self.rooms_stop_sales[key]);

                    date_range = self.dateRange([self.range_start,self.range_stop],date_range)
                    //if(date_range){
                        var room_list = self.rooms_stop_sales[key].map(a => a.room_id[0]);
                        //console.log("ROOMS IN RANGE: ",room_list)
                        var config ={
                            start_date: new Date(moment(date_range[0]).format('MM/DD/YYYY')),
                            end_date:   new Date(moment(date_range[1]).add(1, 'day').format('MM/DD/YYYY')),
                            zones: "fullday",
                            css:   "gray_section",
                            html:"<b>Stop Sale</b>",
                            type:  "dhx_time_block", //the hardcoded value
                            sections:{
                                "month_timeline":room_list,
                                'week_timeline':room_list,
                                'two_week_timeline':room_list
                            }
                        };
                        console.log("MARKER CONFIG stop sales: ",JSON.stringify(config));
                        //marks and blocks dates
                        scheduler.addMarkedTimespan(config);
                  //  }

                });
            }

            if(self.dataset_events){
                 Object.keys(self.dataset_events).forEach(function(key) {
                        console.log("#########################")
                        console.log("ROOM: ",self.dataset_events[key].room_id);
                        console.log("Checkin: ",new Date(self.dataset_events[key].checkin));
                        console.log("Checkout: ",new Date(self.dataset_events[key].checkout));
                        console.log("#########################")

                        var config ={
                            start_date: new Date(self.dataset_events[key].checkin),
                            end_date:   new Date(new Date(self.dataset_events[key].checkout).setHours(14)),
                            zones: "fullday",
                            sections:{
                                "month_timeline":[self.dataset_events[key].room_id[0]],
                                'week_timeline':[self.dataset_events[key].room_id[0]],
                                'two_week_timeline':[self.dataset_events[key].room_id[0]]
                            }
                        };
                        scheduler.deleteMarkedTimespan(config);
                 });
            }

            if(self.flag){
                console.log("#################### UPDATE VIEW ###############")
                scheduler.updateView();
                console.log("dataset_events: ",self.dataset_events)
            }
            self.flag = true;
        },
        dateRange: function(search_date, between_date) {
            var return_dates=[]
            if((between_date[0] >= search_date[0] && between_date[0] <= search_date[1]) ||
               (search_date[0] >= between_date[0] && search_date[0] <= between_date[1])){

                if(between_date[0] < search_date[0]){
                    return_dates.push(search_date[0])
                }else{
                    return_dates.push(between_date[0])
                }

                if(between_date[1] > search_date[1]){
                    return_dates.push(search_date[1])
                } else{
                    return_dates.push(between_date[1])
                }

                return return_dates
            }

            return false
        },
        convert_event: function(evt) {
            console.log("convert_event");
            var date_start = evt[this.date_start],
                date_stop = this.date_stop ? evt[this.date_stop] : null,
                date_delay = evt[this.date_delay] || 1.0,
                res_text = '';

            if (this.info_fields) {
                res_text = _.map(this.info_fields, function(fld) {
                    if(evt[fld] instanceof Array)
                        return evt[fld][1];
                    return evt[fld];
                });
            }
           /* if (!date_stop && date_delay) {
                date_stop = date_start.clone().addHours(date_delay);
            }*/

            var r={
                'start_date': date_start,
                'end_date': date_stop,
                'text': evt.state,
                'id': evt.id
            };
            r[this.fields_view.arch.attrs.y_object]=evt[this.fields_view.arch.attrs.y_object][0];

            return r;
        },
        get_range_domain: function() {
            console.log("get_range_domain");
            var self = this;
            var domain = this.last_search[0].slice(0);
            console.log('this.last_search[0]: ',this.last_search[0]);
            domain.unshift([self.fields_view.arch.attrs.date_stop, '>=', this.range_start.clone().format("YYYY-MM-DD")]);
            domain.unshift([self.fields_view.arch.attrs.date_start, '<=', this.range_stop.clone().format("YYYY-MM-DD")]);
            console.log("DOMAINS: ",domain);
            return domain;
        },
        view_changed: function(mode, date) {
            console.log("view_changed");
            var self=this;
            self.scale=mode;
            var date_moment=moment(date);
                console.log("view_changed: ",[mode, date_moment.format("YYYY-MM-DD"),this.range_start.format("YYYY-MM-DD"),this.range_stop.format("YYYY-MM-DD")]);
            this.$el.find('.oe_calendar').removeClass('oe_cal_day oe_cal_week oe_cal_month').addClass('oe_cal_' + mode);
            if (!this.range(date_moment,this.range_start,this.range_stop)) {
                this.update_range_dates(date_moment);
                this.ranged_search();
            }
            this.has_been_loaded.resolve();

        },
        range:function(date,start_date,end_date){
            return date <= end_date && date >= start_date

        },
        update_range_dates: function(date) {
            console.log("update_range_dates");
            this.range_start = date.clone().startOf("month");
            this.range_stop = date.clone().endOf("month");

        },
        /**
         * Handler used when clicking on an empty cell. The behaviour is to create a new task
         * and apply some default values.
         */
        create_on_click: function (id) {
            console.log("create_on_click");
            var self = this;
            //var id = e.target.parentElement.attributes.task_id.value;
            var task = scheduler.getEvent(id);
            console.log("TASK: ",task);
            var update=false;
            var start_date = moment(task['start_date']).format('YYYY-MM-DD HH:mm:ss');

            var end_date = moment(task['end_date']).format('YYYY-MM-DD HH:mm:ss');
            /*switch (self.scale) {
                case "day":
                    end_date = start_date.clone().add(4, "hour");
                    break;
                case "week":
                    end_date = start_date.clone().add(2, "day");
                    break;
                case "month":
                    end_date = start_date.clone().add(4, "day");
                    break;
                case "year":
                    end_date = start_date.clone().add(2, "month");
                    break;
            }*/

            var create = {};
            var get_create = function (item) {
                if (item.create) {
                    create["default_"+item.create[0]] = item.create[1][0];
                }
                if (item.parent) {
                    var parent = gantt.getTask(item.parent);
                    get_create(parent);
                }
            };
                get_create(task);
            console.log("CREATE TASK :",create);
            create["default_"+self.fields_view.arch.attrs.date_start] = start_date;
            create["default_enterprise_id"] = self.enterprise_id;
            create["default_"+scheduler.matrix[self.scale].y_property] = task[scheduler.matrix[self.scale].y_property];
            if(self.fields_view.arch.attrs.date_stop) {
                create["default_"+self.fields_view.arch.attrs.date_stop] = end_date;
            } else { // We assume date_delay is given
                create["default_"+self.fields_view.arch.attrs.date_delay] = gantt.calculateDuration(start_date, end_date);
            }
            console.log("ALL EVENTS: ",self.dataset_events);
            console.log("DATASET: ",self.getItemById(self.dataset_events,id));
            var dataset_event=self.getItemById(self.dataset_events,id);
            var fields=['checkin',
                'checkout',
                'booking_date',
                'duration',
                'pricelist_item_id',
                'num_adults',
                'num_extra_bed',
                'num_children',
                'extra_beds_amount',
                'unitary_amount',
                'amount'
                ];
            if(dataset_event){
                for(var i=0;i<fields.length;i++){
                        if(dataset_event[fields[i]].constructor == Array){
                            dataset_event[fields[i]]=dataset_event[fields[i]][0]
                        }
                        create["default_"+fields[i]]=dataset_event[fields[i]]
                }
                self.on_task_update(id);

            }else{
                console.log("CREATE DEFAULT: ",create);
                self.on_task_create(id,create);
            }

        },

         /**
         * Dialog to create a task.
         */
        on_task_create: function (id,context) {
            console.log("on_task_create: ",id,context);
            this.new_event_id = id
            console.log("THIS: ",this)
            var self = this;
            this.scheduler_form = new form_common.FormViewDialog(self,{
                res_model: this.dataset.model,
                view_id: +this.open_popup_action,
                context: context,
                buttons: [{
                    text: _t("Save"), classes: "btn-primary", click: function() {
                        var sel = this;
                        sel.view_form.onchanges_mutex.def.then(function() {
                            if (!sel.view_form.warning_displayed) {
                                $.when(sel.view_form.save()).done(function() {
                                    console.log("DONE")
                                    sel.view_form.reload_mutex.exec(function() {
                                        sel.trigger('record_saved');
                                        sel.close();
                                        sel.view_form.on_button_save();
                                        console.log("ON TASK CREATE: ",id,context)
                                        scheduler.startLightbox(id, self.html("lightbox_form"));
                                        scheduler.endLightbox(false);
                                        self.reload();
                                    });
                                }).fail(function() {
                                    console.log("FAILS")
                                    scheduler.endLightbox(false);
                                    self.reload();
                                });
                            }
                        });
                    }
                },
                    {text: _lt("Close"), classes: 'btn-default', close: true,click: function(){
                        scheduler.endLightbox(false);
                        self.reload();
                    }}
                ]
            })

            this.scheduler_form.open();
            console.log("THIS FORM: ",this.scheduler_form)
            //scheduler.endLightbox(false);

            console.log("END TASK CREATE");

        },
        /**
         * Dialog to create a task.
         */
        on_task_update: function (id) {
            console.log("on_task_update");
            var self = this;
            this.scheduler_form = new form_common.FormViewDialog(self,{
                res_model: this.dataset.model,
                view_id: +this.open_popup_action,
                res_id:parseInt(id),
                buttons: [{
                    text: _t("Save"), classes: "btn-primary", click: function() {
                        var sel = this;
                        sel.view_form.on_button_edit();
                        sel.view_form.onchanges_mutex.def.then(function() {
                            if (!sel.view_form.warning_displayed) {
                                $.when(sel.view_form.save()).done(function() {
                                    console.log("DONE")
                                    sel.view_form.reload_mutex.exec(function() {
                                        sel.trigger('record_saved');
                                        sel.close();
                                        sel.view_form.on_button_save();
                                        console.log("ID ON UPDATE: ",id)
                                        scheduler.startLightbox(id, self.html("lightbox_form"));
                                        scheduler.endLightbox(false);
                                        self.reload();


                                    });
                                }).fail(function() {
                                    console.log("FAILS")
                                    scheduler.endLightbox(false);
                                     self.reload();
                                });
                            }
                        });
                    }
                },
                    {text: _lt("Close"), classes: 'btn-default', close: true,click: function(){

                        scheduler.endLightbox(false);
                         self.reload();
                    }}
                ]
            }).open();
            //scheduler.endLightbox(false);
            console.log("END TASK CREATE");
        },
        fetch_colors: function (tasks, group_bys) {
            console.log("fetch_colors: ",[tasks, group_bys])
            var self = this;
            if (self.type === 'gantt' || group_bys.length === 0) {

                return self.on_data_loaded(tasks, group_bys);
            }
            // Load the color for the group_bys
            // Prepare an object with the model in key, and an array of ids in value
            var model_ids = {};
            _.each(tasks, function (task) {
                _.each(group_bys, function (group) {
                    var model = self.fields[group].relation;
                    var id = task[group];
                    if (model && id){
                        if (!model_ids[model]) {
                            model_ids[model] = [];
                        }
                        model_ids[model].push(id[0]);
                    }
                });
            });
            // remove duplicate
            _.each(model_ids, function(ids, model){
                model_ids[model] = _.uniq(ids);
            });

            // Fetch the color for the specified ids in the specified model
            var color_by_group = {};
            var fetch = function (keys) {
                if (keys.length === 0) {
                    return self.on_data_loaded(tasks, group_bys, color_by_group);
                } else {
                    var key = _.first(keys);
                    if (!key) {
                        return fetch(_.rest(keys)); // not a relation field
                    }
                    new Model(key)
                        .query(["color"])
                        .filter([ ['id', 'in', model_ids[key]] ])
                        .all()
                        .then(function (colors) {
                            if (!color_by_group[key]) {
                                color_by_group[key] = {};
                            }
                            _.each(colors, function (color) {
                                color_by_group[key][color.id] = color.color;
                            });
                            return fetch(_.rest(keys));
                        });
                }
            };
            var keys = [];
            for(var k in model_ids) {
                keys.push(k);
            }
            fetch(keys);
        },

        getShortDayName: function(date) {
            console.log("getShortDayName");
            switch(date.getDay())
            {
                case 0:
                    return "Su";
                case 1:
                    return "Mo";
                case 2:
                    return "Tu";
                case 3:
                    return "We";
                case 4:
                    return "Th";
                case 5:
                    return "Fr";
                case 6:
                    return "Sa";
                default:
                    return "";
            }
        },

        get_formatted_duration:function (start, end) {
            console.log("get_formatted_duration");
            return moment.duration(end.diff(start)).asHours();

        },
        get_duration:function (start, end) {
            console.log("get_duration");
            return moment.duration(moment(end).hour(0).diff(moment(start).hour(0))).days();

        },


        show_minical:function(htmlElem, id) {
            console.log("show_minical");
            //if mini calendar already shown - destroy it
            if (scheduler.isCalendarVisible()){
                scheduler.destroyCalendar(null, true);
                if(scheduler.currentCal == htmlElem) return;
            }

            scheduler.currentCal = htmlElem;
            //create minicalendar
            scheduler.renderCalendar({
                position: htmlElem.id,
                date: scheduler._date,
                navigation: true,
                handler: function (date, calendar) {
                    //on click - put selected value to the input
                    document.getElementById(id).value = scheduler.date.date_to_str(scheduler.pickerDateFormat)(date);
                    //update sections
                    self.updateSections();
                    //and destroy calendar
                    scheduler.destroyCalendar();
                    //check if 'To' date is later than 'From' date
                    if (!areDatesCorrect()) {
                        showWarning();
                    }else{
                        self.updateTotalCost(html("lightboxEventId").value,getDate("lightboxPickUpDate"),getDate("lightboxDropOffDate"));
                    }
                }
            });

            function areDatesCorrect() {
                var from = document.getElementById("dateFrom").value,
                    to = document.getElementById("dateTo").value;

                if (from && to) {
                    //function to convert string to date object
                    var converter = scheduler.date.str_to_date(scheduler.pickerDateFormat);
                    from = converter(from);
                    to = converter(to);
                    if (from && to) {//if converted successfully
                        if (from.getTime() > to.getTime())
                        //return false only if start date is later than end date, other cases are valid
                            return false;
                    }
                }
                return true;
            }

            function showWarning() {
                document.getElementById("dateTo").value = "";
                dhtmlx.message("Check-in date must be before Check-out date!");
            }
        },

        getItem: function(array, key){
            console.log("getItem");
            for (var i = 0; i < array.length; i++) {
                if (key == array[i].key){
                    return array[i];
                }
            }
            return null;
        },

        getMonthDays:function(date){
            return parseInt(moment(date).endOf('month').format("DD"))
        },

        getItemById:function(array, id){
            for (var i = 0; i < array.length; i++) {
                if (id == array[i].id){
                    return array[i];
                }
            }
            return null;
        },

        getTotalCost:function(singleCost,repeats){
            return singleCost*repeats;
        },

        updateTotalCost: function(id,startDate,endDate){
           /* var event = scheduler.getEvent(id);
            //console.log("EVENT: ",event);
            var days=parseInt(get_formatted_duration(startDate,endDate));
            //console.log("DAYS: ",days);
            var car = self.getItemById(cars, event.car);
            //console.log("CAR: ",car);
            var totalCost=self.getTotalCost(car.price,days);
            //console.log("TOTAL COST: ",totalCost);
            //console.log('--------------------');
            html("lightboxTotalCost").value = totalCost+" ECV";*/

            return 1000;
        },

        convertToDateObj: function(date, time){
            var formatFunc = scheduler.date.str_to_date("%d/%m/%Y %H:%i"),
                targetDate = date /*+ " " + time*/,
                convertedDate = formatFunc(targetDate);

            return convertedDate;
        },

        filterByType: function(car, types){
            return !!types[car.type];
        },

        filterByPrice:function(car, prices){
            return prices.some(function(price){
                return +car.price >= price.minVal && +car.price < price.maxVal;
            });
        },

        filterByDate:function(car, dateFrom, dateTo){
            if(dateFrom){
                var evs = scheduler.getEvents();

                for (var i=0; i<evs.length; i++){
                    if(car.key == evs[i].car){
                        var evStart = (evs[i].start_date).getTime(),
                            evEnd = (evs[i].end_date).getTime(),
                            filterDateStart = dateFrom.getTime(),
                            filterDateEnd = dateTo.getTime();
                        if(( (evStart>=filterDateStart)&&(evEnd<=filterDateEnd) )||( (evStart<=filterDateStart)&&(evEnd>=filterDateEnd) )||( (evStart>=filterDateStart)&&(evEnd>=filterDateEnd && evStart<filterDateEnd) )||( (evEnd<=filterDateEnd)&&(evStart<=filterDateStart && evEnd>filterDateStart) ) )
                            return false;
                    }
                }
                return true;
            }

            return true;
        },

        getCheckedValues:function(boxId){
            return Array.prototype.slice
                .call(document.querySelectorAll("#" + boxId + " input[type=checkbox]:checked"))
                .map(function (box) {
                    return box.value;
                });
        },

        updateSections:function(){
             console.log("updateSections");
            scheduler.updateCollection("currentCars", cars.slice());

            var types = getCheckedValues("type-options")
                .reduce(function (hash, value) {
                    hash[value] = true;
                    return hash;
                }, {});

            var arrByType = cars.filter(function(car){
                return filterByType(car, types)
            });

            var selectedPrices = getCheckedValues("price-options")
                .map(function(value) {
                    return getItem(priceRanges, value);
                });

            var arrByPrice = arrByType.filter(function(car){
                return filterByPrice(car, selectedPrices);
            });

            var checkbox = document.getElementById("dateFilter");
            var newDate = document.getElementById("dateFrom").value;
            if(checkbox.checked && newDate){
                var formatFunc = scheduler.date.str_to_date("%d/%m/%Y");
                scheduler.setCurrentView(formatFunc(newDate));

                var dateFrom = document.getElementById("dateFrom").value,
                    /*timeFrom = getItem(hours, document.getElementById("timeFrom").value).label,*/
                    dateTo = document.getElementById("dateTo").value/*,
                     timeTo = getItem(hours, document.getElementById("timeTo").value).label*/;
                if(dateFrom){
                    var targetDateFrom = convertToDateObj(dateFrom, 0);
                    var targetDateTo = (!dateTo) ? (scheduler.date.add(targetDateFrom, 1, 'hour')) : convertToDateObj(dateTo, 0);
                }

                var arrByDate = arrByPrice.filter(function(car){
                    return filterByDate(car, targetDateFrom, targetDateTo)
                });

                scheduler.updateCollection("currentCars", arrByDate)
            } else {
                scheduler.updateCollection("currentCars", arrByPrice)
            }
        },

        pushSelectOptions:function(elementID, arr, formatter){
            console.log("pushSelectOptions");
            var select = document.getElementById(elementID);
            var selectHTML = [""];
            for(var i=0; i<arr.length; i++){
                var item = arr[i];
                selectHTML.push("<option value='"+item.key+"'>"
                    +(formatter ? formatter(item) : item.label)
                    +"</option>");
            }
            select.innerHTML = selectHTML.join("");
        },

        pushCheckboxes:function(root, options, formatter, name){
            console.log("pushSelectOptions");
            var select = document.getElementById(root);
            var html = [];
            for(var i = 0; i < options.length; i++){
                var item = options[i];

                html.push("<label>" +
                    "<div class='checkbox'>" +
                    "<input type='checkbox' name='"+name+"' value='"+item.key+"' onchange='self.updateSections()' checked>" +
                    "<span class='checkbox_marker'></span>" +
                    "</div>" +
                    "<span class='checkbox_text'>" +
                    (formatter ? formatter(item) : item.label) +
                    "</span>" +
                    "</label>");
            };
            select.innerHTML = html.join("<br>");
        },

        html:function(id) {
            console.log("html: ",id);
            return document.getElementById(id);
        },

        setRadio:function(containerId, value){
            var boxes = html(containerId).querySelectorAll("input[type=radio]");
            if(!value) {
                boxes[0].checked = true;
            }
            else {
                for(var i = 0; i < boxes.length; i++) {
                    if(boxes[i].value == value){
                        boxes[i].checked = true;
                        break;
                    }
                }
            }
        },

        getRadio:function(containerId) {
            var boxes = html(containerId).querySelectorAll("input[type=radio]");
            for(var i = 0; i < boxes.length; i++) {
                if(boxes[i].checked){
                    return boxes[i].value;
                }
            }
            return 0;
        },

        dateToLightboxStr : function(){return scheduler.date.date_to_str(scheduler.pickerDateFormat)},

        setDate:function(containerId, value) {
            var block = html(containerId);
            block.querySelector("input[type=text]").value = dateToLightboxStr(value);
            /*var hour = value.getHours() + 1;
             block.querySelector("select").value = hour;*/
        },

        getDate:function(containerId) {
            var block = html(containerId);
            var date = block.querySelector("input[type=text]").value;
            /*var time = getItem(hours, block.querySelector("select").value).label*/

            var result = convertToDateObj(date, 0);
            if(isNaN(+result)) return null;

            return result;
        },

        change_focus_date_left: function () {
            this.focus_date = this.focus_date.subtract(1, this.scale);
            this.display_focus_date();
            this.reload();
        },

        change_focus_date_right: function () {
            this.focus_date = this.focus_date.add(1, this.scale);
            this.display_focus_date();
            this.reload();
        },

        save_form:function() {
            console.log("save_form");
            var isError = false;

            var text = html("lightboxName").value.trim();
            if(!text) {
                dhtmlx.message("Enter correct Name", "error");
                isError = true;
            }

            var car = html("lightboxCar").value;

            var status = getRadio("lightboxStatus");
            if(!status) {
                dhtmlx.message("Enter correct Status", "error");
                isError = true;
            }

            var startDate = getDate("lightboxPickUpDate");
            if(!startDate){
                dhtmlx.message("Enter correct Check-in date", "error");
                isError = true;
            }

            var endDate = getDate("lightboxDropOffDate");
            if(!endDate){
                dhtmlx.message("Enter correct Check-ou date", "error");
                isError = true;
            }
            if(!isError && +endDate <= +startDate){
                dhtmlx.message("Check-out date should be higher than Check-in date", "error");
                isError = true;
            }

            if(!isError) {
                var ev = scheduler.getEvent(scheduler.getState().lightbox_id);
                if(!scheduler.checkCollision({
                        id: ev.id,
                        start_date: startDate,
                        end_date: endDate,
                        car: car
                    })) return;

                ev.text = text;
                ev.car = car;
                ev.status = status;
                ev.start_date = startDate;
                ev.end_date = endDate;

                ev.total_cost = updateTotalCost(ev.id,startDate,endDate);

                scheduler.endLightbox(false);
            }
        },

        close_form:function() {
            scheduler.endLightbox(false);
        },

        delete_event:function() {
            var event_id = scheduler.getState().lightbox_id;
            scheduler.endLightbox(false);
            scheduler.deleteEvent(event_id);
        },

        initLightboxBgCancel:function() {
            var self = this;

            dhtmlxEvent(document.body, "click", function (e) {
                console.log("BODY CLICK TARGET: ",e.target)
                console.log("BODY CLICK CLASSNAME: ",e.target.className)
                console.log("SCHEDULER GET STATE: ",scheduler.getState())

                if(document.getElementsByClassName('modal-dialog') && e.target.className == "close" || e.target.className == "modal in"){
                    if(self.scheduler_form){

                        self.scheduler_form.close();
                        console.log("CLOSE")
                        scheduler.startLightbox(self.new_event_id, self.html("lightbox_form"));
                        scheduler.endLightbox(false);
                        self.reload();
                    }
                }
                if(e.target.className =='refresh_tab'){
                    self.ranged_search();
                }
                /*if(e.target.className.includes("dhx_cal_event_line") && e.target.getAttribute("event_id")){
                   console.log("TARGET : ",e.target.getAttribute("event_id"));
                   self.create_on_click(e.target.getAttribute("event_id"));
                }*/

            });
        },

        display_focus_date: function () {
            // range date
            // Format to display it
            var date_display;
            switch(this.scale) {
                case "day":
                    date_display = this.focus_date.format("D MMM");
                    break;
                case "week":
                    var date_start = this.focus_date.clone().startOf("week").format("D MMM");
                    var date_end = this.focus_date.clone().endOf("week").format("D MMM");
                    date_display = date_start + " - " + date_end;
                    break;
                case "month":
                    date_display = this.focus_date.format("MMMM YYYY");
                    break;
                case "year":
                    date_display = this.focus_date.format("YYYY");
                    break;
            }
            this.set({'title': 'Booking Scheduler'});
        },

        change_scale_button: function (e) {
            this.scale = e.target.value;
            this.reload();
        },

        reload: function () {

                console.log("RELOAD: ",[this.last_domains, this.last_contexts, this.last_group_bys]);
               //location.reload();
                return this.do_search(this.last_domains, this.last_contexts, this.last_group_bys);

        },

        /**
         * Prepare the tasks and group by's to be handled by dhtmlxgantt and render
         * the view. This function also contains workaround to the fact that
         * the gantt view cannot be rendered in a documentFragment.
         */
        on_data_loaded: function (tasks, group_bys, color_by_group) {

            console.log("TASK: ",tasks);
            var self = this;

        },

        /**
         * Render the buttons according to the GanttView.buttons template and add listeners on it.
         * Set this.$buttons with the produced jQuery element
         * @param {jQuery} [$node] a jQuery node where the rendered buttons should be inserted
         * $node may be undefined, in which case they are inserted into this.options.$buttons
         */
        render_buttons: function($node) {
            console.log("render_buttons");
            var self = this;

        },
    });

    core.view_registry.add('gantt', SchedulerView);

    return SchedulerView;
});
