/*---------------------------------------------------------
 * OpenERP web_gantt
 *---------------------------------------------------------*/
openerp.web_gantt = function (openerp) {
QWeb.add_template('/web_gantt/static/src/xml/web_gantt.xml');
openerp.web.views.add('gantt', 'openerp.web_gantt.GanttView');
openerp.web_gantt.GanttView = openerp.web.View.extend({

init: function(parent, element_id, dataset, view_id) {
        this._super(parent, element_id);
        this.view_manager = parent || new openerp.web.NullViewManager();
        this.dataset = dataset;
        this.model = dataset.model;
        this.view_id = view_id;
        this.fields_views = {};
        this.widgets = {};
        this.widgets_counter = 0;
        this.fields = this.dataset.fields ? this.dataset.fields: {};
        this.ids = this.dataset.ids;
        this.name = "";
        this.date_start = "";
        this.date_delay = "";
        this.date_stop = "";
        this.color_field = "";
        this.colors = [];
        this.color_values = [];
        this.calendar_fields = {};
        this.info_fields = [];
        this.domain = this.dataset._domain ? this.dataset._domain: [];
        this.context = this.dataset.context || {};
    },

    start: function() {
        this.rpc("/web_gantt/ganttview/load",
        {"model": this.model, "view_id": this.view_id}, this.on_loaded);
    },

    on_loaded: function(data) {

        var self = this;
        this.fields_view = data.fields_view;

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

        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;

        this.color_field = this.fields_view.arch.attrs.color;
        this.day_length = this.fields_view.arch.attrs.day_length || 8;
        this.colors = this.fields_view.arch.attrs.colors;
        var arch_children = this.fields_view.arch.children[0];
        this.text = arch_children.children[0] ? arch_children.children[0].attrs.name : arch_children.attrs.name;
        this.parent = this.fields_view.arch.children[0].attrs.link;

        this.format = "yyyy-MM-dd";
        this.grp = [];

        self.create_gantt();
        self.get_events();

        this.$element.html(QWeb.render("GanttView", {"view": this, "fields_view": this.fields_view}));

    },

    create_gantt: function() {

        ganttChartControl = new GanttChart(this.day_length);
        ganttChartControl.setImagePath("/web_gantt/static/lib/dhtmlxGantt/codebase/imgs/");
        ganttChartControl.setEditable(true);
        ganttChartControl.showTreePanel(true);
        ganttChartControl.showContextMenu(true);
        ganttChartControl.showDescTask(true,'d,s-f');
        ganttChartControl.showDescProject(true,'n,d');

    },

    get_events: function() {

        var self = this;
        this.dataset.read_slice([],{}, function(result) {
            self.load_event(result);
        });

    },

    load_event: function(events) {

        var self = this;
        var result = events;
        var smalldate = "";

        COLOR_PALETTE = ['#ccccff', '#cc99ff', '#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'];

        if (result.length != 0){
            var show_event = [];
            for (var i in result){
                var res = result[i];
                if (res[this.date_start] != false){
                    
                    var start_date = this.convert_str_date(res[this.date_start]);
                    res[this.date_start] = start_date;
                    show_event.push(res);
                    if (smalldate == ""){
                        smalldate = start_date;
                    }
                    else{
                        if (start_date < smalldate){
                            smalldate = start_date;
                        }
                    }
                }
            }
            if (smalldate == ""){
                smalldate = Date.today();
            }
            project = new GanttProjectInfo("_1", "", smalldate);
            ganttChartControl.addProject(project);
        }

        //create child
        var k = 0;
        var color_box = {};
        var parents = {};
        var all_events = {};
        var child_event = {};
        var temp_id = "";
        var final_events = [];
        for (var i in show_event) {

            var res = show_event[i];

            var id = res['id'];
            var text = res[this.text];
            var start_date = res[this.date_start];

            var color = res[this.color_field][0] || res[this.color_field];
            if (color_box[color] == undefined){
                color_box[color] = COLOR_PALETTE[k];
                k += 1;
            }

            if (this.date_stop != undefined){
                if (res[this.date_stop] != false){
                    var stop_date = this.convert_str_date(res[this.date_stop]);
                    var duration= self.hours_between(start_date, stop_date);
                }
                else{
                    var duration = 0;
                }
            }
            else{
                var duration = res[this.date_delay];
            }
            if (!duration)
                duration = 0;

            if (self.grp.length){
                for (var j in self.grp){
                    var grp_key = res[self.grp[j]['group_by']];
                    if (typeof(grp_key) == "object"){
                        grp_key = res[self.grp[j]['group_by']][1];
                    }
                    else{
                        grp_key = res[self.grp[j]['group_by']];
                    }

                    if (!grp_key){
                        grp_key = "Undefined";
                    }

                    if (j == 0){
                        if (parents[grp_key] == undefined){
                            var mod_id = i+ "_" +j;
                            parents[grp_key] = mod_id;
                            child_event[mod_id] = {};
                            all_events[mod_id] = {'parent': "", 'evt':[mod_id , grp_key, start_date, start_date, 100, "", "white"]};
                        }
                        else{
                            mod_id = parents[grp_key];
                        }
                        temp_id = mod_id;
                    }else{
                        if (child_event[mod_id][grp_key] == undefined){
                            var ch_mod_id = i+ "_" +j;
                            child_event[mod_id][grp_key] = ch_mod_id;
                            child_event[ch_mod_id] = {};
                            temp_id = ch_mod_id;
                            all_events[ch_mod_id] = {'parent': mod_id, 'evt':[ch_mod_id , grp_key, start_date, start_date, 100, "","white"]};
                            mod_id = ch_mod_id;
                        }
                        else{
                            mod_id = child_event[mod_id][grp_key];
                            temp_id = mod_id;
                        }
                    }
                }
                all_events[id] = {'parent': temp_id, 'evt':[id , text, start_date, duration, 100, "", color_box[color]]};
                final_events.push(id);
            }
            else {
                if (i == 0) {
                    var mod_id = "_" + i;
                    all_events[mod_id] = {'parent': "", 'evt': [mod_id, this.name, start_date, start_date, 100, "", "white"]};
                }
                all_events[id] = {'parent': mod_id, 'evt':[id , text, start_date, duration, 100, "", color_box[color]]};
                final_events.push(id);
            }
        }

        for (var i in final_events){
            var evt_id = final_events[i];
            var evt_date = all_events[evt_id]['evt'][2];
            while (all_events[evt_id]['parent'] != "") {
               var parent_id =all_events[evt_id]['parent'];
               if (all_events[parent_id]['evt'][2] > evt_date){
                    all_events[parent_id]['evt'][2] = evt_date;
               }
               evt_id = parent_id;
            }
        }
        var evt_id = [];
        var evt_date = "";
        var evt_duration = "";
        var evt_end_date = "";

        for (var i in final_events){
            evt_id = final_events[i];
            evt_date = all_events[evt_id]['evt'][2];
            evt_duration = all_events[evt_id]['evt'][3];

            var evt_str_date = this.convert_date_str(evt_date);
            evt_end_date = this.end_date(evt_str_date, evt_duration);

            while (all_events[evt_id]['parent'] != "") {
               var parent_id =all_events[evt_id]['parent'];
               if (all_events[parent_id]['evt'][3] < evt_end_date){
                    all_events[parent_id]['evt'][3] = evt_end_date;
               }
               evt_id = parent_id;
            }
        }

        for (var j in self.grp) {
            self.render_events(all_events, j);
        }

        if (!self.grp.length) {
            self.render_events(all_events, 0);
        }

        for (var i in final_events){
            evt_id = final_events[i];
            res = all_events[evt_id];
            task=new GanttTaskInfo(res['evt'][0], res['evt'][1], res['evt'][2], res['evt'][3], res['evt'][4], "",res['evt'][6]);
            prt = project.getTaskById(res['parent']);
            prt.addChildTask(task);
        }

        var oth_hgt = 264;
        var min_hgt = 150;
        var name_min_wdt = 150;
        var gantt_hgt = jQuery(window).height() - oth_hgt;
        var search_wdt = jQuery("#oe_app_search").width();

        if (gantt_hgt > min_hgt){
            jQuery('#GanttDiv').height(gantt_hgt).width(search_wdt);
        } else{
            jQuery('#GanttDiv').height(min_hgt).width(search_wdt);
        }

        ganttChartControl.create("GanttDiv");
        ganttChartControl.attachEvent("onTaskStartDrag", function(task) {self.on_drag_start(task);});
        ganttChartControl.attachEvent("onTaskEndResize", function(task) {self.on_resize_drag_end(task, "resize");});
        ganttChartControl.attachEvent("onTaskEndDrag", function(task) {self.on_resize_drag_end(task, "drag");});
        ganttChartControl.attachEvent("onTaskDblClick", function(task) {self.open_popup(task);});

        var taskdiv = jQuery("div.taskPanel").parent();
        taskdiv.addClass('ganttTaskPanel');
        taskdiv.prev().addClass('ganttDayPanel');
        var $gantt_panel = jQuery(".ganttTaskPanel , .ganttDayPanel");

        var ganttrow = jQuery('.taskPanel').closest('tr');
        var gtd =  ganttrow.children(':first-child');
        gtd.children().addClass('task-name');

        jQuery(".toggle-sidebar").click(function(e) {
            self.set_width();
        });

        jQuery(window).bind('resize',function(){
            window.clearTimeout(ganttChartControl._resize_timer);
            ganttChartControl._resize_timer = window.setTimeout(function(){
                self.reload_gantt();
            }, 200);
        });

        jQuery("div #_1, div #_1 + div").hide();
    },

    set_width: function() {

        $gantt_panel.width(1);
        jQuery(".ganttTaskPanel").parent().width(1);

        var search_wdt = jQuery("#oe_app_search").width();
        var day_wdt = jQuery(".ganttDayPanel").children().children().width();
        jQuery('#GanttDiv').css('width','100%');

        if (search_wdt - day_wdt <= name_min_wdt){
            jQuery(".ganttTaskPanel").parent().width(search_wdt - name_min_wdt);
            jQuery(".ganttTaskPanel").width(search_wdt - name_min_wdt);
            jQuery(".ganttDayPanel").width(search_wdt - name_min_wdt - 14);
            jQuery('.task-name').width(name_min_wdt);
            jQuery('.task-name').children().width(name_min_wdt);
        }else{
            jQuery(".ganttTaskPanel").parent().width(day_wdt);
            jQuery(".ganttTaskPanel").width(day_wdt);
            jQuery(".taskPanel").width(day_wdt - 16);
            jQuery(".ganttDayPanel").width(day_wdt -16);
            jQuery('.task-name').width(search_wdt - day_wdt);
            jQuery('.task-name').children().width(search_wdt - day_wdt);
        }

    },

    end_date: function(dat, duration) {

         var self = this;

         var dat = this.convert_str_date(dat);

         var day = Math.floor(duration/self.day_length);
         var hrs = duration % self.day_length;

         dat.add(day).days();
         dat.add(hrs).hour();

         return dat;
    },

    hours_between: function(date1, date2, parent_task) {

        var ONE_DAY = 1000 * 60 * 60 * 24;
        var date1_ms = date1.getTime();
        var date2_ms = date2.getTime();
        var difference_ms = Math.abs(date1_ms - date2_ms);

        var d = parent_task? Math.ceil(difference_ms / ONE_DAY) : Math.floor(difference_ms / ONE_DAY);
        var h = (difference_ms % ONE_DAY)/(1000 * 60 * 60);
        var num = (d * this.day_length) + h;
        return parseFloat(num.toFixed(2));

    },

    render_events : function(all_events, j) {

        var self = this;
        for (var i in all_events){
            var res = all_events[i];
            if ((typeof(res['evt'][3])) == "object"){
                res['evt'][3] = self.hours_between(res['evt'][2],res['evt'][3], true);
            }

            k = res['evt'][0].toString().indexOf('_');

            if (k != -1) {
                if (res['evt'][0].substring(k) == "_"+j){
                    if (j == 0){
                        task = new GanttTaskInfo(res['evt'][0], res['evt'][1], res['evt'][2], res['evt'][3], res['evt'][4], "",res['evt'][6]);
                        project.addTask(task);
                    } else {
                        task = new GanttTaskInfo(res['evt'][0], res['evt'][1], res['evt'][2], res['evt'][3], res['evt'][4], "",res['evt'][6]);
                        prt = project.getTaskById(res['parent']);
                        prt.addChildTask(task);
                    }
                }
            }
        }
    },

    open_popup : function(task) {
        var event_id = task.getId();
        if(event_id.toString().search("_") != -1)
            return;
        if(event_id) event_id = parseInt(event_id, 10);

        var action = {
            "res_model": this.dataset.model,
            "res_id": event_id,
            "views":[[false,"form"]],
            "type":"ir.actions.act_window",
            "view_type":"form",
            "view_mode":"form"
        };

        action.flags = {
            search_view: false,
            sidebar : false,
            views_switcher : false,
            pager: false
        };
        var element_id = _.uniqueId("act_window_dialog");
        var dialog = jQuery('<div>', {
            'id': element_id
            }).dialog({
                modal: true,
                width: 'auto',
                height: 'auto',
                buttons: {
                    Cancel: function() {
                        $(this).dialog("destroy");
                    },
                    Save: function() {
                        var view_manager = action_manager.viewmanager;
                        var _dialog = this;
                        view_manager.views[view_manager.active_view].controller.do_save(function(r) {
                            $(_dialog).dialog("destroy");
                            self.reload_gantt();
                        })
                    }
                }
        });
        var action_manager = new openerp.web.ActionManager(this, element_id);
        action_manager.start();
        action_manager.do_action(action);

        //Default_get
        if(!event_id) action_manager.viewmanager.dataset.index = null;
    },

    on_drag_start : function(task){
        var st_date = task.getEST();
        if(st_date.getHours()){
            self.hh = st_date.getHours();
            self.mm = st_date.getMinutes();
        }
    },

    on_resize_drag_end : function(task, evt){

        var event_id = task.getId();
        var data = {};

        if(event_id.toString().search("_") != -1)
            return;
        if (evt == "drag"){
            full_date = task.getEST().set({hour: self.hh, minute : self.mm, second:0});
            data[this.date_start] = this.convert_date_str(full_date);
        }
        if (this.date_stop != undefined){
            tm = (task.getDuration() % this.day_length);
            stp = task.getFinishDate().add(tm).hour();
            data[this.date_stop] = this.convert_date_str(stp);
        }else{
            data[this.date_delay] = task.getDuration();
        }
        this.dataset.write(event_id, data, {}, function(result) {});

    },

    do_show: function () {
        this.$element.show();
    },

    do_hide: function () {
        this.$element.hide();
    },

    convert_str_date: function (str){
        if (str.length == 19){
            this.format = "yyyy-MM-dd HH:mm:ss";
            return openerp.web.str_to_datetime(str);
        } else if (str.length == 10){
            this.format = "yyyy-MM-dd";
            return openerp.web.str_to_date(str);
        } else if (str.length == 8){
            this.format = "HH:mm:ss";
            return openerp.web.str_to_time(str);
        }
        throw "Unrecognized date/time format";
    },

    convert_date_str: function(full_date) {
        if (this.format == "yyyy-MM-dd HH:mm:ss"){
            return openerp.web.datetime_to_str(full_date);
        } else if (this.format == "yyyy-MM-dd"){
            return openerp.web.date_to_str(full_date);
        } else if (this.format == "HH:mm:ss"){
            return openerp.web.time_to_str(full_date);
        }
        throw "Unrecognized date/time format";
    },

    reload_gantt: function() {
        var self = this;
        this.dataset.read_slice([],{}, function(response) {
            ganttChartControl.clearAll();
            jQuery("#GanttDiv").children().remove();
            self.load_event(response);
        });
    },

    do_search: function (domains, contexts, groupbys) {
        var self = this;
        this.grp = groupbys;
        return this.rpc('/web/session/eval_domain_and_context', {
            domains: domains,
            contexts: contexts,
            group_by_seq: groupbys
        }, function (results) {
            self.dataset.context = results.context;
            self.dataset.domain = results.domain;
            self.reload_gantt();
        });
    }

});

// here you may tweak globals object, if any, and play with on_* or do_* callbacks on them

};
// vim:et fdc=0 fdl=0:
