/**
 * 
 * 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) 2004-2010 Open-Xchange, Inc. Mail: info@open-xchange.com
 * 
 * @author Markus Wagner <markus.wagner@open-xchange.com>
 * @author Jan Finsel <jan.finsel@open-xchange.com>
 * @author Stefan Preuss <stefan.preuss@open-xchange.com>
 * 
 */

// global variable for the new appointment window
var newAppointment = {};

var json = new JSON();
var c = 0;
var session;
var showAsPopup;
var startTimePopup;
var endTimePopup;
var reminderPopup;
var startdate;
var enddate;
var treeLoaded = false;
var calenObj = {};
var clickedItem;
var ap_object;
var treeVisible = false;
var miniStartVisible = false;
var miniEndVisible = false;
var recurrencePosition;
var updateReminder = false;
var globalseries = null;
var newappTimestamp;
var messageCloseWindow = _("Do you really want to discard your changes and close the window?");
var avaliabityInitialLoaded = false;
var newAppointmentFolderTree = null;
var messageOnCancel = false;
var configContainsKey = corewindow.configContainsKey;
var configGetKey = corewindow.configGetKey;
var configSetKey = corewindow.configSetKey;
var savePending = false;
var folderOwner = null;
var data = {};
var externalParticipants = null;
var triggerReady = jQuery.noop;

// register("Loaded",initAppointment);

registerView("calendar_new", null, null, null, null);

// modal dialog
function setModalBusy(state) {
    if (state == true) {
        ox.api.setModal(true);
        jQuery("#modal-dialog-decorator").addClass("busy");
    } else {
        ox.api.setModal(false);
        jQuery("#modal-dialog-decorator").removeClass("busy");
    }
}

function setNumberOfAttNewApp(nNumOfAttParam) {
    if ($("app_number_of_attachments").firstChild.data)
        $("app_number_of_attachments").firstChild.data = nNumOfAttParam;
    else {
        removeChildNodes($("app_number_of_attachments"));
        $("app_number_of_attachments").appendChild(
                document.createTextNode(nNumOfAttParam));
    }
}

function setNumberOfParticipants(num) {
    if (newAppointment && newAppointment.participants) {
        num = newAppointment.participants.getParticipants().length;
    }
    $("countParticipantsNewAppointment").firstChild.data = num;
}

registerView(
        "calendar_new/appointment",
        function() {
            $("tab1").style.display = "block";
            $("panel1").className = "tabPanelFirstHi tabPanelHiColor background-color-content font-style-lable border-color-content-default";
        },
        function() {
            try {
                setTimeout(function() {
                    if ($("newappointment_description"))
                        $("newappointment_description").focus();
                }, 0);
            } catch (e) {
            }
        },
        null,
        function() {
            $("tab1").style.display = "none";
            $("panel1").className = "tabPanelFirst tabPanelColors font-color-disabled background-color-additional-content border-color-design font-weight-default";
        }, function() {
            try {
                setTimeout(function() {
                    if ($("newappointment_description"))
                        $("newappointment_description").focus();
                }, 0);
            } catch (e) {
            }
        });

var externalCounter = 0;

registerView(
        "calendar_new/participant",
        function() {
            $("tab2").style.display = "block";
            $("panel2").className = "tabPanelHi tabPanelHiColor background-color-content font-style-lable border-color-content-default";
        },
        function() {
            if (participantsLoaded) {
                newAppointment.participants.enableTheGrid();
                setNumberOfParticipants();
            }
            if (externalParticipants == null) {
                function on_ok(data) {
                    if (!participantsLoaded || !newAppointment.participants) {
                        return;
                    }
                    var extStorage = newAppointment.participants.participantsGridBig.storage;
                    for ( var i in data) {
                        var found = new Array();
                        for ( var j in extStorage.data.data) {
                            if (extStorage.data.data[j][5] === data[i].email) {
                                found.push(data[i].email);
                            }
                        }
                        if (found.length) {
                            newAlert(
                                    _("Info"),
                                    // #, c-format
                                    format(
                                            _("The following addresses are already on the list of participants and therefore not been added: %s"),
                                            found.join(",")));
                        } else {
                            extStorage.append( [ [
                                    "contact_ext_" + externalCounter++, 0,
                                    data[i].displayName, _("not sent"), "",
                                    data[i].email, "contact", null ] ]);
                        }
                    }
                }
                externalParticipants = new ParticipantsExternal(null, on_ok);
            }
        },
        function() {
            if (newAppointment.participants) {
                setNumberOfParticipants();
            }
            newAppointment.participants.disableTheGrid();
        },
        function() {
            $("tab2").style.display = "none";
            $("panel2").className = "tabPanel tabPanelColors font-color-disabled background-color-additional-content border-color-design font-weight-default";
        });
registerView(
        "calendar_new/attachment",
        function() {
            $("tab3").style.display = "block";
            $("panel3").className = "tabPanelHi tabPanelHiColor background-color-content font-style-lable border-color-content-default";
        },
        function() {
            register("OX_Attachments_Changed_InGrid", setNumberOfAttNewApp);
            if (!newAppointment.attachmentGridLoaded) {
                initAttachmentsGrid();
                newAppointment.attachmentGridLoaded = true;
                newAppointment.attachmentGrid.getAttachments();
            } else {
                newAppointment.attachmentGrid.enableGrid();
            }
        },
        function() {
            unregister("OX_Attachments_Changed_InGrid", setNumberOfAttNewApp);
            if (newAppointment.attachmentGridLoaded)
                newAppointment.attachmentGrid.disableGrid();
        },
        function() {
            $("tab3").style.display = "none";
            $("panel3").className = "tabPanel tabPanelColors font-color-disabled background-color-additional-content border-color-design font-weight-default";
        });

registerView(
        "calendar_new/availability",
        function() {
            resizeEvents.register("Resized", cnavail_resizeParticipantScroller);
            if (!avaliabityInitialLoaded) {
                if (newAppointment.participants == undefined) {
                    // Besitzer des Folders
                    if (!folderOwner) {
                        folderOwner = configGetKey("identifier");
                    }
                    newAppointment.participants = new Participants(
                            "participantsNewAppointment",
                            function(cb) {
                                $("countParticipantsNewAppointment").firstChild.data = newAppointment.participants
                                        .getParticipants().length;
                            }, true, true, true, true,
                            "Select Participants and Resources", folderOwner); /* i18n */
                    if (!calenObj.participants) {
                        calenObj.participants = new Array();
                    }
                    if (!calenObj.users) {
                        calenObj.users = new Array();
                    }
                    calenObj.participants.push( {
                        id : folderOwner,
                        type : 1
                    });
                    calenObj.users.push( {
                        id : folderOwner,
                        type : 1
                    });
                    initParticipantContent();
                    newAppointment.participants.initalFillBigGrid(calenObj);
                }
                initAvailability();
            }
            $("tab4").style.display = "block";
            $("panel4").className = "tabPanelHi tabPanelHiColor background-color-content font-style-lable border-color-content-default";
        },
        function() {
            startAvailability();
        },
        null,
        function() {
            resizeEvents.unregister("Resized",
                    cnavail_resizeParticipantScroller);
            $("tab4").style.display = "none";
            $("panel4").className = "tabPanel tabPanelColors font-color-disabled background-color-additional-content border-color-design font-weight-default";
        });

/**
 * ******************************** before on unload window
 * ****************************************************************
 */
function unloadMessage() {
    return messageCloseWindow;
}

function setBeforeUnload(on) {
    window.onbeforeunload = (on) ? unloadMessage : null;
    messageOnCancel = on;
}

// ausschalten
// window.onbeforeunload=null;
/**
 * ******************************** Ende before on unload
 * ****************************************************************
 */

function newAppointmentOnload() {

    // get passed data
    data = jQuery.extend((url || {}), ox.api.window.getData(url.guid));

    activemodule = "calendar_new";
    initContents("calendar_new");
    initAll();

    config = corewindow.config;
    var themeStyle = corewindow.oxThemeStyle || {
        name : "Default",
        path : "default"
    };
    removeCSSFilesForNewWindow(themeStyle.path);
    loadCSSFileForNewWindow("themes/" + themeStyle.path + "/css/popup.css");
    loadCSSFileForNewWindow("themes/" + themeStyle.path + "/css/calendar.css");

    window.setTimeout(function() {
        initAppointment();
    }, 0);
}

function openCategoriesDialog() {
    ox.categories.ui.open((calenObj.categories || ""), function(list, str) {
        calenObj.categories = str;
        ox.categories.ui.drawCategoriesList(ox.categories
                .getByString(calenObj.categories),
                $("newappointment_categories_list"));
    });
}

function initAppointment() {
    session = corewindow.session;

    internalCache = corewindow.internalCache;
    check0GroupDisplayName = corewindow.check0GroupDisplayName;
    register("OX_SAVE_OBJECT", writeNewAppointment);
    register("OX_Cancel_Object", closeNewAppointmentWindow);

    if (data["folder_id"]) {
        clickedItem = data["folder_id"];
    } else {
        clickedItem = configGetKey("folder.calendar");
    }

    createComboxes();

    // continue
    var cont = function() {

        if (newAppointment.participants == undefined) {
            // folder owner
            if (!folderOwner) {
                folderOwner = configGetKey("identifier");
            }
            newAppointment.participants = new Participants(
                    "participantsNewAppointment", setNumberOfParticipants,
                    true, true, true, true,
                    "Select Participants and Resources", folderOwner); /* i18n */
            initParticipantContent();
        }

        // init toolbar
        ox.gui.initToolBarNewWindowCalendar();
        
        // bind close button to "Window Close" events for intercom
        window.onunload = function() {
            ox.api.window.core.triggerEvent("OX_Window_Close", {
                handle : url.guid
            });
        };
        
        // triggerEvent "Window Ready" for intercom with special intercom Object
        // and whole window object
        triggerReady = function () {
            
            // special object for intercom lib
            var intercomWindowData = {
                handle : url.guid,
                type : "appointment",
                id : url.id ? url.id : null,
                folder_id : url.folder_id ? url.folder_id : null,
                title : window.document.title
            };
            
            ox.api.window.core.triggerEvent("OX_Window_Ready", intercomWindowData, window);
        };

        if (window.location.hash != "") {
            createSeriesView();
            fillFields();
        } else {
            triggerReady();
        }
        
        setTabLists(tabsList, panelsList, eventList);
        loadingComplete();

        function callMeOnOK(parameter) {
            newAppointment.attachmentGrid.updateGrid(parameter);
        }
        newAppointment.attachmentDialog = new attachmentDialog(0, callMeOnOK);
        $("mini_start_img").onkeydown = toggleMiniStartEnter;
        $("mini_end_id").onkeydown = toggleMiniEndEnter;

        setTimeout(function() {
            ox.api.folder.getPathString( {
                folder : clickedItem,
                success : function(str) {
                    cb_getpath(str);
                    triggerEvent("OX_Switch_View", 'calendar_new/appointment');
                }
            });
        }, 0);

        // just in case it's not set
        if (!calenObj.categories) {
            calenObj.categories = "";
        }

        // add click on categories button
        addDOMEvent($("newappointment_categories_button"), "click",
                function(e) {
                    openCategoriesDialog();
                });
        // handle dbl click which attachs an inplace input field to div
        addDOMEvent(
                $("newappointment_categories_list"),
                "dblclick",
                function(e) {
                    ox.categories.ui
                            .attachInplaceInput(
                                    $("newappointment_categories_list"),
                                    function(value) {
                                        // handle value
                                        var list = clone(ox.categories
                                                .getByString(
                                                        calenObj.categories,
                                                        ox.categories.match.ALL,
                                                        true));
                                        // add only if not empty!
                                        if (value
                                                && trimStr(value).length
                                                && !ox.categories.utils
                                                        .existsInObject(
                                                                trimStr(value),
                                                                list)) {
                                            var category = {
                                                name : value,
                                                color : 0
                                            };
                                            list.push(category);
                                            calenObj.categories = ox.categories.utils
                                                    .paramToString(list, "name");
                                        }
                                        ox.categories.ui
                                                .drawCategoriesList(
                                                        ox.categories
                                                                .getByString(calenObj.categories),
                                                        $("newappointment_categories_list"));
                                    });
                });
        
        triggerEvent("OX_menu_Change_Height", true);
    };

    // get folder owner
    folderOwner = configGetKey("identifier");

    // overwrite via url/data?
    if (data.folderowner !== undefined) {
        folderOwner = data.folderowner;
        cont();
    } else if (clickedItem) {
        // overwrite via selection?
        // get folder
        ox.api.folder
                .get( {
                    folder : clickedItem,
                    success : function(data) {
                        if (data.created_by
                                && ox.api.folder.is("private|shared", data)) {
                            folderOwner = data.created_by;
                        }
                        cont();
                    }
                });
    } else {
        cont();
    }
}

