var AIRTIME = (function(AIRTIME){
    var mod;
    
    if (AIRTIME.schedule === undefined) {
        AIRTIME.schedule = {};
    }
    mod = AIRTIME.schedule;
    
    return AIRTIME;
    
}(AIRTIME || {}));

var serverTimezoneOffset = 0;

function closeDialogCalendar(event, ui) {
    
    $el = $(this);
    $el.dialog('destroy');
    $el.remove();
    
    //need to refetch the events to update scheduled status.
    $("#schedule_calendar").fullCalendar( 'refetchEvents' );
}

function confirmCancelShow(show_instance_id){
    if (confirm($.i18n._('Cancel Current Show?'))) {
        var url = baseUrl+"Schedule/cancel-current-show";
        $.ajax({
            url: url,
            data: {format: "json", id: show_instance_id},
            success: function(data){
                scheduleRefetchEvents(data);
            }
        });
    }
}

function confirmCancelRecordedShow(show_instance_id){
    if (confirm($.i18n._('Stop recording current show?'))) {
        var url = baseUrl+"Schedule/cancel-current-show";
        $.ajax({
            url: url,
            data: {format: "json", id: show_instance_id},
            success: function(data){
                scheduleRefetchEvents(data);
            }
        });
    }
}

function findViewportDimensions() {
    var viewportwidth,
        viewportheight;
    
    // the more standards compliant browsers (mozilla/netscape/opera/IE7) use
    // window.innerWidth and window.innerHeight
    if (typeof window.innerWidth != 'undefined') {
        viewportwidth = window.innerWidth, viewportheight = window.innerHeight;
    }
    // IE6 in standards compliant mode (i.e. with a valid doctype as the first
    // line in the document)
    else if (typeof document.documentElement != 'undefined'
            && typeof document.documentElement.clientWidth != 'undefined'
            && document.documentElement.clientWidth != 0) {
        viewportwidth = document.documentElement.clientWidth;
        viewportheight = document.documentElement.clientHeight;
    }
    // older versions of IE
    else {
        viewportwidth = document.getElementsByTagName('body')[0].clientWidth;
        viewportheight = document.getElementsByTagName('body')[0].clientHeight;
    }
    
    return {
        width: viewportwidth,
        height: viewportheight-45
    };
}

function highlightMediaTypeSelector(dialog) {
    var selected;
    if (location.hash === "") {
        selected = dialog.find("a[href$='#tracks']");
    } else {
        selected = dialog.find("a[href$='"+location.hash+"']")
    }

    selected.parent().addClass("selected");
    $("#library_filter").text(selected.text());

    // Slightly hacky way of triggering the click event when it's outside of the anchor text
    dialog.find(".media_type_selector").on("click", function() {
        // Need get(0) here so we don't create a stack overflow by recurring the click on the parent
        $(this).find("a").get(0).click();
    });

    $(window).on('hashchange', function() {
        var selected = dialog.find("a[href$='"+location.hash+"']");
        AIRTIME.library.selectNone();
        dialog.find(".media_type_selector").each(function () {
            $(this).removeClass("selected");
        });
        $("#library_filter").text(selected.text());
        selected.parent().addClass("selected");
        oTable.fnDraw();
    });
}

function buildTimerange(dialog) {
    var builder = dialog.find("#show_builder"),
        oBaseDatePickerSettings = {
            dateFormat: 'yy-mm-dd',
            //i18n_months, i18n_days_short are in common.js
            monthNames: i18n_months,
            dayNamesMin: i18n_days_short,
            onClick: function(sDate, oDatePicker) {
                $(this).datepicker("setDate", sDate);
            },
            onClose: validateTimeRange
        },
        oBaseTimePickerSettings = {
            showPeriodLabels: false,
            showCloseButton: true,
            closeButtonText: $.i18n._("Done"),
            showLeadingZero: false,
            defaultTime: '0:00',
            hourText: $.i18n._("Hour"),
            minuteText: $.i18n._("Minute"),
            onClose: validateTimeRange
        };

    /*
     * Icon hover states for search.
     */
    builder.on("mouseenter", ".sb-timerange .ui-button", function(ev) {
        $(this).addClass("ui-state-hover");
    });
    builder.on("mouseleave", ".sb-timerange .ui-button", function(ev) {
        $(this).removeClass("ui-state-hover");
    });

    builder.find(dateStartId)
        .datepicker(oBaseDatePickerSettings);
    builder.find(timeStartId)
        .timepicker(oBaseTimePickerSettings);
    builder.find(dateEndId)
        .datepicker(oBaseDatePickerSettings);
    builder.find(timeEndId)
        .timepicker(oBaseTimePickerSettings);

    var oRange = AIRTIME.utilities.fnGetScheduleRange(dateStartId, timeStartId,
        dateEndId, timeEndId);
    AIRTIME.showbuilder.fnServerData.start = oRange.start;
    AIRTIME.showbuilder.fnServerData.end = oRange.end;
}

