/**
 * 
 * All content on this website (including text, images, source
 * code and any other original works), unless otherwise noted,
 * is licensed under a Creative Commons License.
 * 
 * http://creativecommons.org/licenses/by-nc-sa/2.5/
 * 
 * Copyright (C) Open-Xchange Inc., 2006-2011
 * Mail: info@open-xchange.com 
 * 
 * @author Matthias Biggeleben <matthias.biggeleben@open-xchange.com>
 * 
 */

/*jslint bitwise: false, nomen: false, onevar: false, plusplus: false, regexp: false, white: true, browser: true, devel: true, evil: true, forin: true, undef: true, eqeqeq: true, immed: true */

/*global ox, jQuery, $, triggerEvent, menuswitchMailView */

ox.gui.initToolBarCalendar = function ($p) {
    
    /*
     * Meta data
     */
    var meta = $.extend(ox.widgets.toolBar.meta, {
       
        /*
         * Calendar
         */
        calendar: {
            "compose": {
                title: _("New appointment"),
                icons: ["mod_calendar.png"],
                big: true
            },
            "edit": {
                title: _("Edit"),
                icons: ["edit.png"],
                big: true,
                requires: ["one", "modify"]
            },
            "delete": {
                title: _("Delete"),
                icons: ["delete.png"],
                big: true,
                requires: ["some", "delete"]
            },
            "print": {
                title: _("Print"),
                icons: ["print.png"],
                big: true,
                requires: ["none"]
            },
            "move": {
                title: _("Move"),
                icons: ["calendar_move.png"],
                big: true,
                requires: ["some", "delete"]
            },
            "confirmation-change": {
                title: _("Confirmation"),
                icons: ["confirmation_change.png"],
                big: true,
                requires: function (ability, selection, cont) {
                    if (ability.some && !AcceptDeny.visible) {
                        var myself = ox.api.config.get("identifier");
                        var anyPrivate = false, allParticipant = true;
                        if ("title" in selection[0]) {
                            for (var i = 0; i < selection.length; i++) {
                                check(i, selection[i]);
                            }
                            done();
                        } else if (convertAppointmentArray != identity &&
                                   storageCache.current)
                        {
                            storageCache.current.newIterate(selection,
                                emptyFunction, check, done);
                        } else {
                            cont(false);
                        }
                    } else {
                        cont(false);
                    }
                    function check(n, item) {
                        item = convertAppointmentArray(item);
                        anyPrivate = anyPrivate || item.private_flag;
                        // loop over users and check if current user is listed
                        var users = item.users || item.participants;
                        var $l = users.length;
                        var participant = false;
                        for (var i = 0; i < $l; i++) {
                            if (users[i].id === myself) {
                                participant = true;
                            }
                        }
                        allParticipant = allParticipant && participant;
                    }
                    function done() { cont(!anyPrivate && allParticipant); }
                }
            },
            /*Attachments*/
            "attachment-open": {
                title: _("Open attachment"),
                icons: ["attachment_open.png"],
                selection: "attachments",
                requires: function(ability) {
                    return ability.one;
                }
            },
            "attachment-save": {
                title: _("Save as"),
                icons: ["send_as_attachment.png"],
                selection: "attachments",
                requires: function(ability) {
                    return ability.one;
                }
            },
            "attachment-save-infostore": {
                title: _("Save in InfoStore"),
                icons: ["save.png"],
                selection: "attachments",
                requires: function(ability) {
                    return ability.one;
                },
                mousedown: function (options, e) {
                    if (ox.api.config.get("modules.infostore.module") == false) {
                        corewindow.triggerEvent("Feature_Not_Available", 
                                "modules/calendar/save_to_infostore", window);
                    }
                }
            },
            
            /* Views */
            "calendar": {
                title: _("Calendar"),
                icons: ["mod_calendar.png"],
                big: true,
                behavior: "radio",
                group: "calendar-view-type",
                checked: function () {
                    return currentpath[1] === "calendar";
                }
            },
            "team": {
                title: _("Team"),
                icons: ["teamchange.png"],
                big: true,
                behavior: "radio",
                group: "calendar-view-type",
                requires: function (ability) {
                    return ox.api.config.get("modules.calendar.calendar_teamview"); 
                },
                checked: function () {
                    return currentpath[1] === "team";
                },
                mousedown: function (options, e) {
                    if (ox.api.config.get("modules.calendar.calendar_teamview") == false) {
                        corewindow.triggerEvent("Feature_Not_Available", 
                                "modules/calendar/team", window);
                    }
                }
            },
            "list": {
                title: _("List"),
                icons: ["list_view.png"],
                big: true,
                behavior: "radio",
                group: "calendar-view-type",
                checked: function () {
                    return currentpath[1] === "list";
                }
            },
            "detail": {
                title: _("Detail"),
                icons: ["detail_view.png"],
                big: true,
                requires: ["one"],
                behavior: "radio",
                group: "calendar-view-type",
                checked: function () {
                    return currentpath[1] === "detail";
                }
            },
            // Timeranges
            "day": {
                 title: _("Day"),
                 icons: ["dummy.gif"],
                 behavior: "radio",
                 group: "calendar-view-interval",
                 checked : function () {
                    return currentpath[2] === "day";
                }
            },
            "workweek": {
                 title: _("Work Week"),
                 icons: ["dummy.gif"],
                 behavior: "radio",
                 group: "calendar-view-interval",
                 checked : function () {
                     return currentpath[2] === "workweek";
                 }
            },
            "month": {
                 title: _("Month"),
                 icons: ["dummy.gif"],
                 behavior: "radio",
                 group: "calendar-view-interval",
                 checked : function () {
                     return currentpath[2] === "month";
                 }
            },
            "week": {
                title: _("Week"),
                icons: ["dummy.gif"],
                behavior: "radio",
                group: "calendar-view-interval",
                checked : function () {
                    return currentpath[2] === "week";
                }
            },
            "custom": {
                 title: _("Custom"),
                 icons: ["dummy.gif"],
                 behavior: "radio",
                 group: "calendar-view-interval",
                 checked : function () {
                     return currentpath[2] === "custom";
                 }
            },
            /* team members */
            "add": {
                 title: _("Add"),
                 icons: ["member_add.png"],
                 selection: "team-member",
                 requires: function (ability) {
                     // in teamview?
                     return currentpath[1] === "team";
                 }
                
            },
            "remove": {
                 title: _("Remove"),
                 icons: ["member_remove.png"],
                 selection: "team-member",
                 requires: function (ability) {
                    // teamview and "some" selection
                    return currentpath[1] === "team" && ability.some; 
                 }
                
            },
            "choose-team": {
                 title: _("Choose Team"),
                 icons: ["teamchange.png"],
                 selection: "team-member",
                 requires: function (ability) {
                        // teamview and teams exists
                        return currentpath[1] === "team" && 
                            (ox.api.config.get("gui.calendar.teams") || []).length > 0;
                     }
                
            },
            "create-team": {
                 title: _("Create Team"),
                 icons: ["teamchange.png"],
                 selection: "team-member",
                 requires: function (ability) {
                        // teamview and "some" selection
                        return currentpath[1] === "team"; 
                 }
                
            }
        },
        teams: {}
    });
    
    // toggles attachment section
    var toggleAttachmentSection = function () {
        if (currentpath[0] === "calendar") {
            // get parent tab
            var tab = ox.widgets.toolBar.tabs.calendarEdit;
            var section = tab.children[3];
            var visible = section.isVisible();
            // in team view?
            if (currentpath[2] === "attachment") {
                if (!visible) {
                    section.setVisible(true);
                    tab.validate();
                }
            } else if (visible) {
                section.setVisible(false);
                tab.validate();
            }
        }
    };
    
    // hide/show teamview section
    var toggleTeamviewSection = function () {
        if (currentpath[0] === "calendar") {
            // get parent tab
            var tab = ox.widgets.toolBar.tabs.calendarEdit;
            var section = tab.children[2];
            var visible = section.isVisible();
            // in team view?
            if (currentpath[1] === "team") {
                if (!visible) {
                    section.setVisible(true);
                    tab.validate();
                }
            } else if (visible) {
                section.setVisible(false);
                tab.validate();
            }
        }
    };
    
    // Add existing teams to metadata
    var addTeams = function () {
        var teams = ox.api.config.get("gui.calendar.teams"); 
        if (teams) {
            meta.teams = {};
            var teamItems = [];
            var i = 0, $l = teams.length;
            for (; i < $l; i++) {
                teamItems.push("team-#" + i);
                meta.teams["team-#" + i] = {
                    title: teams[i].name,
                    behavior: "radio",
                    group: "calendar-teamview-teams-internal"
                };
            }
            // add
            add(items["calendar-teamview-choose-team"], meta.teams, "calendar-teamview", teamItems);
        }
    };
    
    register("OX_Calendar_Teamlist_Changed", function () {
        // get menu item
        var item = ox.widgets.toolBar.menuItems["calendar-teamview-choose-team"];
        // remove children
        item.removeChildren();
        // add teams
        addTeams();
        // repaint
        item.validate();
    });

    /*
     * Add widgets
     */
    
    // vars
    var tabs = ox.widgets.toolBar.tabs;
    var sections = ox.widgets.toolBar.sections;
    var items = ox.widgets.toolBar.menuItems;
    var toolbar, tab, section;
    
    // fn
    var add = $p.add;
    
    // create toolbar instance
    toolbar = ox.widgets.toolBar.views.calendar = new ox.gui.TabMenu(
        $p.getOptions({
            id: "toolbar-calendar",
            showSectionNames: false
        })
    );
    
    // new
    tab = tabs.calendarCreate = new ox.gui.PanelMenu("toolbar-calendar-create",
        //#. '&' before a letter indicates a shortcut, i.e. Alt+N for '&New'
        _("&New")).addTo(toolbar);
    // section
    section = sections.calendarCreate = new ox.gui.PanelMenuSection(_("New"), "calendarCreateSection").addTo(tab);
    // add items
    add(section, meta.create, "calendar-create",
        ["mail", "calendar", "contact", "distributionlist", "task", "file"]
    );
    
    // edit
    tab = tabs.calendarEdit = new ox.gui.PanelMenu("toolbar-calendar-edit",
        //#. '&' before a letter indicates a shortcut, i.e. Alt+E for '&Edit'
        _("&Edit")).addTo(toolbar);
    // section "new"
    section = sections.calendarCompose = new ox.gui.PanelMenuSection(_("New"), "calendarComposeSection").addTo(tab);
    // add items
    add(section, meta.calendar, "calendar-edit",
        ["compose"]
    );
    // section "edit"
    section = sections.calendarEdit = new ox.gui.PanelMenuSection(_("Edit"), "calendarEditSections").addTo(tab);
    // add items
    add(section, meta.calendar, "calendar-edit",
        ["edit", "delete", "confirmation-change", "print", "move"]
    );
    
    // section teams
    section = sections.calendarTeam = new ox.gui.PanelMenuSection(_("Teams"), "calendarTeamSection").addTo(tab);
    // add items
    add(section, meta.calendar, "calendar-teamview",
        ["add","remove","choose-team","create-team"]
    );
    
    // section attachments only visible in detail view
    section = sections.calendarAttachment = new ox.gui.PanelMenuSection(_("Attachments"), "calendarAttachmentSections").addTo(tab);
    add(section, meta.calendar, "calendar-attachments",
            ["attachment-open","attachment-save","attachment-save-infostore"]);
            
    // add existing teams to chooseTeam
    addTeams();
    
    // views
    tab = tabs.calendarView = new ox.gui.PanelMenu("toolbar-calendar-view",
        //#. '&' before a letter indicates a shortcut, i.e. Alt+V for '&View'
        _("&View")).addTo(toolbar);
    
    // section View
    section = sections.calendarView = new ox.gui.PanelMenuSection(_("View"), "calendarViewSection").addTo(tab);
    // add items
    add(section, meta.calendar, "calendar-view",
        ["calendar", "team", "list", "detail"]
    );
    
    // section Interval
    section = sections.calendarInterval = new ox.gui.PanelMenuSection(_("Time Range"), "calendarIntervalSection").addTo(tab);
    // add items
    add(section, meta.calendar, "calendar-view-interval",
        ["day", "workweek", "month", "week", "custom"]
    );
    
    // Tagging (Flags & Categories)
    tab = tabs.calendarTagging = new ox.gui.PanelMenu("toolbar-calendar-tag",
        //#. '&' before a letter indicates a shortcut, i.e. Alt+F for '&Flags'
        _("&Flags")).addTo(toolbar);
    // section
    section = sections.calendarFlags = new ox.gui.PanelMenuSection(_("Flags"), "calendarFlagSection").addTo(tab);
    // add items
    add(section, meta.flags, "calendar-flag",
       ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
    );
    
    // Add section search when embbedded mode is on
    if (corewindow.embedded) {
        ox.widgets.searchField.calendar = new ox.gui.SearchField("ox-topbar-search-calendar").
        addListener("widget:search", function(e) {
            triggerEvent("OX_New_Search", ox.api.ui.getActiveModule(), e.data.value);
        });
        
        tab = tabs.calendarSearch = new ox.gui.PanelMenu("toolbar-calendar-search",
                _("&Search")).addTo(toolbar);
        // section
        section = sections.calendarSearch = new ox.gui.PanelMenuSection(_("Search"), "calendarSearchSection").addTo(tab);
        // add items
        section.add(ox.widgets.searchField.calendar);
    }
    
    
    /*
     * Add handler
     */
    
    // event hash
    var events = {
        "calendar-edit-compose": "OX_Before_Create_Calendar",
        "calendar-edit-delete": "OX_Calendar_Delete",
        "calendar-edit-edit": "OX_Calendar_Edit",
        "calendar-edit-print": "OX_Calendar_Print",
        "calendar-edit-move": "OX_Calendar_Move",
        "calendar-edit-print": "OX_Print",
        "calendar-attachments-attachment-save": "OX_Attachment_Save",
        "calendar-attachments-attachment-save-infostore": "OX_Attachment_SaveInfoStore"
        
    };
    
    // add handler function (must return true when action taken)
    ox.ToolBarController.addHandler(function (id, selections) {
        
        // confirmation change?
        if (id === "calendar-edit-confirmation-change") {
            // get current selection
            var selection = selections["default"];
            var tmp = [];
            if ("title" in selection[0]) {
                var i = 0, $l = selection.length;
                for (; i < $l; i++) {
                    tmp.push(new AcceptDenyObject("calendar", selection[i]));
                }
            } else {
                storageCache.current.newIterate(selection, emptyFunction,
                    function(n, item) {
                        tmp.push(new AcceptDenyObject("calendar",
                            convertAppointmentArray(item)));
                    });
            }
            // show dialog
            (new AcceptDeny(true)).showConfirmation(tmp);
        }
        
        // regex matches
        var m;

        // defined by event?
        if (events[id] !== undefined) {
            // trigger
            triggerEvent(events[id]);
            return true;
        }
        
        // is flag/mark?
        m = id.match(/^\w+-flag-(\d+)$/);
        if (m && m.length) {
            // trigger event
            triggerEvent("OX_Add_Flag", m[1]);
            return true;
        }
        
        // action for team selection
        var teamindex;
        if (id.match(/#[0-9]/)) {
            teamindex = id.substr( id.indexOf("#") + 1, id.length);
            var grid = getCalendarGrid("teamview");
            // delay for better gui responsiveness
            setTimeout(function() {
                 grid.loadTeamByIndex(teamindex);
            }, 10);
            return true;
        }
        
        switch (id) {
        case "calendar-view-calendar":
            menuswitchCalendarView('calendar');
            return true;
        case "calendar-view-list":
            menuswitchCalendarView('list');
            return true;
        case "calendar-view-team":
            menuswitchCalendarView('team');
            return true;
        case "calendar-view-detail":
            menuswitchCalendarView('detail');
            return true;
        case "calendar-view-interval-day":
            menuswitchCalendarTimerange('day');
            return true;
        case "calendar-view-interval-workweek":
            menuswitchCalendarTimerange('workweek');
            return true;
        case "calendar-view-interval-month":
            menuswitchCalendarTimerange('month');
            return true;
        case "calendar-view-interval-week":
            menuswitchCalendarTimerange('week');
            return true;
        case "calendar-view-interval-custom":
            menuswitchCalendarTimerange('custom');
            return true;
        case "calendar-teamview-add":
            triggerEvent('OX_Calendar_Teammember_Add');
            return true;
        case "calendar-teamview-remove":
            triggerEvent('OX_Calendar_Teammember_Remove');
            return true;
        case "calendar-teamview-create-team":
            triggerEvent('OX_Calendar_Team_Add_Team');
            triggerEvent('OX_Switch_View','configuration/calendar/teams');
            return true;
        case "calendar-attachments-attachment-open":
            triggerEvent(menunestedmessage ? "OX_Attachment_Open_Nested" : "OX_Attachment_Open");
            return true;
        
        }
       
    });
    
    // add to top-level element
    toolbar.addTo(ox.widgets.toolBar.viewControl);
    
    //Bind to team-member selection
    ox.api.event.register("SubSelected", function (selection) {
        ox.ToolBarController.processSelection("team-member", false, selection, true);
        if( currentpath[2] === "attachments") {
            ox.ToolBarController.processSelection("attachments", false, [selection], true);
        }
        
    });
    
    // hide and show teamview components
    // process selection for confirmation change
    ox.api.event.register("OX_View_Changed", function () {

        toggleTeamviewSection();
        toggleAttachmentSection();
        
        if (currentpath[0] === "calendar") {
            if (currentpath[1] !== "detail") {
                ox.ToolBarController.processSelection("default", false, [], true);
                ox.ToolBarController.processSelection("detailappointment", false, [], true);
            } else {
                ox.ToolBarController.processSelection("default", false, [selectedAppointment], true);
            }
            if (currentpath[2] !== "attachments") {
                ox.ToolBarController.processSelection("attachments", false, [], true);
            }
        }
    });
    
    ox.api.event.register("Confirmation_Changed", function(en) {
        ox.widgets.toolBar.menuItems["calendar-edit-confirmation-change"].
            setEnabled(Boolean(en));
    });
    
    // init
    ox.ToolBarController.processSelection("team-member", false, [], true);
    ox.ToolBarController.processSelection("detailappointment", false, [], true);
    ox.ToolBarController.processSelection("attachments", false, [], true);
    
    // "edit" tab is default
    ox.ToolBarController.setDefaultTab(toolbar, 1);
};