function createSeriesView() {
    function getSeriesString() {
        return calenObj && calenObj.recurrence_position ? _("Exception")
                : globalseries.getSeriesString();
    }
    globalseries = new SeriesView();

    globalseries.initView();

    addOnClose($('series_window'), function() {
        globalseries.hideView()
    });

    var s = getSeriesString();
    $("series_text").value = s;
    register("OX_Series_Data_Init", function() {
        var s = getSeriesString();
        $("series_text").value = s;
    });
    register("LanguageChanged", function() {
        var s = getSeriesString();
        $("series_text").value = s;
    });

    register("OX_Series_Data_Changed", function() {
        var s = globalseries.getSeriesString();
        $("series_text").value = s;
        var mydate = parseDateString($("newappointment_begins_date").value,
                "date");
        if (mydate == null) {
            $("newappointment_begins_date").value = formatDate(new Date(
                    globalseries.sequenceStart.selectedTime), "date");
            $("newappointment_ends_date").value = formatDate(new Date(
                    globalseries.sequenceStart.selectedTime), "date");
        }
        var tmpstart = parseDateString($("newappointment_begins_date").value,
                "date");
        var tmpend = parseDateString($("newappointment_ends_date").value,
                "date");
        if (tmpend == null) {
            tmpend = new Date(tmpstart.getTime());
        }
        var changes = globalseries.sequenceStart.selectedTime
                - tmpstart.getTime();
        tmpend.setTime(tmpend.getTime() + changes);
        $("newappointment_begins_date").value = formatDate(globalseries
                .getStartDate(), "date");
        $("newappointment_ends_date").value = formatDate(tmpend, "date");

    });
    if (calenObj)
        globalseries.setParameters(calenObj, data.modul == "new");
}

function showSeriesDialogue() {
    if (!calenObj || calenObj.recurrence_position)
        return;
    if (globalseries == null)
        createSeriesView();
    globalseries.showView('appointments', parseDateString(
            $('newappointment_begins_date').value, 'date'), parseDateString(
            $('newappointment_begins_date').value, 'date'));
}

function initAttachmentsGrid() {
    var nId = (data['modul'] && data['modul'] == "edit") ? data["id"] : false;
    // take the origin folder when editing an object as we may run in trouble if
    // the user
    // change the folder and goes to the attachment tab, see bug #11336
    var nFolder = calenObj && calenObj.folder_id ? calenObj.folder_id
            : clickedItem;
    newAppointment.attachmentGrid = new attachmentGrid("newappAttachmentGrid",
            nId, nFolder, 1, newAppointment.attachmentDialog);
}

function closeTimeout() {
    window.setTimeout(function() {
        ox.api.window.close(url.guid);
    }, 100);
}

function createMiniCalendar(startdate, enddate) {
    beginCalendar = new cMiniCalendar($("begin_header"), $("begin_container"),
            setStartDate, false, 'begin', $("begin_header_month"),
            $("begin_header_year"), null, startdate);

    endCalendar = new cMiniCalendar($("end_header"), $("end_container"),
            setEndDate, false, 'end', $("end_header_month"),
            $("end_header_year"), null, enddate);

    // createSequenceMiniCalendar();
}

function cb_getpath(sPath) {
    document.getElementsByName('newappointment_folder')[0].value = sPath;
}

function initTree() {
    var nPermission = 0;
    function fn_cb_perms_loaded(folder) {

        if (clickedItem === undefined || clickedItem !== folder.id) {
            return;
        }

        /*
         * if(folder.type != 1){
         * $("newappointment_personal_tr").style.visibility = "hidden"; } else {
         * $("newappointment_personal_tr").style.visibility = "visible"; }
         */
        ox.api.folder.getPathString( {
            folder : clickedItem,
            success : function(str) {
                cb_getpath(str);
                triggerEvent("OX_Switch_View", 'calendar_new/appointment');
            }
        });

        var folderViewSettingsNewAppointment = new Object();
        if (!treeLoaded) {
            // folder.popup
            // TODO: review

            ox.api.ui.selectFolder( {
                type: "calendar",
                id: "select-folder-popup-calendar",
                callback: folderAction,
                node: $('folder_tree_info')
            });

            treeLoaded = true;
        }
    }

    ox.api.folder.get( {
        folder : clickedItem,
        success : fn_cb_perms_loaded
    });
}

function folderAction (data) {
    // set new folder
    clickedItem = data.id;
    // toggle tree
    toggleTree();
    // get path
    ox.api.folder.getPathString( {
        folder : data.id,
        success : function(str) {
            // show path
            cb_getpath(str);
            triggerEvent("OX_Switch_View", 'calendar_new/appointment');
        }
    });
}

function toggleTree() {
    if (newAppointmentFolderTree == null) {
        initTree();
    }
    if (!treeVisible) {
        centerPopupWindow($("TreeDialogNewAppointment"));
        $("TreeDialogNewAppointment").style.display = "block";
        $("TreeDialogNewAppointment").style.top = "120px";
        $("TreeDialogNewAppointment").style.left = "170px";
        treeVisible = true;
    } else {
        $("TreeDialogNewAppointment").style.display = "none";
        treeVisible = false;
    }
}

function changeTimeDayView(type) {
    var date;
    var combobox;
    if (type == "end") {
        combobox = endTimePopup;
        date = parseDateString(
                $("newAppointmentForm").newappointment_ends_time_text.value,
                "time");
        if (date) {
            var tmp1 = formatDate(date, "time");
            $("newAppointmentForm").newappointment_ends_time_text.value = tmp1;
            combobox.setKey(-1, true);
            combobox.setKey(tmp1, true);
        }
        nappointment_checkDate('end');
    }
    if (type == "start") {
        combobox = startTimePopup;
        date = parseDateString(
                $("newAppointmentForm").newappointment_begins_time_text.value,
                "time");
        if (date) {
            var tmp1 = formatDate(date, "time");
            $("newAppointmentForm").newappointment_begins_time_text.value = tmp1;
            combobox.setKey(-1, true);
            combobox.setKey(tmp1, true);
        }
        nappointment_checkDate('start');
    }
}
function setStartDate() {
    beginCalendar.setSelected(this.id);
    setStartDate2();
}

function setStartDate2() {
    $("newAppointmentForm").newappointment_begins_date.value = formatDate(
            new Date(Date.UTC(beginCalendar.selectedYear,
                    beginCalendar.selectedMonth, beginCalendar.selectedDate, 0,
                    0, 0)), "date");
    $("mini_start").style.display = "none";
    miniStartVisible = false;
    nappointment_checkDate("start");
}

function setEndDate() {
    endCalendar.setSelected(this.id);
    setEndDate2();
}

function setEndDate2() {
    $("newAppointmentForm").newappointment_ends_date.value = formatDate(
            new Date(Date.UTC(endCalendar.selectedYear,
                    endCalendar.selectedMonth, endCalendar.selectedDate, 0, 0,
                    0)), "date");
    $("mini_end").style.display = "none";
    miniEndVisible = false;
    nappointment_checkDate("end");
}

function setStartDateManual() {
    var tmp = parseDateString(
            $("newAppointmentForm").newappointment_begins_date.value, "date");
    beginCalendar.setSelectedByDate(tmp.getUTCFullYear(), tmp.getUTCMonth(),
            tmp.getUTCDate());
}

function setEndDateManual() {
    var tmp = parseDateString(
            $("newAppointmentForm").newappointment_ends_date.value, "date");
    endCalendar.setSelectedByDate(tmp.getUTCFullYear(), tmp.getUTCMonth(), tmp
            .getUTCDate());
}

function showMiniStart() {
    var startdate = parseDateString(
            $("newAppointmentForm").newappointment_begins_date.value, "date");
    var enddate = parseDateString(
            $("newAppointmentForm").newappointment_ends_date.value, "date");

    beginCalendar.setSelectedByDate(startdate.getUTCFullYear(), startdate
            .getUTCMonth(), startdate.getUTCDate());
    endCalendar.setSelectedByDate(enddate.getUTCFullYear(), enddate
            .getUTCMonth(), enddate.getUTCDate());
    var tmp = $("mini_start");
    $("mini_end").style.display = "none";
    tmp.style.display = "block";
    tmp.style.left = 210 + "px";
    tmp.style.top = 120 + "px";
    tmp.style.height = 210 + "px";
    tmp.style.zIndex = "3";
}

function showMiniEnd() {
    var startdate = parseDateString(
            $("newAppointmentForm").newappointment_begins_date.value, "date");
    var enddate = parseDateString(
            $("newAppointmentForm").newappointment_ends_date.value, "date");

    beginCalendar.setSelectedByDate(startdate.getUTCFullYear(), startdate
            .getUTCMonth(), startdate.getUTCDate());
    endCalendar.setSelectedByDate(enddate.getUTCFullYear(), enddate
            .getUTCMonth(), enddate.getUTCDate());
    var tmp = $("mini_end");
    $("mini_start").style.display = "none";
    tmp.style.display = "block";
    tmp.style.left = 210 + "px";
    tmp.style.top = 150 + "px";
    tmp.style.height = 210 + "px"
    tmp.style.zIndex = "3";
}

function closeMiniStart() {
    $("mini_start").style.display = "none";
}

function closeMiniEnd() {
    $("mini_end").style.display = "none";
}