function buildScheduleDialog (json, instance_id) {
    var dialog = $(json.dialog),
        viewport = findViewportDimensions(),
        height = Math.floor(viewport.height * 0.96),
        width = Math.floor(viewport.width * 0.96),
        fnServer = AIRTIME.showbuilder.fnServerData;

    dialog.dialog({
        autoOpen: false,
        title: json.title,
        width: width,
        height: height,
        resizable: false,
        draggable: true,
        modal: true,
        close: closeDialogCalendar,
        buttons: [
            {
                text: $.i18n._("Ok"),
                class: "btn",
                click: function() {
                    $(this).dialog("close");
                    //getUsabilityHint();
                }
            }
        ]
    });

    //set the start end times so the builder datatables knows its time range.
    fnServer.start = json.start;
    fnServer.end = json.end;
    fnServer.ops = {};
    fnServer.ops.showFilter = 0;
    fnServer.ops.showInstanceFilter = instance_id;
    fnServer.ops.myShows = 0;
    
    AIRTIME.library.libraryInit();
    AIRTIME.showbuilder.builderDataTable();
    
    dialog.dialog('open');
    highlightMediaTypeSelector(dialog);
    buildTimerange(dialog);
}

function buildContentDialog (json){
    var dialog = $(json.dialog),
        viewport = findViewportDimensions(),
        height = viewport.height * 2/3,
        width = viewport.width * 4/5;
    
    if (json.show_error == true){
        alertShowErrorAndReload();
    }
          
    dialog.find("#show_progressbar").progressbar({
        value: json.percentFilled
    });
     
    dialog.dialog({
        autoOpen: false,
        title: $.i18n._("Contents of Show") +" '" + json.showTitle + "'",
        width: width,
        height: height,
        modal: true,
        close: closeDialogCalendar,
        buttons: [
            {
                text: $.i18n._("Ok"),
                "class": "btn",
                click: function() {
                    dialog.remove();
                }
            }
        ]
    });

    dialog.dialog('open');
}

/**
 * Use user preference for time scale; defaults to month if preference was never set
 */
function getTimeScalePreference(data) {
    return data.calendarInit.timeScale;
}

/**
 * Use user preference for time interval; defaults to 30m if preference was never set
 */
function getTimeIntervalPreference(data) {
    return parseInt(data.calendarInit.timeInterval);
}

function createFullCalendar(data){

    serverTimezoneOffset = data.calendarInit.timezoneOffset;

    var mainHeight = $(window).height() - 200 - 35;

    $('#schedule_calendar').fullCalendar({
        header: {
            left: 'prev, next, today',
            center: 'title',
            right: 'agendaDay, agendaWeek, month'
        }, 
        defaultView: getTimeScalePreference(data),
        slotMinutes: getTimeIntervalPreference(data),
        firstDay: data.calendarInit.weekStartDay,
        editable: false,
        allDaySlot: false,
        axisFormat: 'H:mm',
        timeFormat: {
            agenda: 'H:mm{ - H:mm}',
            month: 'H:mm{ - H:mm}'
        },
        //i18n_months is in common.js
        monthNames: i18n_months,
        monthNamesShort: [
            $.i18n._('Jan'),
            $.i18n._('Feb'),
            $.i18n._('Mar'),
            $.i18n._('Apr'),
            $.i18n._('May'),
            $.i18n._('Jun'),
            $.i18n._('Jul'),
            $.i18n._('Aug'),
            $.i18n._('Sep'),
            $.i18n._('Oct'),
            $.i18n._('Nov'),
            $.i18n._('Dec')
        ],
        buttonText: {
            today: $.i18n._('Today'),
            month: $.i18n._('Month'),
            week: $.i18n._('Week'),
            day: $.i18n._('Day')
        },
        dayNames: [
            $.i18n._('Sunday'),
            $.i18n._('Monday'),
            $.i18n._('Tuesday'),
            $.i18n._('Wednesday'),
            $.i18n._('Thursday'),
            $.i18n._('Friday'),
            $.i18n._('Saturday')
        ],
        dayNamesShort: [
            $.i18n._('Sun'),
            $.i18n._('Mon'),
            $.i18n._('Tue'),
            $.i18n._('Wed'),
            $.i18n._('Thu'),
            $.i18n._('Fri'),
            $.i18n._('Sat')
        ],
        contentHeight: mainHeight,
        theme: true,
        lazyFetching: true,
        serverTimestamp: parseInt(data.calendarInit.timestamp, 10),
        serverTimezoneOffset: parseInt(data.calendarInit.timezoneOffset, 10),
       
        events: getFullCalendarEvents,

        //callbacks (in full-calendar-functions.js)
        viewDisplay: viewDisplay,
        dayClick: dayClick,
        eventRender: eventRender,
        eventAfterRender: eventAfterRender,
        eventDrop: eventDrop,
        eventResize: eventResize,
        windowResize: windowResize
    });
}