function toggleMiniStartEnter(event) {
    if (!event)
        event = window.event;
    if (event.which && event.which == 13)
        toggleMiniStart();
    else if (event.keyCode && event.keyCode == 13)
        toggleMiniStart();
};
var old_startdate;
function nappointment_checkDate(type) {
    var mystartdate = parseDateString($("newappointment_begins_date").value,
            "date");
    var mystarttime = parseDateString(
            $("newappointment_begins_time_text").value, "time");
    var mystart;
    if (mystartdate && mystarttime) {
        mystart = new Date(mystartdate.getTime() + mystarttime.getTime())
    } else
        return;
    var myenddate = parseDateString($("newappointment_ends_date").value, "date");
    var myendtime = parseDateString($("newappointment_ends_time_text").value,
            "time");
    var myend;
    if (myenddate && myendtime) {
        myend = new Date(myenddate.getTime() + myendtime.getTime())
    } else
        return;
    if (type == "start") {
        if (old_startdate || old_startdate == 0) {
            if (mystart) {
                if (myend) {
                    if (mystart.getTime() != old_startdate) {
                        myend = new Date(myend.getTime() - old_startdate
                                + mystart.getTime());
                    }
                }
            }
        } else {
            if (mystart) {
                if (myend) {
                    if (mystart.getTime() > myend.getTime()) {
                        myend = new Date(mystart.getTime() + (1000 * 60 * 60));
                    }
                }
            }
        }
    }
    if (type == "end") {
        if (myend) {
            if (mystart) {
                if (myend.getTime() < mystart.getTime()) {
                    mystart = new Date(myend.getTime() - (1000 * 60 * 60));
                }
            }
        }
    }
    if (mystart) {
        $("newappointment_begins_date").value = formatDate(mystart, "date");
        beginCalendar.setSelectedByDate(mystart.getUTCFullYear(), mystart
                .getUTCMonth(), mystart.getUTCDate());
        $("newappointment_begins_time_text").value = formatDate(mystart, "time");
        startTimePopup.setKey(-1, true);
        startTimePopup.setKey(formatDate(mystart, "time"), true);
    }
    if (myend) {
        $("newappointment_ends_date").value = formatDate(myend, "date");
        endCalendar.setSelectedByDate(myend.getUTCFullYear(), myend
                .getUTCMonth(), myend.getUTCDate());
        $("newappointment_ends_time_text").value = formatDate(myend, "time");
        endTimePopup.setKey(-1, true);
        endTimePopup.setKey(formatDate(myend, "time"), true);
    }
    old_startdate = mystart.getTime();
}
function toggleMiniStart() {
    if (!miniStartVisible) {
        var startdate = parseDateString(
                $("newAppointmentForm").newappointment_begins_date.value,
                "date");
        var enddate = parseDateString(
                $("newAppointmentForm").newappointment_ends_date.value, "date");
        if (startdate) {
            beginCalendar.setSelectedByDate(startdate.getUTCFullYear(),
                    startdate.getUTCMonth(), startdate.getUTCDate());
        }
        if (enddate) {
            endCalendar.setSelectedByDate(enddate.getUTCFullYear(), enddate
                    .getUTCMonth(), enddate.getUTCDate());
        }
        var tmp = $("mini_start");
        $("mini_end").style.display = "none";
        tmp.style.display = "block";
        tmp.style.position = "absolute";
        tmp.style.left = 210 + "px";
        tmp.style.top = 120 + "px";
        tmp.style.height = 210 + "px";
        tmp.style.zIndex = "3";
        miniStartVisible = true;
    } else {
        $("mini_start").style.display = "none";
        miniStartVisible = false;
    }
}

function toggleMiniEndEnter(event) {
    if (!event)
        event = window.event;
    if (event.which && event.which == 13)
        toggleMiniEnd();
    else if (event.keyCode && event.keyCode == 13)
        toggleMiniEnd();
};

function toggleMiniEnd() {
    if (!miniEndVisible) {
        var startdate = parseDateString(
                $("newAppointmentForm").newappointment_begins_date.value,
                "date");
        var enddate = parseDateString(
                $("newAppointmentForm").newappointment_ends_date.value, "date");
        if (startdate) {
            beginCalendar.setSelectedByDate(startdate.getUTCFullYear(),
                    startdate.getUTCMonth(), startdate.getUTCDate());
        }
        if (enddate) {
            endCalendar.setSelectedByDate(enddate.getUTCFullYear(), enddate
                    .getUTCMonth(), enddate.getUTCDate());
        }
        var tmp = $("mini_end");
        $("mini_start").style.display = "none";
        tmp.style.display = "block";
        tmp.style.position = "absolute";
        tmp.style.left = 210 + "px";
        tmp.style.top = 150 + "px";
        tmp.style.height = 210 + "px"
        tmp.style.zIndex = "3";
        miniEndVisible = true;
    } else {
        $("mini_end").style.display = "none";
        miniEndVisible = false;
    }
}
function fillFields() {
    if (!data.module) {
        data.module = "new";
    }

    if (data['modul'] == "edit") {
        if (data["id"].indexOf("_") != -1) {
            data["id"] = data["id"].substring(0, data["id"].indexOf("_"));
        }
        var uri;
        if (data["recurrence_position"] && data["recurrence_position"] > 0) {
            uri = AjaxRoot + "/calendar?action=get&session=" + session + "&id="
                    + data["id"] + "&folder=" + data["folder_id"]
                    + "&recurrence_position=" + data["recurrence_position"];
        } else {
            uri = AjaxRoot + "/calendar?action=get&session=" + session + "&id="
                    + data["id"] + "&folder=" + data["folder_id"]
        }
        if (data["singleappointment"] && data["singleappointment"] == "yes") {
            $("newappointment_categories_tr").style.display = "none";
        }
        // get appointment data
        json.get(uri, null, function(response) {
            if (response && response.data) {
                newappTimestamp = response.timestamp;
                setFields(response.data);
                triggerReady();
            }
        });
        
    } else if (data['modul'] == "new") {

        if (!calenObj.participants) {
            calenObj.participants = new Array();
        }
        if (!calenObj.users) {
            calenObj.users = new Array();
        }
        if (!calenObj.confirmations) {
            calenObj.confirmations = new Array();
        }

        var _isPub = configGetKey("gui.calendar.autoadd_participant_public");
        var _tmpF = ox.api.folder.get( {
            folder : clickedItem
        }); // use return value
        if (_isPub == undefined || _isPub
                || (!_isPub && _tmpF && _tmpF.type != 2)) {
            calenObj.participants.push( {
                id : folderOwner,
                type : 1
            });
            calenObj.users.push( {
                id : folderOwner,
                type : 1
            });
        }

        var extPart = {};
        // use clone to clean up the data provided by the core window
        var oFromMail = data.oFromMail = clone(data.oFromMail, corewindow);
        var sFromModule = data.sFromModule = clone(data.sFromModule, corewindow);
        // adding mail information
        if (oFromMail != undefined && sFromModule == "mail") {
            data['title'] = oFromMail[0].subject;
            data["note"] = "", addresses = {
                "from" : _("From:"),
                "to" : _("To:"),
                "cc" : _("Cc:")
            };
            for ( var i = 0; i < oFromMail.length; i++) {
                var msg = oFromMail[i];
                data["note"] += "---------- " + _("Original Message")
                        + " ----------\n";
                for ( var i in addresses) {
                    if (msg[i]) {
                        data["note"] += addresses[i] + " ";
                        for ( var ia = 0; ia < msg[i].length; ia++) {
                            extPart[msg[i][ia][1]] = msg[i][ia][0]
                                    || msg[i][ia][1];
                            data["note"] += msg[i][ia][1];
                            if (ia < msg[i].length - 1)
                                data["note"] += ", ";
                        }
                        data["note"] += "\n";
                    }
                }
                if (msg.received_date) {
                    data["note"] += _("Received:") + " "
                            + formatDate(msg.received_date, "datetime") + "\n";
                }
                if (msg.subject) {
                    data["note"] += _("Subject:") + " " + msg.subject + "\n";
                }
                data["note"] += "\n";
                if (msg.attachments_plain && msg.attachments_plain.length) {
                    data["note"] += msg.attachments_plain[0].content.replace(
                            /<br?(.\/)>/gi, "\n");
                }
                if (i < oFromMail.length - 1)
                    data["note"] += "\n\n";
            }

            // try to filter html parts out of mail text
            var node = newnode("div");
            node.innerHTML = data["note"];
            if (node.innerText) {
                // IE needs <br>'s to show valid line breaks
                data["note"] = data["note"].replace(/\n/g, "<br/>\n");
                node.innerHTML = data["note"];
                data["note"] = node.innerText;
            } else if (node.textContent) {
                // every other brother :)
                data["note"] = node.textContent;
            }
            node = null;
        }

        // adding participants
        if (oFromMail && sFromModule == "contacts") {
            for ( var i = 0; i < oFromMail.length; i++) {
                if (oFromMail[i][1] == 6 || oFromMail[i][7] != undefined) {
                    // these are internal users
                    calenObj['participants'].push( {
                        id : oFromMail[i][4],
                        type : oFromMail[i][7] || 1
                    });
                    calenObj['users'].push( {
                        id : oFromMail[i][4],
                        type : oFromMail[i][7] || 1
                    });
                } else {
                    // external users
                    extPart[oFromMail[i][3]] = oFromMail[i][2];
                }
            }
        }
        for ( var ib in extPart) {
            calenObj['participants'].push( {
                display_name : extPart[ib],
                mail : ib,
                type : 5
            });
            calenObj['confirmations'].push( {
                display_name : extPart[ib],
                mail : ib,
                type : 5,
                status : 0,
                message : ""
            });
        }
        if (oFromMail && sFromModule == "calendar") {
            function copy(array) {
                if (oFromMail[array]) {
                    for ( var i = 0; i < oFromMail[array].length; i++) {
                        calenObj[array].push(oFromMail[array][i]);
                    }
                }
            }
            copy("participants");
            copy("users");
            copy("confirmations");
            setFields(oFromMail);
        } else {
            setFields(data);
        }
        
        triggerReady();
    }
}

var setDisabled = classNameSetter("font-color-disabled");

/*
 * Callbackfunctions for Reminder popup
 */

function setTitle (title) {
    title = title || "";
    $("newappointment_description").value = title;
    document.title = (url.modul === "new" ? _("New Appointment") : _("Edit Appointment")) + (title !== "" ? ": " + title : "");
};

function setFields(object) {
    for ( var i in object) {
        if (!calenObj[i])
            calenObj[i] = object[i];
    }
    function fillFieldsPrivate() {
        startTimePopup.setKey(-1, true);
        startTimePopup.setKey(formatDate(startdate, "time"), true);
        endTimePopup.setKey(-1, true);
        endTimePopup.setKey(formatDate(enddate, "time"), true);
        $("newAppointmentForm").newappointment_begins_time_text.value = formatDate(
                startdate, "time");
        $("newAppointmentForm").newappointment_ends_time_text.value = formatDate(
                enddate, "time");
        createMiniCalendar(startdate, enddate);
        // beginCalendar.setSelectedByDate(startdate.getUTCFullYear(),
        // startdate.getUTCMonth(), startdate.getUTCDate());
        // endCalendar.setSelectedByDate(enddate.getUTCFullYear(),
        // enddate.getUTCMonth(), enddate.getUTCDate());

        $("newAppointmentForm").newappointment_begins_date.value = formatDate(
                new Date(Date.UTC(beginCalendar.selectedYear,
                        beginCalendar.selectedMonth,
                        beginCalendar.selectedDate, 0, 0, 0)), "date");
        $("mini_start").style.display = "none";
        miniStartVisible = false;
        $("newAppointmentForm").newappointment_ends_date.value = formatDate(
                new Date(Date.UTC(endCalendar.selectedYear,
                        endCalendar.selectedMonth, endCalendar.selectedDate, 0,
                        0, 0)), "date");
        $("mini_end").style.display = "none";
        miniEndVisible = false;
        old_startdate = startdate.getTime();
    }
    // fill out form
    var ap = $("newAppointmentForm");
    
    // title / description
    setTitle(calenObj.title);
    
    // location
    (calenObj.location) ? ap.newappointment_location.value = calenObj.location
            : ap.newappointment_location.value = "";
    if (calenObj.categories) {
        ox.categories.ui.drawCategoriesList(ox.categories
                .getByString(calenObj.categories),
                $("newappointment_categories_list"));
    }
    (calenObj.note) ? ap.newappointment_comments.value = calenObj.note
            : ap.newappointment_comments.value = "";
    (calenObj.recurrence_position) ? recurrencePosition = calenObj.recurrence_position
            : recurrencePosition = 0;

    if (recurrencePosition && recurrencePosition > 0) {
        $("newappointment_personal_tr").style.display = "none";
        $("newappointment_categories_tr").style.display = "none";
        var series_button = $("newappointment_series_button");
        setDisabled(series_button, true);
        series_button.style.cursor = "default";
        series_button.tabIndex = -1;
    }

    if (calenObj.shown_as) {
        switch (calenObj.shown_as) {
        case 1:
            showAsPopup.setKey("RESERVED");
            break;
        case 2:
            showAsPopup.setKey("TEMPORARY");
            break;
        case 3:
            showAsPopup.setKey("ABSENT");
            break;
        case 4:
            showAsPopup.setKey("FREE");
            break;
        default:
            break;
        }
    }
    if (calenObj["start_date"]) {
        var mydate = new Date(parseInt(calenObj["start_date"]));
        startdate = new Date(Date.UTC(mydate.getUTCFullYear(), mydate
                .getUTCMonth(), mydate.getUTCDate(), mydate.getUTCHours(),
                mydate.getUTCMinutes(), 0));
    } else {
        var mydate = new Date();
        startdate = new Date(Date.UTC(mydate.getUTCFullYear(), mydate
                .getUTCMonth(), mydate.getUTCDate(), mydate.getUTCHours(),
                mydate.getUTCMinutes(), 0));
    }
    if (calenObj["end_date"]) {
        var mydate = new Date(parseInt(calenObj["end_date"]));
        enddate = new Date(Date.UTC(mydate.getUTCFullYear(), mydate
                .getUTCMonth(), mydate.getUTCDate(), mydate.getUTCHours(),
                mydate.getUTCMinutes(), 0));
    } else {
        enddate = new Date(startdate.getTime() + (1000 * 60 * 60));
    }
    if (calenObj["full_time"] === true || calenObj["full_time"] === "true") {
        ap.newappointment_wholeday.checked = "checked";
        window.setTimeout(function() {
            $("newappointment_begins_time_td").style.visibility = "hidden";
            $("newappointment_ends_time_td").style.visibility = "hidden";
            $("newappointment_begins_time").style.visibility = "hidden";
            $("newappointment_ends_time").style.visibility = "hidden";
        }, 0);
        if (enddate.getTime() - 86400000 < startdate.getTime()) {
            enddate = new Date(startdate.getTime());
        } else {
            enddate = new Date(object.end_date - 86400000);
        }
    }
    if (calenObj["private_flag"]) {
        ap.newappointment_personal.checked = "checked";
    }
    if (calenObj["alarm"] != undefined) {
        var setKeyDefault = reminderPopup.setKey(calenObj.alarm);
        if (!setKeyDefault) {
            // fallback when reminder is setting with a external tool like
            // Outlook and a alarm time which is not per default supported
            var milliAlarmTime = calenObj.alarm * 60 * 1000;

            reminderPopup.addElement(getInterval(milliAlarmTime),
                    calenObj.alarm);
            reminderPopup.sortKeys();
            reminderPopup.getDomNode();
            reminderPopup.setKey(object.alarm);
        }

    } else if (data["modul"].match(/edit/, i)) {
        // set back to -1 on edit if no reminder has been set
        reminderPopup.setKey(-1);
    }

    if (calenObj["notification"]) {
        ap.newappointment_notification.checked = "checked";
    }
    if (calenObj["number_of_attachments"]) {
        setNumberOfAttNewApp(calenObj.number_of_attachments);
    }
    minutesstart = startdate.getUTCMinutes();
    minutesend = enddate.getUTCMinutes();
    if ((minutesstart.toString()).length < 2) {
        minutesstart = "0" + minutesstart;
    }
    if ((minutesend.toString()).length < 2) {
        minutesend = "0" + minutesend;
    }
    endhour = enddate.getUTCHours();
    starthour = startdate.getUTCHours();

    fillFieldsPrivate();
    if (globalseries != null)
        globalseries.setParameters(calenObj, data.modul == "new");

    // enable final participant object (and wait for callback)
    newAppointment.participants.initalFillBigGrid(calenObj, function() {
        participantsLoaded = true;
        // set participants tab
            setNumberOfParticipants();
            // disable loading screen
            $("loading_data_bg").style.display = "none";
        });
}

function createComboxes() {
    showAsPopup = new ComboBox3(window, "newappointment_display", "190px", 0,
            true, null, null);
    showAsPopup.addElement(_("reserved"), "RESERVED");
    showAsPopup.addElement(_("temporary"), "TEMPORARY");
    showAsPopup.addElement(_("absent on business"), "ABSENT");
    showAsPopup.addElement(_("free"), "FREE");
    showAsPopup.getDomNode();

    startTimePopup = new ComboBox3(window, "newappointment_begins_time",
            "85px", 0, true, "cdv_starttimepopup", 10);
    endTimePopup = new ComboBox3(window, "newappointment_ends_time", "85px", 0,
            true, "cdv_endtimepopup", 10);

    register("cdv_starttimepopup", setStartTimeDayView);
    register("cdv_endtimepopup", setEndTimeDayView);
    startTimePopup.addElement(_("--:--"), -1);
    endTimePopup.addElement(_("--:--"), -1);
    var interval = configGetKey("gui.calendar.interval");
    var d = new Date(0);
    for ( var i = 0; i < 60 * 24; i += interval) {
        d.setTime(i * 60000);
        var s = formatDate(d, "time");
        startTimePopup.addElement(s, expectI18n(s));
        endTimePopup.addElement(s, expectI18n(s));
    }
    endTimePopup.getDomNode();
    startTimePopup.getDomNode();

    var h = 60, d = 1440, w = 10080; // minutes per hour, day and week
    var intervals = [ 0, 15, 30, 45, 1 * h, 2 * h, 4 * h, 6 * h, 8 * h, 12 * h,
            1 * d, 2 * d, 3 * d, 4 * d, 5 * d, 6 * d, 1 * w, 2 * w, 3 * w,
            4 * w ];

    reminderPopup = new ComboBox3(window, "newappointment_reminder", "12em", 2,
            true, null, 7);
    reminderPopup.addElement(_("no reminder"), "-1");
    for ( var i = 0; i < intervals.length; i++) {
        reminderPopup.addElement(getInterval(intervals[i] * 6e4), intervals[i]); // ms /
                                                                                    // min
    }
    reminderPopup.getDomNode();

    var default_reminder = configGetKey("gui.calendar.default_reminder");
    if (default_reminder != undefined) {
        reminderPopup.setKey(default_reminder);
    }

}

function setStartTimeDayView() {
    var key = startTimePopup.getKey();
    if (key != -1) {
        $("newAppointmentForm").newappointment_begins_time_text.value = key;
    }
    nappointment_checkDate('start');
}
function setEndTimeDayView() {
    var key = endTimePopup.getKey();
    if (key != -1) {
        $("newAppointmentForm").newappointment_ends_time_text.value = key;
    }
    nappointment_checkDate('end');
}

function fn_afterUpload(errorUpdate) {
    window.onbeforeunload = null;

    if (updateReminder) {
        corewindow.updateReminders();
    }
    corewindow.triggerEvent("OX_Refresh_Mini_Calendar");

    // callback to close window
    function fn_close() {
        if (!errorUpdate)
            window.setTimeout(function() {
                ox.api.window.close(url.guid);
            }, 0);
    }

    if (newAppointment.attachmentDialog.attach_changed()) {
        corewindow.triggerEvent("OX_Quota_Update");
    }

    // is the current view of the opener of type calendar?
    // if not we just close this window
    if (!corewindow || corewindow.currentpath[0] != "calendar") {
        fn_close();

    } else {
        // ok, it's calendar. some of the update implementations are different
        // and needs to be triggered manually.
        if (corewindow.currentpath[1] == "detail") {
            corewindow.reloadAppDetailView(fn_close, clickedItem);
        } else if (corewindow.currentpath[0] == "calendar"
                && corewindow.currentpath[1] == "team") {
            // trigger event
            corewindow.triggerEvent("OX_After_New_Appointment");
            setTimeout(fn_close, 0);
        } else {
            corewindow.storageCache.update(fn_close);
        }
    }
}

var cb_error = function(cb) {
    fn_afterUpload(true);
    newServerError(cb);
}