//Alert the error and reload the page
//this function is used to resolve concurrency issue
function alertShowErrorAndReload(){
    alert($.i18n._("The show instance doesn't exist anymore!"));
    window.location.reload();
}

$(document).ready(function() {

    $.contextMenu({
        selector: 'div.fc-event',
        trigger: "left",
        ignoreRightClick: true,
        className: 'calendar-context-menu',
        
        build: function($el, e) {
            var data, 
                items, 
                callback;
            
            data = $el.data("event");
            
            function processMenuItems(oItems) {
                
                //define a schedule callback.
                if (oItems.schedule !== undefined) {
                    
                    callback = function() {
                        $.post(oItems.schedule.url, {format: "json", id: data.id}, function(json){
                            buildScheduleDialog(json, data.id);
                        });
                    };
                    
                    oItems.schedule.callback = callback;
                }
                
                //define a clear callback.
                if (oItems.clear !== undefined) {
                    
                    callback = function() {
                        if (confirm($.i18n._("Remove all content?"))) {
                            $.post(oItems.clear.url, {format: "json", id: data.id}, function(json){
                                scheduleRefetchEvents(json);
                            });
                        }
                    };
                    oItems.clear.callback = callback;
                }
                
                //define an edit callback.
                if (oItems.edit !== undefined) {
                    if(oItems.edit.items !== undefined){
                        var edit = oItems.edit.items;
                        
                        
                        //edit a single instance
                        callback = function() {
                            $.get(edit.instance.url, {format: "json", showId: data.showId, instanceId: data.id, type: "instance"}, function(json){
                                beginEditShow(json);
                            });
                        };
                        edit.instance.callback = callback;
                        
                        //edit this instance and all
                        callback = function() {
                            $.get(edit.all.url, {format: "json", showId: data.showId, instanceId: data.id, type: "all"}, function(json){
                                beginEditShow(json);
                            });
                        };
                        edit.all.callback = callback;
                    }else{
                        callback = function() {
                            $.get(oItems.edit.url, {format: "json", showId: data.showId, instanceId: data.id, type: oItems.edit._type}, function(json){
                                beginEditShow(json);
                            });
                        };
                        oItems.edit.callback = callback;
                    }
                }

                //define a content callback.
                if (oItems.content !== undefined) {
                    
                    callback = function() {
                        $.get(oItems.content.url, {format: "json", id: data.id}, function(json){
                            buildContentDialog(json);
                        });
                    };
                    oItems.content.callback = callback;
                }
                
                //define a cancel recorded show callback.
                if (oItems.cancel_recorded !== undefined) {
                    
                    callback = function() {
                        confirmCancelRecordedShow(data.id);
                    };
                    oItems.cancel_recorded.callback = callback;
                }
                
                //define a view recorded callback.
                if (oItems.view_recorded !== undefined) {
                    callback = function() {
                        $.get(oItems.view_recorded.url, {format: "json"}, function(json){
                            //in library.js
                            buildEditMetadataDialog(json);
                        });
                    };
                    oItems.view_recorded.callback = callback;
                }
                
                //define a cancel callback.
                if (oItems.cancel !== undefined) {
                    
                    callback = function() {
                        confirmCancelShow(data.id);
                    };
                    oItems.cancel.callback = callback;
                }
                
                //define a delete callback.
                if (oItems.del !== undefined) {
                    
                    //repeating show multiple delete options
                    if (oItems.del.items !== undefined) {
                        var del = oItems.del.items;
                        
                        //delete a single instance
                        callback = function() {
                            $.post(del.single.url, {format: "json", id: data.id}, function(json){
                                scheduleRefetchEvents(json);
                            });
                        };
                        del.single.callback = callback;
                        
                        //delete this instance and all following instances.
                        callback = function() {
                            $.post(del.following.url, {format: "json", id: data.id}, function(json){
                                scheduleRefetchEvents(json);
                            });
                        };
                        del.following.callback = callback;  
                        
                    }
                    //single show
                    else {
                        callback = function() {
                            $.post(oItems.del.url, {format: "json", id: data.id}, function(json){
                                scheduleRefetchEvents(json);
                            });
                        };
                        oItems.del.callback = callback; 
                    }
                }
            
                items = oItems;
            }

            $.ajax({
              url: baseUrl+"schedule/make-context-menu",
              type: "GET",
              data: {instanceId : data.id, showId: data.showId, format: "json"},
              dataType: "json",
              async: false,
              success: function(json){
                  processMenuItems(json.items);
              }
            });

            return {
                className: 'calendar-context-menu',
                items: items,
                determinePosition : function($menu, x, y) {
                    $menu.css('display', 'block')
                        .position({ my: "left top", at: "right top", of: this, offset: "-20 10", collision: "fit"})
                        .css('display', 'none');
                }
            };
        }
    });
});