function writeNewAppointment() {
    if (savePending)
        return;
    savePending = true;

    function radioValue(rObj) {
        for ( var i = 0; i < rObj.length; i++)
            if (rObj[i].checked)
                return rObj[i].value;
        return false;
    }

    $("newAppointmentForm").newappointment_description.className = "leftVerylong";
    $("newAppointmentForm").newappointment_begins_date.className = "dateTimeInput";
    $("newAppointmentForm").newappointment_ends_date.className = "dateTimeInput";
    $("newAppointmentForm").newappointment_ends_time_text.className = "dateTimeInput";
    $("newAppointmentForm").newappointment_begins_time_text.className = "dateTimeInput";

    if (data['modul'] && data['modul'] == "new") {
        var ap = $("newAppointmentForm");

        var startdate = parseDateString(ap.newappointment_begins_date.value,
                "date");
        var enddate = parseDateString(ap.newappointment_ends_date.value, "date");
        var starttime = parseDateString(
                ap.newappointment_begins_time_text.value, "time");
        var endtime = parseDateString(ap.newappointment_ends_time_text.value,
                "time");

        if (startdate && enddate && starttime && endtime) {
            startdate.setUTCHours(starttime.getUTCHours());
            startdate.setUTCMinutes(starttime.getUTCMinutes());
            enddate.setUTCHours(endtime.getUTCHours());
            enddate.setUTCMinutes(endtime.getUTCMinutes());

            starttime = null;
            endtime = null;

            ap_object = {
                folder_id : clickedItem
            }

            if (!ap.newappointment_wholeday.checked)
                ap_object.start_date = startdate.getTime();
            else
                ap_object.start_date = Date.UTC(startdate.getUTCFullYear(),
                        startdate.getUTCMonth(), startdate.getUTCDate(), "0",
                        "0", "0");

            if (!ap.newappointment_wholeday.checked)
                ap_object.end_date = enddate.getTime();
            else
                ap_object.end_date = Date.UTC(enddate.getUTCFullYear(), enddate
                        .getUTCMonth(), enddate.getUTCDate(), "0", "0", "0") + 86400000;

            if (ap_object.end_date >= ap_object.start_date) {

                if (ap.newappointment_description.value != "")
                    ap_object.title = ap.newappointment_description.value;

                if (ap.newappointment_comments.value != "Your comments")
                    ap_object.note = ap.newappointment_comments.value;
                if (ap.newappointment_location.value != "")
                    ap_object.location = ap.newappointment_location.value;
                if (ap.newappointment_wholeday.checked)
                    ap_object.full_time = true;
                else
                    ap_object.full_time = false;
                if (calenObj && calenObj.categories) {
                    ap_object.categories = calenObj.categories;
                }
                if (ap.newappointment_personal.checked
                        && ($("newappointment_personal_tr").style.visibility == "visible" || $("newappointment_personal_tr").style.visibility == "")) {
                    ap_object.private_flag = true;
                } else {
                    ap_object.private_flag = false;
                }
                switch (showAsPopup.getKey()) {
                case "RESERVED":
                    ap_object.shown_as = 1;
                    break;
                case "TEMPORARY":
                    ap_object.shown_as = 2;
                    break;
                case "ABSENT":
                    ap_object.shown_as = 3;
                    break;
                case "FREE":
                    ap_object.shown_as = 4;
                    break;
                default:
                    break;
                }

                ap_object.alarm = reminderPopup.getKey();
                if (ap_object.alarm >= 0)
                    updateReminder = true;

                ap_object.notification = ap.newappointment_notification.checked;
                if (newAppointment.participants == undefined) {
                    // Besitzer des Folders
                    if (!folderOwner) {
                        folderOwner = configGetKey("identifier");
                    }
                    newAppointment.participants = new Participants(
                            "participantsNewAppointment",
                            setNumberOfParticipants, true, true, true, true,
                            "Select Participants and Resources", folderOwner); /* i18n */
                }
                if (newAppointment.participants.containsParticipants()) {
                    setBeforeUnload(true);
                    ap_object.participants = newAppointment.participants
                            .getParticipants();
                }
                if (globalseries != null)
                    ap_object = globalseries.getParameters(ap_object);

                // create new appointment
                setModalBusy(true);
                json.put(AjaxRoot + "/calendar?action=new&session=" + session,
                        ap_object, null, function(cb) {
                            // success?
                        if (cb && cb.data && cb.data.id) {

                            // create dummy divs that are helpful for QA tests
                        var myCreatedAppDiv = document.createElement("div");
                        myCreatedAppDiv.id = "newAppointmentId"; // for QA
                        myCreatedAppDiv.style.display = "none";
                        myCreatedAppDiv.innerHTML = cb.data.id;
                        $('body').appendChild(myCreatedAppDiv);

                        var myCreatedAppDivFolder = document
                                .createElement("div");
                        myCreatedAppDivFolder.id = "newAppointmentFolder"; // for
                                                                            // QA
                        myCreatedAppDivFolder.style.display = "none";
                        myCreatedAppDivFolder.innerHTML = ap_object.folder_id;
                        $('body').appendChild(myCreatedAppDivFolder);

                        if (newAppointment.attachmentDialog.attach_changed()) {
                            setBeforeUnload(true);
                            // savePending = true;
                            var obj = new Object();
                            obj['attached'] = cb.data.id;
                            obj['module'] = 1;
                            obj['folder'] = ap_object.folder_id
                                    || ap_object.folder;
                            newAppointment.attachmentDialog.do_post(obj,
                                    fn_afterUpload, null, null, cb_error);
                        } else {
                            fn_afterUpload();
                        }
                    } else if (cb && cb.data && cb.data.conflicts) {
                        ConflictsPopup.open(ap_object, cb.data.conflicts,
                                cb_cancelCloseConflict, cb_cancelCloseConflict,
                                cb_ignoreConflict);
                    }
                }, setModalBusy);
            } else if (ap_object.end_date < ap_object.start_date) {
                var tmp = ap_object.start_date - ap_object.end_date;
                if (tmp > 86400000)
                    triggerEvent("OX_New_Error", 4,
                            _("End date is before start date"));
                else
                    triggerEvent("OX_New_Error", 4,
                            _("End time is before start time"));
                savePending = false;
            }

        } else {
            if (currentpath[1] != "appointment")
                triggerEvent("OX_Switch_View", "calendar_new/appointment");
            if (!startdate)
                $("newAppointmentForm").newappointment_begins_date.className += " borderDefault border-color-error";
            if (!enddate)
                $("newAppointmentForm").newappointment_ends_date.className += " borderDefault border-color-error";
            if (!endtime)
                $("newAppointmentForm").newappointment_ends_time_text.className += " borderDefault border-color-error";
            if (!starttime)
                $("newAppointmentForm").newappointment_begins_time_text.className += " borderDefault border-color-error";
            triggerEvent("OX_New_Error", 4, _("Mandatory Field(s) missing!"));
            savePending = false;
        }

    } else if (data['modul'] == "edit") {
        var ap = $("newAppointmentForm");
        var startdate = parseDateString(ap.newappointment_begins_date.value,
                "date");
        var enddate = parseDateString(ap.newappointment_ends_date.value, "date");
        var starttime = parseDateString(
                ap.newappointment_begins_time_text.value, "time");
        var endtime = parseDateString(ap.newappointment_ends_time_text.value,
                "time");

        if (startdate && enddate && starttime && endtime) {
            startdate.setUTCHours(starttime.getUTCHours());
            startdate.setUTCMinutes(starttime.getUTCMinutes());
            enddate.setUTCHours(endtime.getUTCHours());
            enddate.setUTCMinutes(endtime.getUTCMinutes());

            starttime = null;
            endtime = null;

            // start with fresh object (single appointment / exception)
            // or copy all information available (recurrence)
            if (calenObj.recurrence_position > 0) {
                // adding the recurrence_position here is mandatory!
                ap_object = {
                    recurrence_position : calenObj.recurrence_position
                };
            } else {
                // copy all data
                ap_object = calenObj;
            }

            // now overwrite changes
            if (!ap.newappointment_wholeday.checked)
                ap_object.start_date = startdate.getTime();
            else
                ap_object.start_date = Date.UTC(startdate.getUTCFullYear(),
                        startdate.getUTCMonth(), startdate.getUTCDate(), "0",
                        "0", "0");

            if (!ap.newappointment_wholeday.checked)
                ap_object.end_date = enddate.getTime();
            else
                ap_object.end_date = Date.UTC(enddate.getUTCFullYear(), enddate
                        .getUTCMonth(), enddate.getUTCDate(), "0", "0", "0") + 86400000;

            if (ap_object.end_date >= ap_object.start_date) {

                // if(clickedItem != calenObj.folder_id) ap_object.folder_id =
                // clickedItem;
                ap_object.folder_id = clickedItem;

                if (ap.newappointment_description.value != calenObj.title)
                    ap_object.title = ap.newappointment_description.value;

                var appComment = ap.newappointment_comments.value;
                if (appComment != calenObj.note)
                    ap_object.note = appComment.length != 0 ? appComment : null;
                if (ap.newappointment_location.value != ""
                        || ap.newappointment_location.value != calenObj.location)
                    ap_object.location = ap.newappointment_location.value;
                if (ap.newappointment_wholeday.checked)
                    ap_object.full_time = true;
                else
                    ap_object.full_time = false;
                if (calenObj && calenObj.categories) {
                    ap_object.categories = calenObj.categories;
                }
                if (ap.newappointment_personal.checked
                        && ($("newappointment_personal_tr").style.visibility == "visible" || $("newappointment_personal_tr").style.visibility == "")) {
                    ap_object.private_flag = true;
                } else {
                    ap_object.private_flag = false;
                }
                switch (showAsPopup.getKey()) {
                case "RESERVED":
                    if (calenObj.shown_as != 1)
                        ap_object.shown_as = 1;
                    break;
                case "TEMPORARY":
                    if (calenObj.shown_as != 2)
                        ap_object.shown_as = 2;
                    break;
                case "ABSENT":
                    if (calenObj.shown_as != 3)
                        ap_object.shown_as = 3;
                    break;
                case "FREE":
                    if (calenObj.shown_as != 4)
                        ap_object.shown_as = 4;
                    break;
                default:
                    break;
                }

                if (newAppointment.participants
                        && newAppointment.participants.containsParticipants()) {
                    setBeforeUnload(true);
                    ap_object.participants = newAppointment.participants
                            .getParticipants();
                } else {
                    ap_object.participants = [];
                }

                if (Number(reminderPopup.getKey()) != Number(calenObj.alarm)) {
                    updateReminder = true;
                    ap_object.alarm = reminderPopup.getKey();
                }

                if (reminderPopup.getKey() >= 0) {
                    updateReminder = true;
                }

                if (ap.newappointment_notification.checked
                        && calenObj.notification != true) {
                    ap_object.notification = true;
                } else {
                    ap_object.notification = false;
                }

                if (globalseries != null) {
                    ap_object = globalseries.getParameters(ap_object);
                    // user want to change a series into a single app.
                    // therefore we have to delete old stuff.
                    if (!(data.recurrence_position > 0) // use > because of
                                                        // undefined etc.
                            && ap_object.recurrence_type === 0) {
                        delete (ap_object.recurrence_position);
                        delete (ap_object.interval);
                        delete (ap_object.recurrence_start);
                        delete (ap_object.recurrence_id);
                        delete (ap_object.occurrences);
                        delete ap_object.days;
                        delete ap_object.day_in_month;
                        delete ap_object.month;
                        delete ap_object.until;
                        delete ap_object.sequence;
                    }

                    // remove "days" if null
                    if (ap_object.days === null) {
                        delete ap_object.days;
                    }
                    // remove "day_in_month" for once/daily/weekly series
                    if (ap_object.recurrence_type < 3) {
                        delete ap_object.day_in_month;
                    }
                    // remove "month" for non-yearly series
                    if (ap_object.recurrence_type < 4) {
                        delete ap_object.month;
                    }
                }

                // display modal loading screen
                setModalBusy(true);
                json
                        .put(AjaxRoot + "/calendar?action=update&session="
                                + session + "&id=" + data["id"] + "&timestamp="
                                + newappTimestamp + "&folder="
                                + data["folder_id"], ap_object, null, function(
                                cb) {
                            if (cb && cb.data && !cb.data.conflicts) {

                                if (newAppointment.attachmentDialog
                                        .attach_changed()) {
                                    setBeforeUnload(true);
                                    // savePending = true;
                                var obj = new Object();
                                obj['attached'] = cb.data.id;
                                obj['module'] = 1;
                                obj['folder'] = ap_object.folder_id
                                        || ap_object.folder; // data["folder_id"];
                                newAppointment.attachmentDialog.do_post(obj,
                                        fn_afterUpload, null, null, cb_error);
                            } else {
                                fn_afterUpload();
                            }
                        } else if (cb && cb.data && cb.data.conflicts) {
                            ConflictsPopup.open(ap_object, cb.data.conflicts,
                                    cb_cancelCloseConflict,
                                    cb_cancelCloseConflict, cb_ignoreConflict);
                        }
                    }, setModalBusy);

            } else if (ap_object.end_date < ap_object.start_date) {
                var tmp = ap_object.start_date - ap_object.end_date;
                if (tmp > 86400000)
                    triggerEvent("OX_New_Error", 4,
                            _("End date is before start date"));
                else
                    triggerEvent("OX_New_Error", 4,
                            _("End time is before start time"));
                savePending = false;
            }
        } else {
            if (currentpath[1] != "appointment")
                triggerEvent("OX_Switch_View", "calendar_new/appointment");
            if (!startdate)
                $("newAppointmentForm").newappointment_begins_date.className += " borderDefault border-color-error";
            if (!enddate)
                $("newAppointmentForm").newappointment_ends_date.className += " borderDefault border-color-error";
            if (!endtime)
                $("newAppointmentForm").newappointment_ends_time_text.className += " borderDefault border-color-error";
            if (!starttime)
                $("newAppointmentForm").newappointment_begins_time_text.className += " borderDefault border-color-error";
            triggerEvent("OX_New_Error", 4, _("Mandatory Field(s) missing!"));
            savePending = false;
        }
    }

    function checkboxValue(rObj) {
        var daysByteValue = 0;
        for ( var i = 0; i < rObj.length; i++) {
            if (rObj[i].checked)
                daysByteValue = parseInt(parseInt(rObj[i].value)
                        + parseInt(daysByteValue));
        }
        return daysByteValue;
    }

}

/**
 * Callback when you cancel or close the ConflictsWindow Needed to enable the
 * save button again
 */
function cb_cancelCloseConflict() {
    savePending = false;
}

/**
 * Callback when you ignore conflicts
 */
function cb_ignoreConflict(cb) {
    ap_object.ignore_conflicts = true;

    var uri = AjaxRoot + "/calendar";
    if (data["modul"] != "edit") {
        uri += "?action=new";
    } else {
        uri += "?action=update&id=" + data["id"] + "&timestamp="
                + 1154505988000 * 2 + "&folder=" + data["folder_id"];
    }
    uri += "&session=" + session;

    setModalBusy(true);
    json
            .put(
                    uri,
                    ap_object,
                    null,
                    function(cb) {
                        savePending = false;
                        if (cb && cb.data && cb.data.id) {
                            if (newAppointment.attachmentDialog
                                    .attach_changed()) {
                                setBeforeUnload(true);
                                var obj = new Object();
                                obj['attached'] = cb.data.id;
                                obj['module'] = 1;
                                obj['folder'] = calenObj && calenObj.folder_id ? calenObj.folder_id
                                        : clickedItem;
                                ;
                                newAppointment.attachmentDialog.do_post(obj,
                                        fn_afterUpload, null, null, cb_error);
                            } else {
                                fn_afterUpload();
                            }
                        }
                    }, setModalBusy);

    ConflictsPopup.close();
}

function getSequenceUntil() {
    return parseDateString($("sequence_end_date").value, "date").getTime();
}

function clearCommentsField() {
    var ap = $("newAppointmentForm");
    removeChildNodes(ap.newappointment_comments);
}

function wholedayNewAppointmentDisable() {
    var ap = $("newAppointmentForm");
    if (ap.newappointment_wholeday.checked) {
        $("newappointment_begins_time_td").style.visibility = "hidden";
        $("newappointment_ends_time_td").style.visibility = "hidden";
        $("newappointment_begins_time").style.visibility = "hidden";
        $("newappointment_ends_time").style.visibility = "hidden";
    } else {
        $("newappointment_begins_time_td").style.visibility = "visible";
        $("newappointment_ends_time_td").style.visibility = "visible";
        $("newappointment_begins_time").style.visibility = "visible";
        $("newappointment_ends_time").style.visibility = "visible";
    }
}

function closeNewAppointmentWindow() {
    function cbyes() {
        window.onbeforeunload = null;
        window.onunload = null;
        // trigger event to notify about window close
        ox.api.window.core.triggerEvent("OX_Window_Close", {
            handle : url.guid
        });

        ox.api.window.close(url.guid);
    }
    if (messageOnCancel)
        newConfirm(
                _("Close Window"),
                _("Do you really want to discard your changes and close the window?"),
                AlertPopup.YESNO, null, null, cbyes, null);
    else
        cbyes();
}

var participantsLoaded = false;

/**
 * ******************************** Tabs
 * ****************************************************************
 */
register("OX_Calendar_New_Switch", function(param) {
    var newpath = currentpath2.slice(0);
    newpath[1] = param;
    newpath.length = 2;
    switchtoView(newpath.join("/"));
});
var tabsList = new Array('tab1', 'tab2', 'tab3', 'tab4');
var panelsList = new Array('panel1', 'panel2', 'panel3', 'panel4');
var eventList = new Array( [ 'OX_Calendar_New_Switch', 'appointment' ], [
        'OX_Calendar_New_Switch', 'participant' ], [ 'OX_Calendar_New_Switch',
        'attachment' ], [ 'OX_Calendar_New_Switch', 'availability' ]);

/**
 * *******************Availability
 * ********************************************************************************
 */
function isDisableTeamview() {
    return !(corewindow.configGetKey("modules.calendar.calendar_freebusy") && corewindow
            .configGetKey("modules.calendar.calendar_teamview"));
}
var na_availability_json = new JSON();
var calendar_new_availability_bool = false;
var tmpstart;
var tmpend;
var calendar_new_availability_do_nothing = false;
var calendar_new_availability_check_date;
var calendar_new_availability_check_date2;
var calendar_new_availability_mini_calendar;
var calendar_new_availability_start_time;
var calendar_new_availability_end_time;
var calendar_new_availability_objects;
var checkdate;
var calendar_new_availability_requests = new Object();
var calendar_new_availability_optimized = new Object();
var cn_avail_subchilds = new Array();
function startAvailability() {
    if (!calendar_new_availability_bool) {
        checkressource = document
                .getElementById('calendar_new_availablity_showressource').checked = true;
        checkparticipants = document
                .getElementById('calendar_new_availablity_showparticipants').checked = true;
        resolvegroups = document
                .getElementById('calendar_new_availablity_resolvegroups').checked = true;
        externalparticipants = document
                .getElementById('calendar_new_availablity_showexternal').checked = true;
        calendar_new_availability_bool = true;
    }
    calendar_resize_first = true;
    cnavail_scroll();
    calendar_new_availability_mini_calendar.setSelectedByDate(
            beginCalendar.selectedYear, beginCalendar.selectedMonth,
            beginCalendar.selectedDate);
    calendar_new_availability_setDate();

    calendar_new_availability_start_time.setKey(startTimePopup.getKey());
    calendar_new_availability_end_time.setKey(endTimePopup.getKey());
    if (calendar_new_availability_start_time.getSelectedIndex() > calendar_new_availability_end_time
            .getSelectedIndex()) {
        calendar_new_availability_end_time
                .setSelectedIndex(calendar_new_availability_end_time.elements.length - 1);
    }
    calendar_new_availability_check_date = new Date(Date.UTC(
            calendar_new_availability_mini_calendar.selectedYear,
            calendar_new_availability_mini_calendar.selectedMonth,
            calendar_new_availability_mini_calendar.selectedDate, 0, 0, 0));
    if (!calendar_new_availability_do_nothing) {
        cn_avail_updateHeaderTime();
        calendar_new_availability_checkFreebusy();
    }

    var hover = new Hover($("cnavail_freebusy_content"), OXAppointmentHover
            .getContent().node);
    hover.setSize(OXAppointmentHover.contentobject.node);
    hover.getTarget = function(node) {
        try {
            while (node) {
                if (node.ox_user != undefined && node.ox_app_id != undefined) {
                    return node.parentNode ? node : null;
                }
                node = node.parentNode;
            }
        } catch (e) { /* see default implementation */
        }
    };
    hover.onShow = function(node) {
        OXAppointmentHover.actualHover = this;
        var obj = calendar_new_availability_objects.users[node.ox_user][node.ox_app_id];

        if (obj.id != undefined && obj.folder_id != undefined) {
            // we have a folder and a object id so we can use the regular hover
            OXAppointmentHover.refillContent(obj.id, obj.folder_id,
                    obj.recurrence_position || 1);
        } else {
            // disable tabs we don't need
            OXAppointmentHover.slider.getTabById("participants").show(false);
            OXAppointmentHover.slider.getTabById("attachments").show(false);
            OXAppointmentHover.slider.getTabById("others").show(false);
            OXAppointmentHover.refillContentByObject(obj);
        }

        OXAppointmentHover.accordion.removeComponent("ConfirmDialog")
        if (OXAppointmentHover.accordion.components["ParticipantsUsers"]) {
            OXAppointmentHover.accordion.components["ParticipantsUsers"].content
                    .getElementsByTagName("td")[1].style.display = "none";
        }
    }
    hover.onHide = function(node) {
        // re-enable tabs for later use
        OXAppointmentHover.slider.getTabById("participants").show(true);
        OXAppointmentHover.slider.getTabById("attachments").show(true);
        OXAppointmentHover.slider.getTabById("others").show(true);
    }
    if (configGetKey("gui.effects.hover.calendar")) {
        OXAppointmentHover.disableConfirmation = true;
        hover.enable();
    }
}
function setScrollPoint() {
    if (calendar_resize_first) {
        var time = calendar_new_availability_start_time.getKey();
        if (time == -1) {
            time = $("newappointment_begins_time_text").value;
        }
        var starttime = parseDateString(time, "time");
        if (starttime) {
            document.getElementById("cnavail_scroller").scrollLeft = starttime
                    .getUTCHours() * 40;
            document.getElementById("cnavail_timeline_scroller").scrollLeft = (document
                    .getElementById("cnavail_scroller").scrollLeft);
        }
    }
    calendar_resize_first = false;
}
function cn_avail_updateHeaderTime() {
    var mytime = document.getElementById("calendar_new_availablity_date");
    /*
     * var
     * showHeader=(calendar_new_availability_check_date.getUTCMonth()+1)+'/'+calendar_new_availability_check_date.getUTCFullYear();
     * if(calendar_new_availability_check_date.getUTCMonth()<9) { showHeader
     * ='0'+showHeader; }
     * showHeader=calendar_new_availability_check_date.getUTCDate()
     * +'/'+showHeader; if(calendar_new_availability_check_date.getUTCDate()<10) {
     * showHeader='0'+showHeader; }
     */
    mytime.innerHTML = formatDate(calendar_new_availability_check_date,
            "dateday");
}
function cn_avail_gotoNextDay(changes) {
    calendar_new_availability_check_date
            .setDate(calendar_new_availability_check_date.getDate() + changes);
    calendar_new_availability_mini_calendar.setSelectedByDate(
            calendar_new_availability_check_date.getUTCFullYear(),
            calendar_new_availability_check_date.getUTCMonth(),
            calendar_new_availability_check_date.getUTCDate());
    calendar_new_availability_setDate();
    if (!calendar_new_availability_do_nothing) {
        cn_avail_updateHeaderTime();
        calendar_new_availability_checkFreebusy();
    }
}
function availability_translateTime(value) {
    return function() {
        return formatDate(value, "time");
    }
}

function initAvailability() {
    avaliabityInitialLoaded = true;
    calendar_new_availability_mini_calendar = new cMiniCalendar(
            $("calendar_new_availability_miniCalendarHeader"),
            $("calendar_new_availability_miniCalendarContent"),
            calendar_new_availability_changeDateByClick, false, 'avaibility',
            $("calendar_new_availability_header_month"),
            $("calendar_new_availability_header_year"));

    calendar_new_availability_start_time = new ComboBox3(window,
            "calendar_new_availability_fromtime", "85px", 0, true, null, 9);
    calendar_new_availability_end_time = new ComboBox3(window,
            "calendar_new_availability_tilltime", "85px", 0, true, null, 9);
    calendar_new_availability_start_time.addElement(_("--:--"), -1);
    calendar_new_availability_end_time.addElement(_("--:--"), -1);
    var interval = configGetKey("gui.calendar.interval");
    var d = new Date(0);
    for ( var i = 0; i < 60 * 24; i += interval) {
        d.setTime(i * 60000);
        var s = formatDate(d, "time");
        calendar_new_availability_start_time.addElement(s, expectI18n(s));
        calendar_new_availability_end_time.addElement(s, expectI18n(s));
    }
    calendar_new_availability_start_time.getDomNode();
    calendar_new_availability_end_time.getDomNode();

    var myheadertimes = $("cnavail_timeline_scroller").getElementsByTagName(
            "div");
    for ( var zahl = 0; zahl < myheadertimes.length - 1; zahl++) {
        d.setUTCHours(zahl, 0);
        myheadertimes[zahl].firstChild.nodeValue = formatDate(d, "hour");
    }

}
function calendar_new_availability_use_Appointment() {
    $("newappointment_begins_date").value = $("calendar_new_availablity_date_input").value;
    if (calendar_new_availability_start_time.getKey() != -1
            && calendar_new_availability_start_time.getKey() != -1) {
        startTimePopup.setKey(calendar_new_availability_start_time.getKey());
        endTimePopup.setKey(calendar_new_availability_end_time.getKey());
        setStartDate2();
        setEndDate2();
    }
    $("newappointment_ends_date").value = $("calendar_new_availablity_date_input").value;
    if (calendar_new_availability_start_time.getKey() != -1
            && calendar_new_availability_start_time.getKey() != -1) {
        startTimePopup.setKey(calendar_new_availability_start_time.getKey());
        endTimePopup.setKey(calendar_new_availability_end_time.getKey());
        setStartDate2();
        setEndDate2();
    }
    changeTab('tab1', 'panel1');

}
function calendar_new_availability_changeDateByClick() {
    calendar_new_availability_mini_calendar.setSelected(this.id);
    calendar_new_availability_setDate();
}
function cnavail_availability_changed() {
    var tmp = document.getElementById("calendar_new_availablity_date_input");
    var tmpdate = parseDateString(tmp.value, "date");
    if (!tmpdate) {
        triggerEvent("OX_New_Error", 4, _("Invalid date"));
    } else {
        tmp.value = formatDate(tmpdate, "date");
        calendar_new_availability_check_date2 = tmpdate;
    }

}
function calendar_new_availability_setDate() {
    var tmp = document.getElementById("calendar_new_availablity_date_input");
    document.getElementById("calendar_new_availability_mini_start").style.display = "none";
    calendar_new_availability_check_date2 = new Date(Date.UTC(
            calendar_new_availability_mini_calendar.selectedYear,
            calendar_new_availability_mini_calendar.selectedMonth,
            calendar_new_availability_mini_calendar.selectedDate, 0, 0, 0));
    tmp.value = formatDate(calendar_new_availability_check_date2, "date");
}
function calendar_new_availability_showMiniStart() {
    var tmp = document.getElementById("calendar_new_availability_mini_start");
    tmp.style.display = "block";
    tmp.left = 0;
    tmp.top = "1.6em";
    tmp.style.zIndex = "250";
}
function calendar_new_availability_closeMiniCalendar() {
    var tmp = document.getElementById("calendar_new_availability_mini_start");
    tmp.style.display = "none";
}
function cnavail_checkClicked(type) {
    switch (type) {
    case "RESSOURCE":
        checkressource = document
                .getElementById('calendar_new_availablity_showressource').checked;
        if (!calendar_new_availability_do_nothing) {
            calendar_new_availability_checkFreebusy();
        }
        break;
    case "PARTICIPANTS":
        checkparticipants = document
                .getElementById('calendar_new_availablity_showparticipants').checked;
        if (!calendar_new_availability_do_nothing) {
            calendar_new_availability_checkFreebusy();
        }
        break;
    case "GROUPS":
        resolvegroups = document
                .getElementById('calendar_new_availablity_resolvegroups').checked;
        cnavail_doResolveGroups(resolvegroups);
        break;
    case "EXTERNAL":
        externalparticipants = document
                .getElementById('calendar_new_availablity_showexternal').checked;
        cnavail_doShowExternalParticipants(externalparticipants);
    }
}
var checkressource = true;
var checkparticipants = true;
var resolvegroups = true;
var externalparticipants = true;

function calendar_new_availability_checkFreebusy() {
    calendar_new_availability_do_nothing = true;
    var requestswaiting = 1;
    var maxrequests = 100;
    calendar_new_availability_objects = new Object();
    calendar_new_availability_requests = new Object();
    calendar_new_availability_requests["request"] = new Array();
    calendar_new_availability_requests["objects"] = new Array();
    calendar_new_availability_optimized = new Object();
    calendar_new_availability_optimized["request"] = new Array();
    calendar_new_availability_optimized["objects"] = new Array();

    calendar_new_availability_requests["response"] = new Array();
    checkdate = calendar_new_availability_check_date;
    if (newAppointment.participants.containsParticipants()) {
        var allparticipants = newAppointment.participants.getParticipants();
        var users = new Array();
        var groups = new Array();
        var ressource = new Array();
        var externalusers = new Array();
        for (i = 0; i < allparticipants.length; i++) {
            var pObject = allparticipants[i];
            switch (pObject.type) {
            case 1:
                if (checkparticipants) {
                    users.push(pObject);
                }
                break;
            case 2:
                if (checkparticipants) {
                    groups.push(pObject);
                }
                break;
            case 3:
                if (checkressource) {
                    ressource.push(pObject);
                }
                break;
            case 5:
                if (externalparticipants) {
                    externalusers.push(pObject);
                }
            }
        }
        for (r = 0; r < users.length; r++) {
            addAjaxRequest("USER", users[r]);
        }
        if (groups.length > 0) {
            addAjaxRequest("GROUP", groups);
        }
        for (r = 0; r < ressource.length; r++) {
            addAjaxRequest("RESSOURCE", ressource[r]);
        }
        requestswaiting--;
        if (requestswaiting == 0) {
            startMultipleRequest();
        }

    } else {
        calendar_new_availability_do_nothing = false;
    }
    function addAjaxRequest(requesttype, pObject) {
        switch (requesttype) {
        case "USER":
            var requestObject = new Object();
            requestObject['module'] = "calendar";
            requestObject['action'] = 'freebusy';
            requestObject['id'] = pObject.id;
            requestObject['type'] = pObject.type;
            requestObject['start'] = checkdate.getTime();
            requestObject['end'] = checkdate.getTime() + (1000 * 60 * 60 * 24);
            calendar_new_availability_requests["request"].push(requestObject);
            calendar_new_availability_requests["objects"].push(pObject);
            break;
        case "GROUP":
            var searchgroups = new Array();
            for (i = 0; i < pObject.length; i++) {
                searchgroups.push(pObject[i]);
            }
            requestswaiting++;
            internalCache.getObjects(searchgroups, groupFirstStep);
            break;
        case "RESSOURCE":
            var requestObject = new Object();
            requestObject['module'] = "calendar";
            requestObject['action'] = 'freebusy';
            requestObject['id'] = pObject.id;
            requestObject['type'] = pObject.type;
            requestObject['start'] = checkdate.getTime();
            requestObject['end'] = checkdate.getTime() + (1000 * 60 * 60 * 24);
            calendar_new_availability_requests["request"].push(requestObject);
            calendar_new_availability_requests["objects"].push(pObject);
            break;
        }

        function groupFirstStep(response) {
            for (i in response) {
                var members = response[i].members;
                for (i2 = 0; i2 < groups.length; i2++) {
                    if (groups[i2].id == i) {
                        groups[i2].members = members;
                    }

                }
                requestswaiting++;
                internalCache.getUsers(members, groupSecondStep);
            }
            requestswaiting--;
            if (requestswaiting == 0) {
                startMultipleRequest();
            }
        }
        function groupSecondStep(response) {
            for (i2 in response) {
                var requestObject = new Object();
                requestObject['module'] = "calendar";
                requestObject['action'] = 'freebusy';
                requestObject['id'] = i2;
                requestObject['start'] = checkdate.getTime();
                requestObject['end'] = checkdate.getTime()
                        + (1000 * 60 * 60 * 24);
                response[i2].type = 1;
                requestObject['type'] = response[i2].type;
                calendar_new_availability_requests["request"]
                        .push(requestObject);
                calendar_new_availability_requests["objects"]
                        .push(response[i2]);
            }
            requestswaiting--;
            if (requestswaiting == 0) {
                startMultipleRequest();
            }
        }
    }
    function startMultipleRequest() {
        calendar_new_availability_do_nothing = true;
        calendar_new_availability_requests = optimizeFreeBusy(calendar_new_availability_requests);
        if (calendar_new_availability_requests["request"].length > 0) {
            na_availability_json.put(AjaxRoot + "/multiple?session=" + session,
                    calendar_new_availability_requests["request"], null,
                    freeBusyResponse);
        } else {
            var allparticipants = document
                    .getElementById("cnavail_participants_names");
            var alllines = document.getElementById("cnavail_freebusy_content");
            removeChildNodes(alllines);
            removeChildNodes(allparticipants);
            calendar_new_availability_do_nothing = false;
            setScrollPoint();
        }
    }
    function freeBusyResponse(response) {
        calendar_new_availability_requests["response"] = new Array();
        for (zaehler = 0; zaehler < response.length; zaehler++) {
            if (response[zaehler].data) {
                calendar_new_availability_requests["response"]
                        .push(response[zaehler].data);
            } else {
                calendar_new_availability_requests["response"]
                        .push(new Array());
            }
        }

        calendar_new_availability_objects = new Object();
        calendar_new_availability_objects.users = new Object();
        if (calendar_new_availability_requests["objects"]) {
            for (i3 = 0; i3 < calendar_new_availability_requests["objects"].length; i3++) {
                switch (calendar_new_availability_requests["objects"][i3].type) {
                case 1:
                case 3:
                    calendar_new_availability_objects.users[calendar_new_availability_requests["objects"][i3].id] = calendar_new_availability_requests["response"][i3];
                    break;
                }
            }
            calendar_new_availability_requests = new Object();
            redrawFreeBusy();
        } else {
            var allparticipants = document
                    .getElementById("cnavail_participants_names");
            var alllines = document.getElementById("cnavail_freebusy_content");
            removeChildNodes(alllines);
            removeChildNodes(allparticipants);
            calendar_new_availability_do_nothing = false;
            setScrollPoint();
        }
    }
    function redrawFreeBusy() {
        cn_avail_subchilds = new Array();
        cn_avail_externals = new Array();
        var allparticipants = document
                .getElementById("cnavail_participants_names");
        var alllines = document.getElementById("cnavail_freebusy_content");
        removeChildNodes(alllines);
        removeChildNodes(allparticipants);
        var mytemplate = document.getElementById("cnavail_template_line");
        if (calendar_new_availability_start_time.getKey() != -1) {
            var templatedatestart = parseDateString(
                    calendar_new_availability_start_time.getKey(), "time");
        } else {
            var templatedatestart = parseDateString(
                    $("newappointment_begins_time_text").value, "time");
        }
        if (calendar_new_availability_end_time.getKey() != -1) {
            var templatedateend = parseDateString(
                    calendar_new_availability_end_time.getKey(), "time");
        } else {
            var templatedateend = parseDateString(
                    $("newappointment_ends_time_text").value, "time");
        }
        var mystarttime = templatedatestart.getUTCHours();
        var myendtime = templatedateend.getUTCHours();
        if (templatedateend.getUTCMinutes() > 0) {
            myendtime++;
        }
        var times = mytemplate.getElementsByTagName("div");
        for ( var i = 0; i < times.length; i++) {
            if (mystarttime <= i && i < myendtime) {
                times[i].className = "cnavailchecktime border-color-design availabilityAppointmentBackground";
            } else {
                times[i].className = "cnavailoutofcheck border-color-design offTimeBackground";
            }
        }
        for ( var i = 0; i < users.length; i++) {
            cnavail_drawnewLineFreeBusy("USER", users[i])
        }
        for ( var i = 0; i < groups.length; i++) {
            cnavail_drawnewLineFreeBusy("GROUP", groups[i])
        }
        for ( var i = 0; i < ressource.length; i++) {
            cnavail_drawnewLineFreeBusy("RESSOURCE", ressource[i]);
        }
        for ( var i = 0; i < externalusers.length; i++) {
            cnavail_drawnewLineFreeBusy("EXTERNAL", externalusers[i]);
        }
        cnavail_doResolveGroups(resolvegroups);
        cnavail_doShowExternalParticipants(externalparticipants);
        calendar_new_availability_do_nothing = false;
        setScrollPoint();
        setTimeout(cnavail_resizeParticipantScroller, 0); // resize if
                                                            // scroller is
                                                            // available
    }
}

function cnavail_resizeParticipantScroller() {
    var ph = parseInt($("cnavail_participants_scroller").clientHeight);
    var ah = parseInt($("cnavail_scroller").clientHeight);
    if (ph != ah)
        $("cnavail_participants_names_spacer").style.height = ph - ah + "px";
}

var superzaehler2 = 1;
function cnavail_drawnewLineFreeBusy(linetype, object) {

    var allparticipants = document.getElementById("cnavail_participants_names");
    var alllines = document.getElementById("cnavail_freebusy_content");
    var newparticipant;
    switch (linetype) {
    case "GROUP":
        newparticipant = document.getElementById("cnavail_template_name")
                .cloneNode(true);
        var newline = document.getElementById("cnavail_template_line")
                .cloneNode(true);
        newparticipant.getElementsByTagName("td")[4].style.display = "none";
        newparticipant.getElementsByTagName("td")[3].style.display = "none";
        newparticipant.getElementsByTagName("td")[2].style.display = "none";
        newparticipant.getElementsByTagName("td")[1].style.display = "";
        newparticipant.getElementsByTagName("td")[0].style.display = "none";

        newparticipant.getElementsByTagName("div")[5].firstChild.nodeValue = object.display_name;
        newparticipant.getElementsByTagName("div")[5].color = "#C0C0C0";
        allparticipants.appendChild(newparticipant, false);
        alllines.appendChild(newline);

        for (i5 = 0; i5 < object.members.length; i5++) {

            newparticipant = document.getElementById("cnavail_template_name")
                    .cloneNode(true);
            var newline2 = document.getElementById("cnavail_template_line")
                    .cloneNode(true);
            newparticipant.getElementsByTagName("td")[4].style.display = "none";
            newparticipant.getElementsByTagName("td")[3].style.display = "";
            newparticipant.getElementsByTagName("td")[2].style.display = "none";
            newparticipant.getElementsByTagName("td")[1].style.display = "none";
            newparticipant.getElementsByTagName("td")[0].style.display = "none";
            internalCache
                    .getUsers(
                            [ object.members[i5] ],
                            function(resp) {
                                newparticipant.getElementsByTagName("div")[5].firstChild.nodeValue = resp[object.members[i5]].display_name;
                            });

            allparticipants.appendChild(newparticipant);
            cn_avail_subchilds.push(newparticipant);
            cn_avail_subchilds.push(newline2);
            appendFreeBusy(newline2, [ object.members[i5] ], true);
            alllines.appendChild(newline2);
        }
        appendFreeBusy(newline, object.members);
        break;
    case "USER":
        newparticipant = document.getElementById("cnavail_template_name")
                .cloneNode(true);
        newline = document.getElementById("cnavail_template_line").cloneNode(
                true);
        newparticipant.getElementsByTagName("td")[4].style.display = "none";
        newparticipant.getElementsByTagName("td")[3].style.display = "none";
        newparticipant.getElementsByTagName("td")[2].style.display = "none";
        newparticipant.getElementsByTagName("td")[1].style.display = "none";
        newparticipant.getElementsByTagName("td")[0].style.display = "";
        newparticipant.getElementsByTagName("div")[5].firstChild.nodeValue = object.display_name;
        allparticipants.appendChild(newparticipant);
        appendFreeBusy(newline, [ object.id ], false);
        alllines.appendChild(newline);
        break;
    case "RESSOURCE":
        newparticipant = document.getElementById("cnavail_template_name")
                .cloneNode(true);
        newline = document.getElementById("cnavail_template_line").cloneNode(
                true);
        newparticipant.getElementsByTagName("td")[4].style.display = "none";
        newparticipant.getElementsByTagName("td")[3].style.display = "none";
        newparticipant.getElementsByTagName("td")[2].style.display = "";
        newparticipant.getElementsByTagName("td")[1].style.display = "none";
        newparticipant.getElementsByTagName("td")[0].style.display = "none";
        newparticipant.getElementsByTagName("div")[5].firstChild.nodeValue = object.display_name;
        allparticipants.appendChild(newparticipant);

        appendFreeBusy(newline, [ object.id ], false);
        alllines.appendChild(newline);
        break;
    case "EXTERNAL":
        newparticipant = document.getElementById("cnavail_template_name")
                .cloneNode(true);
        newline = document.getElementById("cnavail_template_line").cloneNode(
                true);
        newparticipant.getElementsByTagName("td")[4].style.display = "";
        newparticipant.getElementsByTagName("td")[3].style.display = "none";
        newparticipant.getElementsByTagName("td")[2].style.display = "none";
        newparticipant.getElementsByTagName("td")[1].style.display = "none";
        newparticipant.getElementsByTagName("td")[0].style.display = "none";
        newparticipant.getElementsByTagName("div")[5].firstChild.nodeValue = object.display_name;
        allparticipants.appendChild(newparticipant);
        alllines.appendChild(newline);
        removeChildNodes(newline.getElementsByTagName("div")[0]);
        cn_avail_externals.push(newparticipant);
        cn_avail_externals.push(newline);
        break;
    }

    function appendFreeBusy(node, ids, issub) {

        var insertfreebusy = node.getElementsByTagName("div")[0];
        removeChildNodes(insertfreebusy);
        for (zaehler7 = 0; zaehler7 < ids.length; zaehler7++) {
            if (!calendar_new_availability_objects.users[ids[zaehler7]]) {
                return;
            }
            for (zaehler2 = 0; zaehler2 < calendar_new_availability_objects.users[ids[zaehler7]].length; zaehler2++) {
                var data1 = calendar_new_availability_objects.users[ids[zaehler7]][zaehler2];
                // TODO : REMOVE THIS APPOINTMENT
                var sdt = new Date(data1["start_date"]);
                if (sdt.getTime() < checkdate.getTime()) {
                    sdt = new Date(checkdate.getTime());
                } else if (sdt >= checkdate.getTime() + (1000 * 60 * 60 * 24)) {
                    continue;
                }
                var edt = new Date(data1["end_date"]);
                if (edt >= checkdate.getTime() + (1000 * 60 * 60 * 24)) {
                    edt = new Date(checkdate.getTime() + (1000 * 60 * 60 * 24));
                } else if (edt <= checkdate.getTime()) {
                    continue;
                }
                var longstart = (sdt % (1000 * 60 * 60 * 24));
                var startpoint = Math.round(longstart / (1000 * 60 * 15));
                var longend = (edt % (1000 * 60 * 60 * 24));
                var endpoint = Math.round(longend / (1000 * 60 * 15));
                if (endpoint == 0) {
                    endpoint = 4 * 24;
                }
                var newfreebusy = document.getElementById(
                        "cnavail_freebusy_template").cloneNode(false);
                removeChildNodes(newfreebusy);
                newfreebusy.id = ids[zaehler7] + "-" + zaehler2 + "-"
                        + superzaehler2++;
                newfreebusy.ox_user = ids[zaehler7];
                newfreebusy.ox_app_id = zaehler2;

                newfreebusy.style.left = (startpoint * 15) + "px";
                newfreebusy.style.width = ((endpoint - startpoint) * 15) + "px";
                switch (data1.shown_as) {
                case 1:
                    newfreebusy.className = "cnavailreserved";
                    insertfreebusy.appendChild(newfreebusy);
                    break;
                case 2:
                    newfreebusy.className = "cnavailtemporary";
                    insertfreebusy.appendChild(newfreebusy);
                    break;
                case 3:
                    newfreebusy.className = "cnavailoccupied";
                    insertfreebusy.appendChild(newfreebusy);
                    break;
                case 4:
                    newfreebusy.className = "cnavailfree";
                    insertfreebusy.appendChild(newfreebusy);
                    break;
                }
            }
        }
    }
}

function cnavail_doResolveGroups(resolve) {
    for (i = 0; i < cn_avail_subchilds.length; i++) {
        (resolve) ? cn_avail_subchilds[i].style.display = ""
                : cn_avail_subchilds[i].style.display = "none";
    }
}
function cnavail_doShowExternalParticipants(resolve) {
    for (i = 0; i < cn_avail_externals.length; i++) {
        (resolve) ? cn_avail_externals[i].style.display = ""
                : cn_avail_externals[i].style.display = "none";
    }
}
function cnavail_scroll() {
    var scroll1 = document.getElementById("cnavail_scroller");
    document.getElementById("cnavail_participants_scroller").scrollTop = (scroll1.scrollTop);
    document.getElementById("cnavail_timeline_scroller").scrollLeft = (scroll1.scrollLeft);
}
function calendar_new_availability_checkAppointmentTime() {

    calendar_new_availability_check_date = calendar_new_availability_check_date2;
    if (!calendar_new_availability_do_nothing) {
        cn_avail_updateHeaderTime();
        calendar_new_availability_checkFreebusy(true);
    }
    calendar_resize_first = true;
}
function optimizeFreeBusy(objecttooptimize) {
    var returnobject = new Object();
    returnobject["objects"] = new Array();
    returnobject["request"] = new Array();
    var keys = objecttooptimize["objects"];
    var values = objecttooptimize["request"];
    var usersk = new Object();
    var ressourcek = new Object();
    var usersv = new Object();
    var ressourcev = new Object();
    for (i = 0; i < keys.length; i++) {
        switch (keys[i].type) {
        case 1:
            usersk[keys[i].id] = keys[i];
            usersv[keys[i].id] = values[i];
            break;
        case 3:
            ressourcek[keys[i].id] = keys[i];
            ressourcev[keys[i].id] = values[i];
        }
    }
    for (i2 in ressourcek) {
        returnobject["objects"].push(ressourcek[i2]);
        returnobject["request"].push(ressourcev[i2]);
    }

    for (i2 in usersk) {
        returnobject["objects"].push(usersk[i2]);
        returnobject["request"].push(usersv[i2]);
    }
    return returnobject;
}