/*
 * In this document:
 * 
 * - Namespaces
 * - Init
 * - General functions
 * - jQuery UI dialog functions
 * - Contextual menu functions
 * - Specific right-click menus for tables
 * - Project crew/rentals functions
 * - General calendar interaction functions
 * - General call sheet interaction functions
 * - General workbook interaction functions 
 * - General project booking interaction function
 * - General sharing functions
 * - General profile sharingNew window warning
 * - onDOMReady code
 * 
 */


/*------------------------------------
 * Namespaces
 *------------------------------------*/

function qc(){}
qc.vars = {};


/*------------------------------------
 * Init
 *------------------------------------*/

// Width of a minical cell
qc.vars.minicalCellWidth = 37;

// Dialog defaults
$.ui.dialog.defaults.resizable = false;
$.ui.dialog.defaults.modal = true;
$.ui.dialog.defaults.width = 355;
// $.ui.dialog.defaults.maxHeight = $(window).height() - 20;
$.ui.dialog.defaults.close = function(){
    // Close current UI calendars
    $(".hasDatepicker").datepicker('hide',0);
};

// Date picker defaults
qc.currentUICalendar = null;
$.datepicker.setDefaults({
    dateFormat: "dd.mm.yy",
    firstDay: 1
});

// Make sure dialogs reposition when the window resizes or scrolls
$(window).resize(function(){
    $(".ui-dialog")
        .each(qc.reCenterDialog);
});
$(window).scroll(function(){
    $(".ui-dialog")
        .each(qc.reCenterDialog);
});

// If a contextual menu is showing or not
qc.vars.contextShowing = false;

// Hide menus if we click anywhere in the document
$(document).click( function(e) {
    var t = e.target ? e.target : e.srcElement;
    if(qc.vars.contextShowing == true){
        // Make sure it wasn't a click inside the menu
        if($(t).parents("#contextMenu").size() == 0){
            qc.hideContextMenu();
            return false;
        }
    }
    if($(t).parents("#main_menu").size() == 0){
        qc.closeMainMenus();
    }
});


/*------------------------------------
 * General functions
 *------------------------------------*/

qc.stripTags = function(string)
{
    return string.replace(/<\/?[^>]+>/gi, "");
}

qc.togglePanel = function(elem_to_toggle)
{
     // Toggle panel
     elem_to_toggle
         .slideToggle();
     
     // Check if there's a date, and if so toggle it
     elem_to_toggle
         .parent("div")
         .find(".planner_footer_year")
         .slideToggle();
}

qc.closeMainMenus = function(){
    var menu_container = $('ul.sf-menu');
    if(menu_container.size()){
        menu_container.hideSuperfishUl();
    }
}

qc.resizeContentFrame = function(){
    var newHeight = $(window).height() - qc.vars.fixedElementsHeight;
    $('#content_frame')
        .height(newHeight)
        .css("display","block");
}

qc.generateRandomId = function(){
    var chars = "0123456789abcdefghiklmnopqrstuvwxyz";
    var string_length = 8;
    var randomstring = 'random_id_';
    for (var i=0; i<string_length; i++) {
        var rnum = Math.floor(Math.random() * chars.length);
        randomstring += chars.substring(rnum,rnum+1);
    }
    return randomstring;
}

qc.reCenterDialog = function(){   
    // Make sure it's not too high
    if($(this).height() > $(window).height() - 50){
        $(this).height($(window).height() - 50);
        var toolbar_height = 66;
        var dialog_content = $(this).find(".ui-dialog-content");
        dialog_content.height($(this).height() - toolbar_height);
    }

    // Re-center
    var new_y = 0;
    var new_x = 0;
    
    new_y=($(window).height()- $(this).height())/2;
    new_y=$(document).scrollTop()+new_y;
    
    new_x=($(window).width()- $(this).width())/2;
       
    $(this)
        .css({
            top: new_y + "px",
            left: new_x + "px"
        });
        
}

qc.toggleInstructions = function(elem_clicked)
{
    // First loop up to the .panel
    var panel = $(elem_clicked).parents(".panel");
    
    if(panel.size()){
        
        var instructions = panel.find(".instructions");
        var instructions_link = panel.find(".show_instructions a");
        
        // Check if the instructions are showing
        if(instructions.css("display") == "none"){
            
            instructions_link
                .html("Hide instructions");
            
        } else {
            
            instructions_link
                .html("Instructions");
            
        }
        
        instructions
            .slideToggle();
        
    }
    
}

qc.initSelectableTableRows = function()
{
    $("tbody.selectable_rows tr.visible_row, tbody.selectable_secondary_rows tr.visible_row")
        .bind("contextmenu",qc.selectTableRow)
        .click(qc.selectTableRow);

    // Specific tables' click functions
    $("#project_crew_table tbody, #project_crew_table_bookings tbody, #project_crew_table_invites tbody, #project_rentals_table tbody, #project_rentals_table_bookings tbody, #project_rentals_table_invites tbody, tbody.selectable_secondary_rows, #project_crew_table_view_only tbody, #project_rentals_table_view_only tbody, tbody.booking_preview_table")
        .find("tr.visible_row")
        .bind("contextmenu",qc.tableRightClickMenu)
        .bind("dblclick", function(e){
            if (this.tagName != 'A') {
                qc.tableToggleNextRow($(this));
                return false;
            }
        });
    
    // Hovers
    $('table.listing tbody.selectable_rows tr')
	    .mouseover(function() {
	        $(this).addClass('ruler');
	    })
	    .mouseout(function() {
	        $(this).removeClass('ruler');
	    });

}

qc.tableToggleNextRow = function(this_row)
{
    if(typeof(this_row) == "object"){
        this_row
            .next("tr")
            .filter(function(){
                // Only toggle hidden rows
                if($(this).hasClass("hidden_row")){
                    return true;
                }
                return false;
            })
            .toggle()
            .each(function(){
                if($(this).css("display") != 'none'){
                    $(this)
                        .addClass("opened_bottom")
                        .show()
                        .prev("tr")
                        .addClass("opened_top");
                } else {
                    $(this)
                    .removeClass("opened_bottom")
                    .hide()
                    .prev("tr")
                    .removeClass("opened_top");
                }
            });
    }
    
    qc.hideContextMenu();
    qc.closeMainMenus();
}

        
qc.selectTableRow = function(e)
{
    var secondary_table = $(".selectable_secondary_rows");
    if(secondary_table.size() > 0){
        
        // Two tables
        
        // Get row index no.
        var count = 0;
        var current_row = $(this);
        while(current_row.prev().size() > 0){
            count++;
            current_row = current_row.prev();
        }
        
        // Are we in the left or right table?
        var my_parent_div = $(this)
                                .parents("table")
                                .parent();
        if(my_parent_div.hasClass("table_right")){
            var left_div = my_parent_div
                                .prev(".table_left");
            var right_div = my_parent_div;
        } else {
            var right_div = my_parent_div
                                .next(".table_right");
            var left_div = my_parent_div;
        }
                    
        // Uncheck all, then check the right one
        left_div
            .find("tr")
            .removeClass("selected")
            .end()
            .find("tr:nth-child(" + (count+1) + ")")
            .addClass("selected");
        
        // Add selected class to right row on the right
        right_div
            .find("tr")
            .removeClass("selected")
            .end()
            .find("tr:nth-child(" + (count+1) + ")")
            .addClass("selected");
        
    } else {
    
        // Single table
        
        var tbody = $(this).parent("tbody");
        tbody
            .find("tr")
            .removeClass("selected");
        
        $(this) 
            .addClass("selected");
        
    }
    
}

qc.markAsFavourite = function(container_id, favourite_type, fa_status)
{
    qc.hideContextMenu();

    // Try and get container
    var container = $("#" + container_id);
    if(container.size() == 0){
        qc.dialogError(undefined, "Couldn't find container " + container_id + "!");
        return false;
    }
    
    // Get selected row
    var row = qc.tableGetSelectedRow(container);
    if(row){
    
        // Manually added crew?
        if(row.hasClass("manually_added")){
            qc.dialogError(undefined, "Sorry, you can't mark manually added items.");
            return false;
        }
        
        // Try and get favourite_obj_id
        var favourite_container = row.find(".favourite_container");
        if(favourite_container.size() == 0){
            qc.dialogError(undefined, "Couldn't find favourite container for " + container_id + "!");
            return false;
        }
        var fa_favourite_obj_id = favourite_container.attr("id").replace(/fa_favourite_obj_id_/, "");
        
            
        qc.markAsFavouriteGenericFunction(favourite_type, fa_status, fa_favourite_obj_id, favourite_container);
    }

}

qc.markAsFavouriteLink = function(fa_favourite_obj_id, favourite_type, fa_status) {   
    var pars = {
        opt: 'mark_as_favourite',
        fa_obj_type: favourite_type,
        fa_status: fa_status,
        fa_favourite_obj_id: fa_favourite_obj_id
    };

    $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
        qc.markAsFavouriteResponse(data, $("#fa_favourite_obj_id_" + fa_favourite_obj_id));
    });        
    
}

qc.markAsFavouriteGenericFunction = function(favourite_type, fa_status, fa_favourite_obj_id, favourite_container) {
    var pars = {
        opt: 'mark_as_favourite',
        fa_obj_type: favourite_type,
        fa_status: fa_status,
        fa_favourite_obj_id: fa_favourite_obj_id
    };

    $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
        qc.markAsFavouriteResponse(data, favourite_container);
    });    
}
    
qc.markAsFavouriteResponse = function(originalRequest, favourite_container)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.html) == "string"
    ) {
        
        // Refresh status star
        favourite_container.html(result.data.html);
        
    } else {
        
        // Couldn't be marked...
        qc.dialogError(undefined, "<p>" + result.message + "</p>");
        
    }
    
}

qc.collapseAllPanels = function(){
    
    $(".panel")
        .filter(function(){
            if($(this).css("display") == "none"){
                return false;
            }
            return true;
        })
        .each(function(){
            qc.togglePanel($(this));
        });
    
    // Close menus
    qc.hideContextMenu();
    qc.closeMainMenus();
    
}

qc.expandAllPanels = function(){
    
    $(".panel")
        .filter(function(){
            if($(this).css("display") != "none"){
                return false;
            }
            return true;
        })
        .each(function(){
            qc.togglePanel($(this));
        });
    
    // Close menus
    qc.hideContextMenu();
    qc.closeMainMenus();
    
}

qc.newWindowConfirm = function(link) {
    
    // Hide content menu
    qc.hideContextMenu();
     
    // Confirmation dialog
    var html = "<p>This link will open in a new window.</p>";
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Ok',opt);
    opt = {
        extra_classes: "secondary_dialog_button"
    };
    button += " " + qc.button(2,'#','Cancel',opt);
    opt = {
        cssClass: "primary"
    };
    html += qc.buttonBlock(button,opt);
   
    var title = "New Window";
    var dialog = qc.createDialogNode(html, "project_new_window");
    dialog_id = dialog.attr('id');
    dialog
        .dialog("destroy")
        .dialog({
            title: title
        })
        .find(".primary_dialog_button")
        .click(function(){
            window.open(link)
            $("#" + dialog_id)
                .dialog('close');
        })
        .focus()
        .end()
        .find(".secondary_dialog_button")
        .click(function(){
            $("#" + dialog_id)
                .dialog('close');
        })
        .focus()
        .end();
   
    return false;

}

qc.toggleDisabled = function(elem_id)
{
    var elem = $("#" + elem_id);
    if(elem.size()){
        if(elem.attr("disabled")){
            elem.removeAttr("disabled");
        } else {
            elem.attr("disabled", 'disabled');
        }
    }
}

qc.updateNews = function(timestamp) {

    var pars = {
            opt: 'au_update_news',
            time: timestamp
        };
        
    $.getJSON("/ajax-handler.php", pars, qc.updateNewsResponse);

}

qc.updateNewsResponse = function(originalRequest) {

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }

    if (result.status == 1) {
        window.location = window.location.href.substring(0, window.location.href.indexOf('?'));
    }

}

/**
 * Standard button HTML output function
 * NOTE: This function has an equivalent function in PHP called qcButton(),
 * and if the HTML of the JavaScript function is changed, the PHP function MUST be
 * updated as well.
 */
qc.button = function(type, url, button_text, opt) {

    // Default values for parameters
    if(typeof(type) == "undefined"){
        type = '1';
    }
    if(typeof(url) != "string"){
        url = '#';
    }
    if(typeof(button_text) != "string"){
        button_text = 'Submit';
    }
    if(typeof(opt) != "object"){
        opt = {};
    }

    // Get options
    var extra_classes = typeof(opt.extra_classes) != "string" ? "" : " " + opt.extra_classes;
    var onclick = typeof(opt.onclick) != "string" ? "" : "onclick='" + opt.onclick + "'";
    var id = typeof(opt.id) != "string" ? "" : "id='" + opt.id + "'";
    var title = typeof(opt.title) != "string" ? "" : "title='" + opt.title + "'";
    
    // Init HTML output
    var html = '';
    
    // Determine main class
    var button_class = '';
    if(type == '1' || type == '3'){
        button_class = 'button';
    } else if (type == '2'){
        button_class = 'secondary';
    }

    // Compile HTML string
    if(type == '3'){
        html += "<span class='" + button_class + extra_classes + "' " + id + " " + title + ">\n";
    } else {
        html += "<a href='" + url + "' class='" + button_class + extra_classes + "' " + onclick + " " + id + " " + title + ">\n";
    }

    if(type == '1' || type == '3'){
        html += "<strong>";
    }
    html += button_text;
    if(type == '1' || type == '3'){
        html += "</strong>";
    }
    
    if(type == '3'){
        html += "</span>\n";
    } else {
        html += "</a>\n";
    }

    return html;

}

/**
 * Standard button HTML output function
 * NOTE: This function has an equivalent function in PHP called qcButtonBlock(),
 * and if the HTML of the JavaScript function is changed, the PHP function MUST be
 * updated as well.
 */
qc.buttonBlock = function(string, opt)
{

     // Default values for parameters
     if(typeof(string) == "undefined"){
         string = "";
     }
     if(typeof(opt) != "object"){
         opt = {};
     }
     
     // Get options
     var cssClass = typeof(opt.cssClass) != "string" ? "" : opt.cssClass;
     var style = typeof(opt.style) != "string" ? "" : "style='" + opt.style + "'";

     // Output HTML
     return "<div class='button_block " + cssClass + "' " + style + ">" + string + "</div><!-- /.button_block -->\n";
     
}

/**
 * Start reordering mode for table rows
 */
qc.reorderEnable = function(link, tbody_id, ajax_opt)
{	
	var tbody = $("#" + tbody_id);
	if(tbody.size()){
		
		// Ajax opt set?
		if(typeof(ajax_opt) == "undefined"){
			ajax_opt = "generic_reorder_entries";
		}
		
		// Add class to table
		tbody
			.parents("table:eq(0)")
			.addClass("reordering_mode");
		
		// Hide link
		$(link)
			.hide()
			// Apply ID to hidden link so we can show it again later
			.attr("id", tbody_id + "_reorder_link");
		
		// Create save and cancel button? And a spinner?
		var save_button_id = tbody_id + "_save_button";
		var cancel_button_id = tbody_id + "_cancel_button";
		var spinner_id = tbody_id + "_spinner";
		var save_button = $("#" + save_button_id);
		var cancel_button = $("#" + cancel_button_id);
		var spinner = $("#" + spinner_id);
		if(save_button.size() == 0 && cancel_button.size() == 0 && spinner.size() == 0){
			var button_html = "<li class='no_sub'>";
			// Save
		    var opt = {
		            extra_classes: "panel_toolbar_button",
		            id: save_button_id,
		            title: "Save order",
		            onclick: "qc.reorderSave(\"" + tbody_id + "\", \"" + ajax_opt + "\"); return false;"
		        };
		    button_html += qc.button(1,'javascript: void(0);','Save reorder',opt);
		    // Spinner
		    button_html += "<img id='" + tbody_id + "_spinner' class='panel_toolbar_spinner' src='/images/panel_toolbar_spinner.gif' />";
		    // Cancel
		    var cancel_url = String(window.location).replace("#","");
		    if(cancel_url.search(/\?/) == -1){
		    	cancel_url += "?";
		    } else {
		    	cancel_url += "&amp;";
		    }
		    cancel_url += "successmsg=Reordering%20cancelled";
		    opt = {
		            extra_classes: "panel_toolbar_button",
		            id: cancel_button_id,
		            title: "Cancel reorder"
		        };
		    button_html += qc.button(2, cancel_url, 'Cancel reorder', opt);
		    button_html += "</li>";
		    // Add HTML
			$(link)
			    .parent().parent().parent()
				.after(button_html);
			// Add IDs
			save_button = $("#" + save_button_id);
			cancel_button = $("#" + cancel_button_id);
		}
		
		// Fade in save and cancel button
		save_button.fadeOut(0).fadeIn();
		cancel_button.fadeOut(0).fadeIn();

		// Make draggable
		tbody
			.sortable('destroy')
			.sortable({
				items: 'tr.sortable',
				axis: 'y',
	            cursor: 'move',
	            revert: true,
	            forcePlaceholderSize: true,
	            placeholder: "drag_placeholder",
	            start: function(even, ui) {
					$(".drag_placeholder")
						.html("<td colspan='1000'>&nbsp;</td>");
				},
	            stop: function(event, ui) {
					
					/*
	                // Re-stripe
	                $(this)
	                    .children("tr")
	                    .removeClass("stripe")
	                    .end()
	                    .find("tr:odd")
	                    .addClass("stripe");
	                
	                // Get section ID
	                var css_id = $(this)
	                                .parent("table")
	                                .attr("id")
	                                .replace(/css_/, '');
					*/

	            }
			})
			.disableSelection();
		
	}
}

/**
 * Saving reordered records
 */
qc.reorderSave = function(tbody_id, ajax_opt)
{
    
	// Ajax opt set?
	if(ajax_opt == "undefined" || typeof(ajax_opt) == "undefined"){
		ajax_opt = "generic_reorder_entries";
	}
	
	var tbody = $("#" + tbody_id);
	if(tbody.size()){
				
		// Start spinner
		$("#" + tbody_id + "_spinner")
			.show();
		$("#" + tbody_id + "_save_button")	
			.hide();
		$("#" + tbody_id + "_cancel_button")	
			.hide();
		
	    // Get new order
	    var new_order = "";
	    $(tbody)
	        .find("tr.sortable")
	        .each(function(){
	            
	            var tr_id = $(this)
	                            .attr("id");
	            new_order += tr_id + "|"; // Pipe separated id values in order...
	            
	        });
	    
	    // Fire off Ajax to save new order
	    var pars = {
	            opt: ajax_opt,
	            tbody_id: tbody_id,
	            new_order: new_order
	        };
	    $.post("/ajax-handler.php", pars, function(data, something){
	    	qc.reorderSaveResponse(data, tbody);
	    }, "json");
	    
	}
	
}

qc.reorderSaveResponse = function(originalRequest, tbody)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        /*
         * Turn off reordering mode
         */
    	
    	// Get tbody id
    	var tbody_id = tbody.attr("id");
    	
    	// Stop dragging
		tbody
			.sortable('destroy');
    	
		// Remove class from table
		tbody
			.parents("table:eq(0)")
			.removeClass("reordering_mode");
		
		// Hide save and cancel buttons and spinner
		$("#" + tbody_id + "_save_button")
			.hide();
		$("#" + tbody_id + "_cancel_button")
			.hide();
		$("#" + tbody_id + "_spinner")
			.hide();
				
		// Show reorder link
		$("#" + tbody_id + "_reorder_link")
			.fadeIn("3000");
    	
        return;
        
    } else {
        
    	// Show save and cancel button, hide spinner
		$("#" + tbody_id + "_spinner")
			.hide();
		$("#" + tbody_id + "_save_button")	
			.show();
		$("#" + tbody_id + "_cancel_button")	
			.show();
    	
        // Reorder didn't work
        var error = result.message;
        qc.dialogError(undefined,error);
        
    }
}

/*------------------------------------
 * jQuery UI dialog functions
 *------------------------------------*/

qc.createDialogNode = function(html,id)
{
     if(typeof(id) == 'undefined'){
         id = qc.generateRandomId();
     } else {
     
         // Check if it already exists
         var existing = $("#" + id);
         if(existing.size()){
             return existing.html(html);
         }
         
     }
          
     return $("<div>" + html + "</div>").attr("id",id).hide();
}
 
qc.dialogLoading = function(dialog_or_id, text)
{
    if(typeof(text) == "undefined"){
        text = "Loading...";
    }
    if(typeof(dialog_or_id) == "string"){
        dialog_or_id = $("#" + dialog_or_id);
    }
    
    // Set to loading state
    if(dialog_or_id.find('.loading_container').size() > 0){
        dialog_or_id
            .find('input, textarea')
            .attr('disabled', 'disabled')
            .end()
            .find('.button_block')
            .hide()
            .end()
            .find('.loading_container')
            .html(qc.button(3,'#',text))
            .show()
            .end()
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog);
    } else {
        dialog_or_id
            .html("<p>" + text + "</p>")
             // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog);
    }
}

qc.dialogStopLoading = function(dialog_or_id)
{
    if(typeof(dialog_or_id) == "string"){
        dialog_or_id = $("#" + dialog_or_id);
    }
    // Remove loading state
    dialog_or_id
        .find('input, textarea')
        .attr('disabled', '')
        .end()
        .find('.button_block')
        .show()
        .end()
        .find('.loading_container')
        .hide()
        .end()
        // Re-center
        .parents(".ui-dialog")
        .each(qc.reCenterDialog);
}

qc.closeDialog = function(dialog_or_id)
{
    if(typeof(dialog_or_id) == "string"){
        dialog_or_id = $("#" + dialog_or_id);
    }
    // Close
    dialog_or_id
        .dialog('close');
}

qc.dialogError = function(dialog_id, error)
{
    var default_error = false;
    if(typeof(dialog_id) == 'string'){
        var original_dialog = $("#" + dialog_id);
        var dialog_error_id = dialog_id + "_error";
    } else {
        var dialog_error_id = "error_dialog";
    }
    
    if(typeof(error) != "string" || error.length < 1){
        // Default error message
        default_error = true;
        error = "<p>Oops, something went wrong there. Please try again or contact us if the error persists.</p>";
    }

    // Button
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Ok',opt);
    opt = {
        cssClass: "primary"
    };
    error += qc.buttonBlock(button,opt);
    
    // Spawn a new error dialog
    var error_dialog = qc.createDialogNode(error, dialog_error_id);
    
    error_dialog
        .dialog('destroy')
        .dialog({
            title: 'Error',
            width: 400,
            minHeight: 100,
            maxHeight: 400,
            modal: true,
            dialogClass: 'dialog_error',
            closeOnEscape: false,
            close: function(event, ui){
                if(typeof(original_dialog) != 'undefined'){
                    // Take the underlying dialog out of loading mode
                    qc.dialogStopLoading(original_dialog);
                }
            }
        })
        .find(".primary_dialog_button")
        .click(function(){
            $("#" + dialog_error_id)
                .dialog('close')
                .dialog('destroy');
            return false;
        });
}


/*------------------------------------
 * Contextual menu functions
 *------------------------------------*/

qc.contextMenu = function(e, elem, html){

    qc.vars.contextShowing = true;

    // Get click position
    var x, y;
    x = e.pageX;
    y = e.pageY;
    
    // Grab context menu node
    var context_menu_node = $("#contextMenu");
    
    // Create node and make it into a menu
    context_menu_node
        .html(html)
        .show()
        .css({ top: y, left: x })
        .find("ul")
        .superfish({ 
             speed: 0,
             disableHI: true,
             autoArrows:  false,
             dropShadows: false,
             hoverClass: "active"
         });
    
    // Adjust the position if too close to the edge
    var menu_ul = $("#contextMenu > ul");
    var menuWidth = menu_ul.width();
    var menuHeight = menu_ul.height();
    
    // Too close to the right
    if($(window).width() - x < menuWidth) {
        x -= menuWidth;
        context_menu_node
            .css({ left: x })
    }
    
    // Too close to the bottom
    if($(window).height() - y < menuHeight) {
        y -= menuHeight;
        context_menu_node
            .css({ top: y })
    }
    
    return false;
        
}


qc.contextMenuLoading = function(e)
{
    var html = "<ul><li><span class='inactive'>Loading...</span></li></ul>";
    return qc.contextMenu(e, undefined, html);
}

qc.hideContextMenu = function()
{
    $("#contextMenu").hide();
    qc.vars.contextShowing = false;
}

qc.getContextMenu = function()
{
    return $("#contextMenu");
}



 /*----------------------------------------
  * Project crew/rentals viewing functions
  *----------------------------------------*/

qc.tableViewBooking = function(id_or_elem)
{
    
    qc.hideContextMenu();
    
    // Check if we're in double view, as in that view we can view bookings
    var secondary_table = $(".selectable_secondary_rows");
    if(secondary_table.size() > 0){
        
        qc.dialogError(undefined, "Sorry, you can't view bookings here, please switch back to <a href='?_QC_PROJ_VIEW_TYPE=list'>List View</a>.");
        return;
        
    }
    
    if(typeof(id_or_elem) == 'string'){
        id_or_elem = $("#" + id_or_elem);
    }

    // Show (slide open) booking
    var row = qc.tableGetSelectedRow(id_or_elem);
    qc.tableToggleNextRow(row);
    
}

qc.tableGetSelectedRowValue = function(table_obj_or_id)
{
    var selected_row = qc.tableGetSelectedRow(table_obj_or_id);
    if(selected_row){
        return selected_row.find("input.row_value").val();
    }
    return false;
}

qc.tableGetSelectedRow = function(table_obj_or_id)
{
    if(typeof(table_obj_or_id) == 'string'){
        table_obj_or_id = $("#" + table_obj_or_id);
    }
        
    // Check if anything is selected
    var checked_row = table_obj_or_id
                            .find("tbody tr.selected");
    
    if(checked_row.size() == 0){

        // Nothing selected, prompt
        qc.dialogError(undefined, "Please select a row first.");
        return false;
        
    }
    
    return checked_row;
        
}

qc.tableRightClickMenu = function(e)
{
    
    var t = e.target ? e.target : e.srcElement;

    // Don't do right-click menu on links or inputs...
    if(t.tagName == 'A' || t.tagName == 'INPUT'){
        return true;
    }
    
    // Menu HTML
    var html = "<ul>";
        
    // Get left table
    var single_table = true;
    var secondary_table = $(".selectable_secondary_rows");
    if(secondary_table.size() > 0){

        // Double table
        single_table = false;
        
        // Are we in the left or right table?
        var my_parent_div = $(this)
                                .parents("table")
                                .parent();
        if(my_parent_div.hasClass("table_right")){
            var table = my_parent_div
                                .prev(".table_left")
                                .find("table");
        } else {
            var table = my_parent_div
                            .find("table");
        }
        
    } else {
        
        // Single table
        var table = $(t).parents("table");
        
    }
        
    // Get selected row
    var selected_value = qc.tableGetSelectedRowValue(table);
    var selected_row = qc.tableGetSelectedRow(table);
    
    // Nothing selected, can't do anything!
    if(!selected_row){
        return false;
    }
            
    // Get right type
    if(table.hasClass("project_crew_table") || table.hasClass("project_rentals_table")){

        /*
         * Project crew/rentals table
         */

        // Check if project is archived
        var pr_archived = $("#pr_archived").val();
         
        // Booking ID or Change ID
        if (selected_value.match(/ch_/)) {
        	var booking_or_change = 'change';
        	var object_id = selected_value.replace(/ch_/, "");
        } else {
        	var booking_or_change = 'booking';
        	var object_id = selected_value.replace(/bo_/, "");
        }
         
        // View Booking
        if (booking_or_change == 'change') {
        	var view_link_text = 'View Invite';
        } else {
        	var view_link_text = 'View Booking';        	
        }
        if(single_table){
            html += "<li><a href='#' onclick='qc.tableViewBooking(\"" + table.attr("id") + "\");return false;'>" + view_link_text + "</a></li>";
        } else {
            html += "<li><span class='inactive'>" + view_link_text + " </span></li>";
        }

        // Mark As
        if(selected_row.hasClass("manually_added")){
            // Inactive
            html += "<li class='sub_present'><span class='inactive'>Mark As</span><ul>";
            html += "<li><span class='inactive'>Favourite</span></li>";
            html += "<li><span class='inactive'>Blacklisted</span></li>";
            html += "<li class='divide'><span class='inactive'>Remove Mark</span></li>";
            html += "</ul></li>";
        } else {
            // Active
            html += "<li class='sub_present'><a href='#' onclick='qc.return false;'>Mark As</a><ul>";
            html += "<li><a href='#' onclick='qc.markAsFavourite(\"" + table.attr("id") + "\",\"crew\",1);return false;'>Favourite</a></li>";
            html += "<li><a href='#' onclick='qc.markAsFavourite(\"" + table.attr("id") + "\",\"crew\",0);return false;'>Blacklisted</a></li>";
            html += "<li class='divide'><a href='#' onclick='qc.markAsFavourite(\"" + table.attr("id") + "\",\"crew\");return false;'>Remove Mark</a></li>";
            html += "</ul></li>";
        }

        // Firm Book
        if(booking_or_change == 'booking' && $("#bo_" + object_id + "_firmbook_url").size()){
            // Active
            html += "<li><a href='#' onclick='qc.tableFirmBook(\"" + table.attr("id") + "\");return false;'>Firm Book...</a></li>";
        } else {
            // Inactive
            html += "<li><span class='inactive'>Firm Book...</span></li>";
        }

        // Accept on behalf
        if(booking_or_change == 'change' && $("#ch_" + object_id + "_accept_on_behalf_url").size()){
            // Active
            html += "<li><a href='#' onclick='qc.tableAcceptOnBehalf(\"" + table.attr("id") + "\");return false;'>Accept Invite On Behalf...</a></li>";
        } else {
            // Inactive
            html += "<li><span class='inactive'>Accept Invite On Behalf...</span></li>";
        }

        // Modify Booking
        if(booking_or_change == 'booking' && $("#bo_" + object_id + "_modify_url").size()){
            // Active
            html += "<li><a href='#' onclick='qc.tableModifyBooking(\"" + table.attr("id") + "\");return false;'>Edit Booking...</a></li>";
        } else {
            // Inactive
            html += "<li><span class='inactive'>Modify Booking...</span></li>";
        }

        // Reinvite
        if(booking_or_change == 'booking' && $("#bo_" + object_id + "_reinvite_url").size()){
            // Active
            html += "<li><a href='#' onclick='qc.tableReinviteBooking(\"" + table.attr("id") + "\");return false;'>Reinvite...</a></li>";
        } else if (booking_or_change == 'change' && $("#ch_" + object_id + "_reinvite_url").size()) {
        	// Active (invite)
    		html += "<li><a href='#' onclick='qc.tableReinviteBooking(\"" + table.attr("id") + "\");return false;'>Reinvite...</a></li>";
        } else {
            // Inactive
            html += "<li><span class='inactive'>Reinvite...</span></li>";
        }
        
        // Cancel Booking or Invite
        if (booking_or_change == 'booking' && $("#bo_" + object_id + "_cancel_url").size()) {
        	// Active (booking)
    		html += "<li><a href='#' onclick='qc.tableCancelBooking(\"" + table.attr("id") + "\");return false;'>Cancel Booking...</a></li>";
        } else if (booking_or_change == 'change' && $("#ch_" + object_id + "_cancel_url").size()) {
        	// Active (invite)
    		html += "<li><a href='#' onclick='qc.tableCancelBooking(\"" + table.attr("id") + "\");return false;'>Cancel Invite...</a></li>";
        } else {
            // Inactive
            html += "<li><span class='inactive'>Cancel...</span></li>";
        }
        
        // Remove Booking
        if(booking_or_change == 'booking' && $("#bo_" + object_id + "_remove_url").size()){
            // Active (booking)
            html += "<li><a href='#' onclick='qc.tableRemoveBooking(\"" + table.attr("id") + "\");return false;'>Remove...</a></li>";
        } else if (booking_or_change == 'change' && $("#ch_" + object_id + "_remove_url").size()) {
        	// Active (invite)
    		html += "<li><a href='#' onclick='qc.tableRemoveBooking(\"" + table.attr("id") + "\");return false;'>Remove Invite...</a></li>";
        } else {
            // Inactive
            html += "<li><span class='inactive'>Remove...</span></li>";
        }
        
        // View Profile
        if(selected_row.hasClass("manually_added")){
            // Inactive
            html += "<li><span class='inactive'>View Profile</span></li>";
        } else {
            // Active
            html += "<li><a href='#' onclick='qc.tableViewProfile(\"" + table.attr("id") + "\");return false;'>View Profile</li>";
        }
        
    } else if(table.hasClass("project_crew_table_view_only")){

            /*
             * Project crew table view only
             */
    	
	        // Booking ID or Change ID
	        if (selected_value.match(/ch_/)) {
	        	var booking_or_change = 'change';
	        	var object_id = selected_value.replace(/ch_/, "");
	        } else {
	        	var booking_or_change = 'booking';
	        	var object_id = selected_value.replace(/bo_/, "");
	        }
	        if (booking_or_change == 'change') {
	        	var view_link_text = 'View Invite';
	        } else {
	        	var view_link_text = 'View Booking';        	
	        }

            // View Booking
            if(single_table){
                html += "<li><a href='#' onclick='qc.tableViewBooking(\"" + table.attr("id") + "\");return false;'>" + view_link_text + "</a></li>";
            } else {
                html += "<li><span class='inactive'>" + view_link_text + "</span></li>";
            }
    
    } else if (table.hasClass("booking_preview_table")){
        
        /*
         * Crew/rentals booking preview step
         */
        
        // Booking details
        html += "<li><a href='#' onclick='qc.tableToggleNextRow($(\"#" + selected_row.attr("id") + "\"));return false;'>Booking details</a></li>";

        // Delete
        html += "<li><a href='#' onclick='qc.bookingDeletePrepared(\"" + selected_row.attr("id") + "\");return false;'>Delete</a></li>";

        
    }
    
    html += "</ul>";
    
    qc.contextMenu(e, t, html);
        
    return false;
}

qc.tableModifyBooking = function(table_id)
{
    
    qc.hideContextMenu();
    
    // Get selected row and booking id
    var selected_row = qc.tableGetSelectedRow(table_id);
    var bo_id = qc.tableGetSelectedRowValue(table_id).replace(/bo_/, "");
    
    if(bo_id > 0){
    
        // See if we have a hidden input with the 'modify' URL
        var hidden_input = $("#bo_" + bo_id + "_modify_url");
        if(hidden_input.size() && hidden_input.val()){
            
            // Redirect
            window.location = hidden_input.val();
            return;
            
        }
        
    }

    qc.dialogError(undefined, "Sorry, you can't modify this booking. Only active invites or bookings can be modified.");
    return;
    
}

qc.tableViewProfile = function(table_id)
{
    
    qc.hideContextMenu();
    
    // Get selected row
    var selected_row = qc.tableGetSelectedRow(table_id);
    
    // Get profile link
    var profile_link = selected_row.find(".profile_link");
    
    // Is there a link, if so redirect
    if(profile_link.size() > 0){
    	if (profile_link.attr("href")) {
    		window.location = profile_link.attr("href");
    	} else if (profile_link.val()) {
    		window.location = profile_link.val();
    	}
        return;
        
    // There's no link, error
    } else {
        qc.dialogError(undefined, "There is no profile for the selected row.");
        return;
    }
    
}

qc.tableCancelBooking = function(table_id)
{
    
    qc.hideContextMenu();
    
    // Get selected row and booking id
    var selected_row = qc.tableGetSelectedRow(table_id);
    var selected_value = qc.tableGetSelectedRowValue(table_id);
    if (selected_value.match(/ch_/)) {
    	var booking_or_invite = "invite";
    	var obj_id = selected_value.replace(/ch_/, "");
    } else {
    	var booking_or_invite = "booking";
    	var obj_id = selected_value.replace(/bo_/, "");
    }
    
    if(obj_id > 0){
    
        // See if we have a hidden input with the 'cancel' data
    	if (booking_or_invite == 'invite') {
    		var hidden_input = $("#ch_" + obj_id + "_cancel_url");
    	} else {
    		var hidden_input = $("#bo_" + obj_id + "_cancel_url");
    	}
        if(hidden_input.size() && hidden_input.val()){
            
            // Split pipe-separated values
            var values = hidden_input.val().split('|');
            
            if(values.length == 3){
            
                // Name pipe-separated values
                var title = values[0];
                var text = values[1];
                var guid = values[2];
                
                // Show prompt before proceeding
                var html = "<p>" + text + "</p>";
                
                // Buttons
                var opt = {
                    extra_classes: "primary_dialog_button"
                };
                var button = qc.button(1,'#','Cancel',opt);
                opt = {
                    extra_classes: "secondary_dialog_button"
                };
                button += " " + qc.button(2,'#','Don\'t Cancel',opt);
                opt = {
                    cssClass: "primary"
                };
                html += qc.buttonBlock(button,opt);
                opt = {
                    cssClass: "primary loading_container",
                    style: "display: none;"
                };
                html += qc.buttonBlock("",opt);

                var dialog = qc.createDialogNode("");
                dialog_id = dialog.attr('id');
                dialog
                    .dialog("destroy")
                    .html(html)
                    // Add click functions to the buttons
                    .find(".primary_dialog_button")
                    .click(function(){
                        qc.tableCancelBookingConfirm(guid,dialog_id);
                        return false;
                    })
                    .end()
                    .find(".secondary_dialog_button")
                    .click(function(){
                        $("#" + dialog_id).dialog("close");
                        return false;
                    })
                    .end()
                    .dialog({
                        title: title
                    });
                
                return;
            
            }
                
        }
        
    }

    qc.dialogError(undefined, "Sorry, you can't cancel this " + booking_or_invite + ". Only active invites or bookings that aren't manually added can be cancelled.");
    return;
    
}

qc.tableCancelBookingConfirm = function(bo_guid,dialog_id)
{
    
    // Set dialog to loading
    qc.dialogLoading(dialog_id, "Cancelling...");
    
    // Send Ajax request
    var pars = {
            opt: 'booking_cancel',
            bo_guid: bo_guid
        };
    $.getJSON("/ajax-handler.php", pars, function(data){
        qc.tableCancelBookingConfirmResponse(data, dialog_id);
    });

}

qc.tableCancelBookingConfirmResponse = function(originalRequest, dialog_id)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        // Redirect to same page with success message appended to URL
        var strLocation = window.location.toString();
        window.location = strLocation.substring(0, strLocation.indexOf("?")) + "?successmsg=Booking%20cancelled.";
        return;
        
    } else {
        
        // Cancel didn't work
        var error = result.message;
        qc.dialogError(dialog_id,error);
        
    }
    
}

qc.tableRemoveBooking = function(table_id)
{
    
    qc.hideContextMenu();
    
    // Get selected row and booking id
    var selected_row = qc.tableGetSelectedRow(table_id);
    var row_value = qc.tableGetSelectedRowValue(table_id);
    var bo_id = row_value.replace(/bo_/, "");
    var ch_id = row_value.replace(/ch_/, "");
    if(bo_id > 0 || ch_id > 0){
    
        // See if we have a hidden input with the 'remove' data
    	if (bo_id > 0) {
    		var hidden_input = $("#bo_" + bo_id + "_remove_url");
    	} else if (ch_id > 0) {
    		var hidden_input = $("#ch_" + ch_id + "_remove_url");
    	}

        if(hidden_input.size() && hidden_input.val()){
            
            // Split pipe-separated values
            var values = hidden_input.val().split('|');
            
            if(values.length == 3){
            
                // Name pipe-separated values
                var title = values[0];
                var text = values[1];
                var guid = values[2];
                
                // Show prompt before proceeding
                var html = "<p>" + text + "</p>";
                
                // Buttons
                var opt = {
                    extra_classes: "primary_dialog_button"
                };
                var button = qc.button(1,'#','Remove',opt);
                opt = {
                    extra_classes: "secondary_dialog_button"
                };
                button += " " + qc.button(2,'#','Cancel',opt);
                opt = {
                    cssClass: "primary"
                };
                html += qc.buttonBlock(button,opt);
                opt = {
                    cssClass: "primary loading_container",
                    style: "display: none;"
                };
                html += qc.buttonBlock("",opt);

                var dialog = qc.createDialogNode("");
                dialog_id = dialog.attr('id');
                dialog
                    .dialog("destroy")
                    .html(html)
                    // Add click functions to the buttons
                    .find(".primary_dialog_button")
                    .click(function(){
                        qc.tableRemoveBookingConfirm(guid,dialog_id);
                        return false;
                    })
                    .end()
                    .find(".secondary_dialog_button")
                    .click(function(){
                        $("#" + dialog_id).dialog("close");
                        return false;
                    })
                    .end()
                    .dialog({
                        title: title
                    });
                
                return;
            
            }
                
        }
        
    }

    qc.dialogError(undefined, "Sorry, you can't remove this booking or invite. Only cancelled, expired, declined or manually added bookings can be removed.");
    return;
    
}

qc.tableRemoveBookingConfirm = function(bo_guid,dialog_id)
{
    
    // Set dialog to loading
    qc.dialogLoading(dialog_id, "Removing...");
    
    // Send Ajax request
    var pars = {
            opt: 'booking_remove_single',
            bo_guid: bo_guid
        };
    $.getJSON("/ajax-handler.php", pars, function(data){
        qc.tableRemoveBookingConfirmResponse(data, dialog_id);
    });

}

qc.tableRemoveBookingConfirmResponse = function(originalRequest, dialog_id)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        // Redirect to same page with success message appended to URL
        var strLocation = window.location.toString();
        window.location = strLocation.substring(0, strLocation.indexOf("?")) + "?successmsg=" + escape(result.message);
        return;
        
    } else {

        // Remove didn't work
        qc.dialogError(dialog_id,result.message);

    }
    
}



qc.tableFirmBook = function(table_id)
{
    
    qc.hideContextMenu();
    
    // Get selected row and booking id
    var selected_row = qc.tableGetSelectedRow(table_id);
    var bo_id = qc.tableGetSelectedRowValue(table_id).replace(/bo_/, "");
    
    if(bo_id > 0){
    
        // See if we have a hidden input with the 'firm book' data
        var hidden_input = $("#bo_" + bo_id + "_firmbook_url");
        if(hidden_input.size() && hidden_input.val()){
            
            // Split pipe-separated values
            var values = hidden_input.val().split('|');

            if(values.length == 3){
            
                // Name pipe-separated values
                var title = values[0];
                var text = values[1];
                var guid = values[2];
                
                // Show prompt before proceeding
                var html = "<p>" + text + "</p>";
                
                // Buttons
                var opt = {
                    extra_classes: "primary_dialog_button"
                };
                var button = qc.button(1,'#','Firm book',opt);
                opt = {
                    extra_classes: "secondary_dialog_button"
                };
                button += " " + qc.button(2,'#','Cancel',opt);
                opt = {
                    cssClass: "primary"
                };
                html += qc.buttonBlock(button,opt);
                opt = {
                    cssClass: "primary loading_container",
                    style: "display: none;"
                };
                html += qc.buttonBlock("",opt);

                var dialog = qc.createDialogNode("");
                dialog_id = dialog.attr('id');
                dialog
                    .dialog("destroy")
                    .html(html)
                    // Add click functions to the buttons
                    .find(".primary_dialog_button")
                    .click(function(){
                        qc.tableFirmBookConfirm(guid,dialog_id);
                        return false;
                    })
                    .end()
                    .find(".secondary_dialog_button")
                    .click(function(){
                        $("#" + dialog_id).dialog("close");
                        return false;
                    })
                    .end()
                    .dialog({
                        title: title
                    });
                
                return;
            
            }
                
        }
        
    }

    qc.dialogError(undefined, "Sorry, you can't create a firm invite from this booking. Only pencil bookings can be made into firm invites.");
    return;
    
}

qc.tableFirmBookConfirm = function(bo_guid,dialog_id)
{
    
    // Set dialog to loading
    qc.dialogLoading(dialog_id, "Booking...");
    
    // Send Ajax request
    var pars = {
            opt: 'booking_firm',
            url: document.location.href,
            bo_guid: bo_guid
        };
    $.getJSON("/ajax-handler.php", pars, function(data){
        qc.tableFirmBookConfirmResponse(data, dialog_id);
    });
    
}

qc.tableFirmBookConfirmResponse = function(originalRequest, dialog_id)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.url) == "string"
    ) {
        
        // Redirect to booking process
        location.replace(result.data.url);
        return;
        
    } else {
        
        // Firm book didn't work
        var error = result.message;
        qc.dialogError(dialog_id,error);
        
    }
    
}

qc.tableAcceptOnBehalf = function(table_id)
{
    
    qc.hideContextMenu();
    
    // Get selected row and booking id
    var selected_row = qc.tableGetSelectedRow(table_id);
    var ch_id = qc.tableGetSelectedRowValue(table_id).replace(/ch_/, "");
    
    if(ch_id > 0){
    
        // See if we have a hidden input with the 'accept on behalf' URL
        var hidden_input = $("#ch_" + ch_id + "_accept_on_behalf_url");
        if(hidden_input.size() && hidden_input.val()){
            
            // Redirect
            window.location = hidden_input.val();
            return;
            
        }
        
    }

    qc.dialogError(undefined, "Sorry, you can't accept this invite on behalf. Only unaccepted invites can be accepted on behalf.");
    return;
    
}

qc.tableReinviteBooking = function(table_id)
{

    qc.hideContextMenu();
    
    // Get selected row and booking id
    var selected_row = qc.tableGetSelectedRow(table_id);
    var selected_value = qc.tableGetSelectedRowValue(table_id);
    if (selected_value.match(/ch_/)) {
    	var booking_or_invite = "invite";
    	var obj_id = selected_value.replace(/ch_/, "");
    } else {
    	var booking_or_invite = "booking";
    	var obj_id = selected_value.replace(/bo_/, "");
    }
    
    if(obj_id > 0){
    
        // See if we have a hidden input with the 'reinvite' data
    	if (booking_or_invite == 'invite') {
    		var hidden_input = $("#ch_" + obj_id + "_reinvite_url");
    	} else {
    		var hidden_input = $("#bo_" + obj_id + "_reinvite_url");
    	}
        if(hidden_input.size() && hidden_input.val()){
            
            // Split pipe-separated values
            var values = hidden_input.val().split('|');
            
            if(values.length == 3){
            
                // Name pipe-separated values
                var title = values[0];
                var text = values[1];
                var guid = values[2];
                
                // Show prompt before proceeding
                var html = "<p>" + text + "</p>";
                
                // Buttons
                var opt = {
                    extra_classes: "primary_dialog_button"
                };
                var button = qc.button(1,'#','Yes',opt);
                opt = {
                    extra_classes: "secondary_dialog_button"
                };
                button += " " + qc.button(2,'#','No',opt);
                opt = {
                    cssClass: "primary"
                };
                html += qc.buttonBlock(button,opt);
                opt = {
                    cssClass: "primary loading_container",
                    style: "display: none;"
                };
                html += qc.buttonBlock("",opt);
                
                // Dialog
                var dialog = qc.createDialogNode("");
                dialog_id = dialog.attr('id');
                dialog
                    .dialog("destroy")
                    .html(html)
                    // Add click functions to the buttons
                    .find(".primary_dialog_button")
                    .click(function(){
                        qc.tableReinviteBookingConfirm(guid,dialog_id);
                        return false;
                    })
                    .end()
                    .find(".secondary_dialog_button")
                    .click(function(){
                        $("#" + dialog_id).dialog("close");
                        return false;
                    })
                    .end()
                    .dialog({
                        title: title
                    });
                
                return;
            
            }
                
        }
        
    }

    qc.dialogError(undefined, "Sorry, you can't reinvite this booking. Only cancelled, expired or not yet accepted invites can be reinvited.");
    return;
    
}

qc.tableReinviteBookingConfirm = function(bo_guid,dialog_id)
{
    
    // Set dialog to loading
    qc.dialogLoading(dialog_id, "Proceeding...");
    
    // Send Ajax request
    var pars = {
            opt: 'booking_reinvite',
            bo_guid: bo_guid
        };
    $.getJSON("/ajax-handler.php", pars, function(data){
        qc.tableReinviteBookingConfirmResponse(data, dialog_id);
    });
    
}

qc.tableReinviteBookingConfirmResponse = function(originalRequest, dialog_id)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.url) == "string"
    ) {
        
        // Redirect to booking process
        location.replace(result.data.url);
        return;
        
    } else {
        
        // Reinvite didn't work
        var error = result.message;
        qc.dialogError(dialog_id,error);
        
    }
    
}

qc.viewShowReelModal = function(showreel_guid, dialog_title)
{
    // Hide context menu...
    qc.hideContextMenu();
    
    // Launch loading dialog
    var dialog_id = "showreel_modal_dialog";
    var dialog = qc.createDialogNode("", dialog_id);
    dialog
        .dialog("destroy")
        .dialog({
            width: 450,
            title: dialog_title,
            dialogClass: "showreel_dialog",
            resizable: false
        });
    qc.dialogLoading(dialog);
    
    // Fire Ajax to update its contents
    var pars = {
            opt: 'showreel_modal',
            showreel_guid: showreel_guid
    };
     
    // Fire it off
    $.getJSON("/ajax-handler.php", pars, function(data){
        qc.viewShowReelModalResponse(data, dialog);
    });
    
}

qc.viewShowReelModalResponse = function(originalRequest, dialog)
{
    
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.html) == "string"
    ) {    	
        // Replace dialog contents
        dialog
            .html(result.data.html)
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog);
        return;
        
    } else {
        
        // Showreel showing didn't work
        qc.closeDialog(dialog);
        var error = result.message;
        qc.dialogError(dialog,error);
        
    }

}

/* ---------------------------
 * Show bookable related items
   --------------------------- */

qc.viewRelatedBookingObjectsFromTableRow = function(container_id, object_type, project_id){

    // Get crew ID from container
    crew_id = qc.getCrewIdFromContainer(container_id);
    
    // Call parent function
    if (crew_id) {
        return qc.viewRelatedBookingObjects(crew_id, object_type, project_id);
    }
    
}

qc.viewRelatedBookingObjects = function(crew_id, object_type, project_id, show_prepare_invites_link) {
    
    // Hide context menu...
    qc.hideContextMenu();
    
    // Dialog title
    if(object_type == "crew") {
        var dialog_title = 'Crew they like to work with';
    } else {
        var dialog_title = 'Rentals they provide';                
    }
    var dialog_id = "booking_related_objects";    
    
    if(crew_id) {
        // Launch loading dialog
        var dialog = qc.createDialogNode("", dialog_id);
        dialog
            .dialog("destroy")
            .dialog({
                maxHeight: 500,
                title: dialog_title,
                width: 800, 
                resizable: true
            });
        qc.dialogLoading(dialog);
        
        // Default value for show_prepare_invites_link
        if (typeof(show_prepare_invites_link) != "boolean") {
        	show_prepare_invites_link = true;
        }
               
        // Fire Ajax to update its contents
        var pars = {
                opt: 'booking_related_items',
                crew_id: crew_id,
                dialog_id: dialog_id,
                object_type: object_type,
                project_id: project_id,
                show_prepare_invites_link: show_prepare_invites_link
            };
         
        // Fire it off
        $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
            qc.viewRelatedBookingObjectsResponse(data, dialog, show_prepare_invites_link);
        }); 
 
    } else {
        
        var error = "Sorry, this doesn't work for manually added crew.";
        qc.dialogError(dialog_id,error);
        
    }
    
    return false;    
    
}


qc.viewRelatedBookingObjectsResponse = function(originalRequest, dialog, show_prepare_invites_link)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    if (
        result.status == 1
    ) {
        
    	var has_secondary = dialog.find(".secondary").size();
    	
        // Get dialog and add HTML
    	dialog
            .html(result.data.html)
            // Add click functions to the buttons
            .each(function(){
            	if ($(this).find(".secondary").size() > 0) {
            		$(this)
            			.find(".secondary")
			            .click(function(){
			            	dialog.dialog("close");
			                return false;
			            });
            	} else {
            		$(this)
        			.find(".button")
		            .click(function(){
		            	dialog.dialog("close");
		                return false;
		            });
            	}
            })
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog);
        
    } else {
        
        // Reinvite didn't work
        var error = result.message;
        qc.dialogError(dialog_id,error);
        
    }
    
}


/*----------------------------------------
 * General calendar interaction functions
 *----------------------------------------*/

// Saving a calendar note
qc.saveNote = function(guid,dialog_id,calObj)
{
    // Get dialog
    var dialog = $("#" + dialog_id);
    
    // Get note values
    var start_date = dialog
        .find("input[name='cn_start_date']")
        .val();
    var end_date = dialog
        .find("input[name='cn_end_date']")
        .val();
    var text = dialog
        .find("textarea[name='cn_text']")
        .val();
    var parent_guid = dialog
        .find("input[name='cn_parent_guid']")
        .val();
    var colour = dialog
    .find("select[name='cn_colour']")
    .val();    
    
    // Don't need an end date if we have a start date
    if(end_date == ''){
        end_date = start_date;
    }
    
    // Put dialog into loading mode
    qc.dialogLoading(dialog_id,"Saving...");

    // Save it using ajax
    var pars = {
            opt: 'cal_save_note',
            cal_id: calObj.id,
            dialog_id: dialog_id,
            cn_guid: guid,
            cn_start_date: start_date,
            cn_end_date: end_date,
            cn_text: text,
            cn_colour: colour,
            cn_parent_guid: parent_guid
        };
        
    $.getJSON("/ajax-handler.php", pars, qc.saveNoteResponse);
    
}

// Ajax response to saving a note
qc.saveNoteResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.cal_instance_var) == "string" &&
        typeof(result.data.dialog_id) == "string"
    ) {
        
        // Refresh calendar
        eval(result.data.cal_instance_var + ".loadDays(undefined,undefined,'qc.closeDialog','" + result.data.dialog_id + "');");
        
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        // Note couldn't be saved...
        var error = "";
        
        if(typeof(result.data.errors.cn_start_date) != undefined || typeof(result.data.errors.cn_end_date) != undefined){
            error += "<p>Sorry, it doesn't look like you've set the dates for the note correctly.</p>";
        }
        
        qc.dialogError(result.data.dialog_id,error);
        
    }
}

// Deleting a calendar note
qc.deleteNote = function(guid,dialog_id,calObj)
{
    // There's no dialog yet, create one
    if(dialog_id == false){
        qc.hideContextMenu();
        var dialog = qc.createDialogNode("");
        dialog_id = dialog.attr('id');
        dialog
            .dialog("destroy")
            .dialog({
                dialogClass: "calendar_dialog",
                title: "Note"
            });
    } else {
        // Get dialog
        var dialog = $("#" + dialog_id);
    }
    // Put dialog into loading mode
    qc.dialogLoading(dialog_id,"Deleting...");
    // Delete it using ajax
    var pars = {
            opt: 'cal_delete_note',
            cal_id: calObj.id,
            dialog_id: dialog_id,
            cn_guid: guid
        };
        
    $.getJSON("/ajax-handler.php", pars, qc.deleteNoteResponse);
}

// Ajax response function for deleting a calendar note
qc.deleteNoteResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.cal_instance_var) == "string" &&
        typeof(result.data.dialog_id) == "string"
    ) {
        
        // Refresh calendar
        eval(result.data.cal_instance_var + ".loadDays(undefined,undefined,'qc.closeDialog','" + result.data.dialog_id + "');");
        
    }
}

// Shows a dialog box to edit a calendar note
qc.noteEditDialog = function(elem_or_class_string,calObj,opt)
{     
     // Hide context menu...
     qc.hideContextMenu();
     
     // Get guid if it's an existing note
     var guid = false;
     if(typeof(elem_or_class_string) == 'string'){
         guid = calObj.getGuidFromClass(elem_or_class_string);
     } else if(typeof(elem_or_class_string) != 'undefined'){
         guid = calObj.getGuidFromClass(elem_or_class_string.className);
     } else {
         // New note, do we have days selected?
         var date_range = calObj.getSelectedDateRange();
         if(date_range != false){
             var start_date = date_range[0];
             var end_date = date_range[1];
         }
     }
     
     // Is there a parent guid in the options?
     var cn_parent_guid = false;
     if(typeof(opt) != "undefined" && typeof(opt.cn_parent_guid) != "undefined"){
         cn_parent_guid = opt.cn_parent_guid;
     }
     
     // Launch loading dialog
     var dialog_id = "note_edit_" + guid;
     var dialog = qc.createDialogNode("", dialog_id);
     dialog
         .dialog("destroy")
         .dialog({
             dialogClass: "calendar_dialog",
             title: "Note"
         });
     qc.dialogLoading(dialog);
     
     // Fire Ajax to update its contents
     var pars = {
             opt: 'cal_get_note_edit_dialog',
             guid: guid,
             cn_parent_guid: cn_parent_guid
         };
     // Is there a start or end date?
     if(typeof(start_date) != 'undefined'){
         pars.start_date = start_date;
     }
     if(typeof(end_date) != 'undefined'){
         pars.end_date = end_date;
     }     
     
     $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
         qc.noteEditDialogResponse(data, calObj, dialog_id);
     });

     return false;
}

// Ajax response when editing a calendar note
qc.noteEditDialogResponse = function(originalRequest, calObj, dialog_id)
{
    
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }

    if (
        result.status == 1 && 
        typeof(result.data.guid) != undefined && 
        typeof(result.data.html) != undefined
    ) {
        
        // Get dialog and add HTML
        var guid = result.data.guid;
        $("#" + dialog_id)
            .html(result.data.html)
            // Add click functions to the buttons
            .find(".primary_dialog_button")
            .click(function(){
                qc.saveNote(guid,dialog_id,calObj);
                return false;
            })
            .end()
            .find(".secondary_dialog_button")
            .click(function(){
                $("#" + dialog_id).dialog("close");
                return false;
            })
            .end()
            .find(".tertiary_dialog_button")
            .click(function(){
                qc.deleteNote(guid,dialog_id,calObj);
                return false;
            })
            .end()
            // Focus textarea
            .find("textarea[name='cn_text']")
            .focus()
            .end()
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog);
        
    } else {
        
        qc.closeDialog(dialog_id);
        qc.dialogError(undefined,result.message);
        
    }
    
}

//Shows a dialog box to view a calendar note
qc.noteViewDialog = function(elem_or_class_string,calObj,opt)
{

    // Hide context menu...
    qc.hideContextMenu();
    
    // Get guid of note
    var guid = false;
    if(typeof(elem_or_class_string) == 'string'){
        guid = calObj.getGuidFromClass(elem_or_class_string);
    } else if(typeof(elem_or_class_string) != 'undefined'){
        guid = calObj.getGuidFromClass(elem_or_class_string.className);
    }
    
    if(guid){
        
        // Launch loading dialog
        var dialog_id = "note_view_" + guid;
        var dialog = qc.createDialogNode("", dialog_id);
        dialog
            .dialog("destroy")
            .dialog({
                dialogClass: "calendar_dialog",
                title: "Note"
            });
        qc.dialogLoading(dialog);
        
        // Fire Ajax to update its contents
        var pars = {
                opt: 'cal_get_note_view_dialog',
                guid: guid
            }; 
        
        $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
            qc.noteViewDialogResponse(data, calObj, dialog_id);
        });
        
    } else {
        qc.dialogError(undefined, "Sorry, we couldn't open that note due to technical problems!");
    }

}

// Ajax response when viewing a calendar note
qc.noteViewDialogResponse = function(originalRequest, calObj, dialog_id)
{
    
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }

    if (
        result.status == 1 && 
        typeof(result.data.html) != undefined
    ) {
        
        // Get dialog and add HTML
        var guid = result.data.guid;
        $("#" + dialog_id)
            .html(result.data.html)
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog);
        
    } else {
        
        qc.closeDialog(dialog_id);
        qc.dialogError(undefined,result.message);
        
    }
    
}

// Right-clicking a calendar day
qc.calRightClick = function(event,elem,calObj)
{
    
    // Get the type of the calendar
    if(typeof(calObj.day_js_function_args) != 'undefined' && typeof(calObj.day_js_function_args.type) != 'undefined'){
        
        // Check if this day is selected, if not select it and de-select others
        if($(elem).hasClass("ui-selected") == false){
            // Deselect all
            calObj.container
                .find(".ui-selected")
                .removeClass("ui-selected");
            $("#" + calObj.id + "_selected")
                .val("");
            // Select one
            $(elem)
                .addClass("ui-selected");
            calObj.computeSelection();
        }
        
        switch(calObj.day_js_function_args.type){
            
            case 'production_planner':
            case 'rental_planner_panel':
                if(typeof(calObj.day_js_function_args.guid) == 'string'){
                    var html = "<ul>";
                    html += "<li><a href='#' onclick='qc.noteEditDialog(undefined," + calObj.getInstanceNameFromId() + ",{cn_parent_guid:\"" + calObj.day_js_function_args.guid + "\"}); return false;'>Add note</a></li>";
                    html += "</ul>";
                    return qc.contextMenu(event,this,html);
                }
                break;
                
            case 'production_crew_availability':

                break;
                
            case 'crew_rental_planner':
                if(typeof(calObj.day_js_function_args.guid) == 'string'){
                    var availability_string = "Availability";
                    if(typeof(calObj.day_js_function_args.availability_prefix) == "string"){
                        availability_string = calObj.day_js_function_args.availability_prefix + " " + availability_string;
                        if(calObj.day_js_function_args.availability_prefix == 'Crew'){
                            availability_string = 'Your ' + availability_string;
                        }
                    }
                    var html = "<ul>";
                    html += "<li><a href='#' onclick='qc.noteEditDialog(undefined," + calObj.getInstanceNameFromId() + ",{cn_parent_guid:\"" + calObj.day_js_function_args.guid + "\"}); return false;'>Add note</a></li>";
                    html += "<li class='sub_present'><a>" + availability_string + "</a>";
                        /*
                        define("_AVAILABILITY_UNAVAILABLE", 1);
                        define("_AVAILABILITY_CALL_FIRST", 10);
                         */
                        html += "<ul class='nav_options daytypes'>";
                        html += "<li><a href='#' onclick='qc.calAvailabilityUpdate(" + calObj.getInstanceNameFromId() + ",\"" + calObj.day_js_function_args.guid + "\",1); return false;'>Unavailable</a></li>";
                        html += "<li><a href='#' onclick='qc.calAvailabilityUpdate(" + calObj.getInstanceNameFromId() + ",\"" + calObj.day_js_function_args.guid + "\",512); return false;'>Call first</a></li>";
                        html += "<li><a href='#' onclick='qc.calAvailabilityUpdate(" + calObj.getInstanceNameFromId() + ",\"" + calObj.day_js_function_args.guid + "\",0); return false;'>Clear</a></li>";
                        html += "</ul>";
                    html += "</ul>";
                    return qc.contextMenu(event,this,html);
                }
                break;
                
            case 'production_project_calendar':
            case 'production_rebook_shoot_dates_calendar':
                if(typeof(calObj.day_js_function_args.guid) == 'string'){
                    var html = "<ul>";
                    
                    if (calObj.day_js_function_args.type != "production_rebook_shoot_dates_calendar") {
                        html += "<li><a href='#' onclick='qc.noteEditDialog(undefined," + calObj.getInstanceNameFromId() + ",{cn_parent_guid:\"" + calObj.day_js_function_args.guid + "\"}); return false;'>Add note</a></li>";
                    }
                    
                    html += "<li class='sub_present'><a>Day Type</a>";
                        html += "<ul class='nav_options daytypes'>";
                        html += "<li><span class='inactive'>Loading...</span></li>";
                        html += "</ul>";
                    html += "</li>";
                    html += "</ul>";
                    
                    // Are we rebooking?
                    var rebooking = 0;
                    if(calObj.day_js_function_args.type == "production_rebook_shoot_dates_calendar"){
                        rebooking = 1;
                    }
                    
                    // Load the day type menu with Ajax
                    var pars = {
                        opt: 'getDayTypeMenuHTML',
                        sub_class: "daytypes",
                        cal_id: calObj.id,
                        rebooking: rebooking,
                        guid: calObj.day_js_function_args.guid
                    };
                    $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
                        qc.calRightClickResponse(data, event, elem);
                    });
                    
                    return qc.contextMenu(event,this,html);
                }
                break;
                
            case 'booking_overview_panel':

                break;
        
        }
        
        return false;
        
    }
    
    return true;

}

// Right-clicking a note
qc.noteRightClick = function(event,elem,calObj)
{
    
    // Get guid
    var guid = false;
    if(typeof(elem) != 'undefined'){
        guid = calObj.getGuidFromClass(elem.className);
    }
    
    if(guid != false){
        
        var html = "<ul>";
        html += "<li><a href='#' onclick='qc.noteEditDialog(\"" + elem.className + "\"," + calObj.getInstanceNameFromId() + ");return false;'>Edit</a></li>";
        html += "<li><a href='#' onclick='qc.deleteNote(\"" + guid + "\",false," + calObj.getInstanceNameFromId() + ");return false;'>Delete</a></li>";
        html += "</ul>";
        return qc.contextMenu(event,this,html);
        
    }
    
    return true;
}

// Right-clicking a project on the production side of things
qc.productionProjectRightClick = function(event,elem,calObj)
{
    
    // Get guid
    var guid = false;
    if(typeof(elem) != 'undefined'){
        guid = calObj.getGuidFromClass(elem.className);
    }
    
    if(guid != false){
        
        // Get menu options for this project with Ajax
        var pars = {
            opt: 'getProjectMenuHTML',
            type: 'production',
            guid: guid
        };
        $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
            qc.calRightClickResponse(data, event, elem);
        });
        
        // Loading context menu
        return qc.contextMenuLoading(event);
        
    }
    
    return true;
    
}

// Generic context menu Ajax response for the calendars
qc.calRightClickResponse = function(originalRequest, event, elem)
{
    
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    if (
        result.status == 1 && 
        typeof(result.data.html) == 'string'
    ) {
       
        if(typeof(result.data.sub_class) != 'undefined'){
            
            // Only replacing part of the menu (a sub menu)
            var menu = qc.getContextMenu();
            if(menu.size()){
                menu
                    .find("." + result.data.sub_class)
                    .html(result.data.html);
            }
            
        } else {
            
            // Replacing the whole menu
            return qc.contextMenu(event,elem,result.data.html);
            
        }
    }
    
}

// Launch a dialog to request an availability update for a crew/rental calendar
// TODO: still used?
// Peter Dekkers, September 2009
qc.requestAvailabilityUpdate = function(name, to_guid, from_guid)
{
    
    var html = "<p>Do you want to request a calendar update from " + name + "? They will be sent an email.</p>";
    
    // Buttons
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Yes',opt);
    opt = {
        extra_classes: "secondary_dialog_button"
    };
    button += " " + qc.button(2,'#','No',opt);
    opt = {
        cssClass: "primary"
    };
    html += qc.buttonBlock(button,opt);
    opt = {
        cssClass: "primary loading_container",
        style: "display: none;"
    };
    html += qc.buttonBlock("",opt);
    
    // Dialog
    var dialog = qc.createDialogNode(html);
    var dialog_id = dialog.attr('id');
    dialog
        .dialog("destroy")
        .dialog({
            dialogClass: "calendar_dialog",
            title: "Request Update"
        })
        .find(".primary_dialog_button")
        .click(function(){
            qc.dialogLoading(dialog_id, "Requesting...");
            // Request using Ajax
            var pars = {
                    opt: 'cal_request_update',
                    to_guid: to_guid,
                    from_guid: from_guid
                };
            $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
                qc.requestAvailabilityUpdateResponse(data,dialog_id);
            });
            
        })
        .end()
        .find(".secondary_dialog_button")
        .click(function(){
            $("#" + dialog_id)
                .dialog('close');
            return false;
        })
        .end();
    
}

qc.requestAvailabilityUpdateResponse = function(originalRequest,dialog_id)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 
    ) {
        
        // Show success message
        $("#" + dialog_id)
            .html("<p>Success!</p>");
        
    } else {
        
        qc.dialogError(dialog_id, "<p>" + result.message + "</p>");

    }
    
}

qc.calAvailabilityUpdate = function(calObj,guid,availability_type)
{
    
    // Hide context menu...
    qc.hideContextMenu();
    
    // Get selected days
    var dates = calObj.getSelectedTimestamps();
    if(dates.length < 1){
        qc.dialogError(undefined, "Please select a day (or days) on the calendar first. Tip: Right-click selection for options.");
        return;
    }
    
    // Put cal into loading mode
    calObj.loading(true);
    
    // Set the availability using Ajax
    var pars = {
            opt: 'cal_update_availability',
            guid: guid,
            availability_type: availability_type,
            dates: dates
        };
    $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
        qc.calAvailabilityUpdateResponse(data,calObj);
    });

}

qc.calAvailabilityUpdateResponse = function(originalRequest, calObj)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if(result.status == 1) {

        // Reload cal
        calObj.loadDays();
        
    } else {
        
        calObj.loading(false);
        qc.dialogError(undefined, "<p>" + result.message + "</p>");

    }
    
}

qc.calToggleOtherBookings = function(calObj, link)
{
    
    if(typeof(calObj) == "object"){
        
        // Turn loading on
        calObj.loading(true);
        
        // Send Ajax request to set session variable that will
        // be taken into account when loading the days for this calendar.
        var pars = {
                opt: 'cal_toggle_other_bookings',
                cal_id: calObj.id
            };
         
        // Fire it off
        $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
            qc.calToggleOtherBookingsResponse(data, calObj, link);
        });
            
    }
    
}

qc.calToggleOtherBookingsResponse = function(originalRequest, calObj, link)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if(result.status == 1 && typeof(result.data.booking_link_text) == "string") {

        // Update link text
        $(link).html(result.data.booking_link_text);

        // Reload cal
        calObj.loadDays();
        
    } else {
        
        calObj.loading(false);
        qc.dialogError(undefined, "<p>" + result.message + "</p>");

    }
    
}


//Shows a dialog box to edit a calendar note
qc.bookingViewCrewOnDay = function(elem_or_class_string, calObj)
{ 
   
  // Hide context menu...
  qc.hideContextMenu();
  
  // Get guid if it's an existing note
  var guid = false;
  if(typeof(elem_or_class_string) == 'string'){
      guid = calObj.getGuidFromClass(elem_or_class_string);
  } else if(typeof(elem_or_class_string) != 'undefined'){
      guid = calObj.getGuidFromClass(elem_or_class_string.className);
  }
  
  // Is there a parent guid in the options?
  var cn_parent_guid = false;
  if(typeof(opt) != "undefined" && typeof(opt.cn_parent_guid) != "undefined"){
      cn_parent_guid = opt.cn_parent_guid;
  }
  
  var day_info_obj = $("a.guid_" + guid).parent().parent();
  var day_title = day_info_obj.attr("title");
  
  var day_timestamp = calObj.getTimestampFromClass(day_info_obj.attr("class"));
  
  // Launch loading dialog
  var dialog_id = "bookings_on_day" + guid;
  var dialog = qc.createDialogNode("", dialog_id);
  dialog
      .dialog("destroy")
      .dialog({
          //dialogClass: "calendar_dialog",
          title: "Crew bookings on " + day_title
      });
  qc.dialogLoading(dialog);

  // Fire Ajax to update its contents
  var pars = {
          opt: 'cal_get_bookings_on_day',
          guid: guid,
          date: day_timestamp,
          pr_id: $(document.getElementById("current_pr_id")).val()
      };

  
  $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
      qc.bookingViewCrewOnDayResponse(data, calObj, dialog_id);
  });

  return false;
}

//Ajax response when viewing crew booked on day
qc.bookingViewCrewOnDayResponse = function(originalRequest, calObj, dialog_id)
{
     
     try {
         var result=originalRequest;
     } catch(exception) {
         alert(exception);
         alert(originalRequest);
     }
     
   
     if (
         result.status == 1 && 
         typeof(result.data.guid) != undefined && 
         typeof(result.data.html) != undefined
     ) {
         
         // Get dialog and add HTML
         var guid = result.data.guid;
         $("#" + dialog_id)
             .html(result.data.html)
             .end();
         
         $("#" + dialog_id)
             // Re-center
             .parents(".ui-dialog")
             .each(qc.reCenterDialog)
             .end();         
     } else {
         
         qc.closeDialog(dialog_id);
         qc.dialogError(undefined,result.message);
         
     }
 
}

/*------------------------------------
 * Callsheet interaction
 *------------------------------------*/

qc.callsheetDragdropInit = function()
{
    
    // Sort sections
    $("#callsheet_container")
        .find("th")
        .each(function(){
            var my_width = $(this).width();
            $(this)
                .attr("width", my_width);
            $(this).removeClass("filler");
        })
        .end()
        .sortable('destroy')
        .sortable({
           items: '.draggable_panel',
           axis: 'y',
           cursor: 'move',
           handle: '.box_header',
           revert: true,
           stop: function(event, ui) {
            
               // Get css ids in order
               var new_order = "";
               $(this)
                   .find('.draggable_panel table')
                   .each(function(){
   
                       // Get section ID
                       var css_id = $(this)
                           .attr("id")
                           .replace(/css_/, '');
                       
                       if(css_id > 0){
                           new_order += css_id + "|"; // Pipe separated cse_id
                                                        // values in order...
                       }
                       
                   });

               // Fire off Ajax to save new order
               var pars = {
                       opt: 'callsheet_reorder_sections',
                       new_order: new_order
                   };
               $.getJSON("/ajax-handler.php", pars);
            
           }
        });
        //.disableSelection();
    
}

qc.callsheetEntryAdd = function(entry_type, css_id, opt)
{
    // Hide context menu...
    qc.hideContextMenu();
    
    // Dialog title
    var dialog_title = 'Add to Callsheet';
    if(typeof(opt) != "undefined" && typeof(opt.title) != "undefined"){
        dialog_title = opt.title;
    }
    
    var parent_guid = false;
    if(typeof(opt) != "undefined" && typeof(opt.parent_guid) != "undefined"){       
        parent_guid = opt.parent_guid;
    }    

    
    // Launch loading dialog
    var dialog_id = "callsheet_add";
    var dialog = qc.createDialogNode("", dialog_id);
    dialog
        .dialog("destroy")
        .dialog({
            title: dialog_title,
            dialogClass: "callsheet_dialog",
            width: 500,
            maxHeight: 500,
            resizable: true
        });
    qc.dialogLoading(dialog);
    
    
     // Fire Ajax to update its contents
     var pars = {
             opt: 'callsheet_edit_dialog',
             entry_type: entry_type,
             css_id: css_id,
             parent_guid: parent_guid
         };
     
     // Are we editing? If so, add the record ID
     if(typeof(opt.cse_id) != "undefined"){
         pars.cse_id = opt.cse_id;
     }
     
     if(typeof(opt.csh_id) != "undefined"){
         pars.csh_id = opt.csh_id;
     }         
     
     // Fire it off
     $.getJSON("/ajax-handler.php", pars, qc.callsheetAddResponse);

     return false;
}

qc.callsheetAddResponse = function(originalRequest){
    var dialog_id = "callsheet_add";
    
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
        
    if (
        result.status == 1 &&
        typeof(result.data.html) != undefined
    ) {
                
        // Get dialog and add HTML
        $("#" + dialog_id)
            .html(result.data.html)
            // Add click functions to the buttons
            .find(".primary_dialog_button")
            .click(function(){
                qc.saveCallsheetEntry(dialog_id);
                return false;
            })
            .end()
            .find(".tertiary_dialog_button")
            .click(function(){
                $("#" + dialog_id).dialog("close");
                return false;
            })
            .end()
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog)
            .end()
            // Focus textarea
            .find("input[name='cse_column_1']")
            .focus()
            .end();
        
    } else {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(dialog_id, error_msg);
        
    }
    
}

qc.saveCallsheetEntry = function(dialog_id)
{
    // Get dialog
    var dialog = $("#" + dialog_id);
    
    // Put dialog into loading mode
    qc.dialogLoading(dialog_id,"Saving...");
       
    // Ajax parameters
    var pars = {
            opt: 'callsheet_save_entry',
            dialog_id: dialog_id
        };
        
    // Add form field values
    dialog
        .find("input, textarea")
        .each(function(){
            
            var input_name = $(this).attr("name");
            if(input_name != ''){
                
                var value = $(this).val();
                var elem_id = $(this).attr('id');
                
                // If it's a TinyMCE field we need to get the value in another way...
                if(elem_id != '' && typeof(tinyMCE) != "undefined" && tinyMCE.get(elem_id) != null){
                    value = tinyMCE.get(elem_id).getContent();
                    // Remove the editor once we have the value
                    tinyMCE.get(elem_id).remove();
                }
                
                // If it's a SWFUpload field we need to get the value in another way...
                if(input_name.indexOf("swfu_uploaded_file_guids_") > -1){
                    input_name = input_name.replace(/\[\]/,'');
                    if(typeof(pars[input_name]) == "undefined"){
                        pars[input_name] = new Object();
                    }
                    var size = 0, key;
                    for (key in pars[input_name]) {
                        if (pars[input_name].hasOwnProperty(key)) size++;
                    }
                    pars[input_name][size] = value;
                } else {
                    pars[input_name] = value;
                }
            }
            
        });
          
    // Save it using ajax
    // using post because of big texts
    $.post("/ajax-handler.php", pars, qc.saveCallsheetEntryResponse,"json");
    
    
}

// Ajax response to saving a callsheet section
qc.saveCallsheetEntryResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        // Success or form error?
        if(typeof(result.data.errors) != "undefined"){
            
            // Form error
            // Fire Ajax to update the form
            var pars = result.data; // Get all the data
            pars.opt = "callsheet_edit_dialog"; // Add the opt
            
            $.getJSON("/ajax-handler.php", pars, qc.callsheetAddResponse);
            
        } else {
                        
            // Successful save
            // Redraw the section in question
            $("#css_" + result.data.css_id)
                .replaceWith(result.data.html);
            
            // Refresh reorderables
            qc.callsheetDragdropInit();
                                    
            // Close the dialog
            qc.closeDialog(result.data.dialog_id);
            
        }
        
    } else if (typeof(result.data.dialog_id) == 'string') {
                
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
}


// Delete
qc.callsheetEntryDelete = function(cse_id, css_id, opt)
{
    
    // Hide content menu
    qc.hideContextMenu();
    
    // Confirmation dialog
    var html = "<p>Are you sure that you want to delete this entry?</p>";
    
    // Buttons
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Yes',opt);
    opt = {
        extra_classes: "secondary_dialog_button"
    };
    button += " " + qc.button(2,'#','No',opt);
    opt = {
        cssClass: "primary"
    };
    html += qc.buttonBlock(button,opt);
    opt = {
        cssClass: "primary loading_container",
        style: "display: none;"
    };
    html += qc.buttonBlock("",opt);
    
    // Dialog
    var title = "Delete";
    if(typeof(opt) != "undefined" && typeof(opt.title) != "undefined"){
        title = opt.title;
    }
    var dialog = qc.createDialogNode(html, "callsheet_delete_entry");
    dialog_id = dialog.attr('id');
    dialog
        .dialog("destroy")
        .dialog({
            dialogClass: "callsheet_dialog",
            title: title
        })
        .find(".primary_dialog_button")
        .click(function(){
            qc.dialogLoading(dialog_id, "Deleting...");
            // Request using Ajax
            var pars = {
                    opt: 'callsheet_delete_entry',
                    dialog_id: dialog_id,
                    cse_id: cse_id,
                    css_id: css_id
                };
            $.getJSON("/ajax-handler.php", pars, qc.callsheetEntryDeleteResponse);
            return false;
        })
        .focus()
        .end()
        .find(".secondary_dialog_button")
        .click(function(){
            $("#" + dialog_id)
                .dialog('close');
            return false;
        })
        .end();
    
}

qc.callsheetEntryDeleteResponse = function(originalRequest)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.html) != "undefined"
    ) {
        
        // Successful delete
        // Redraw the section in question
        $("#css_" + result.data.css_id)
            .replaceWith(result.data.html);
        
        // Refresh reorderables
        qc.callsheetDragdropInit();
        
        // Close the dialog
        qc.closeDialog(result.data.dialog_id);
                    
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
    
}

qc.callsheetAddSection = function(css_id)
{
    
    // Make sure menu is closed after return false;
    qc.closeMainMenus();
    
    // Hide context menu...
    qc.hideContextMenu();
    
    if(typeof(css_id) == undefined) {
        css_id = false;        
    }
    
    // Launch loading dialog
    var dialog_id = "callsheet_add_section";
    var dialog = qc.createDialogNode("", dialog_id);
    dialog
        .dialog("destroy")
        .dialog({
            title: 'Add Section',
            dialogClass: "callsheet_dialog",
            width: 500
        });
    qc.dialogLoading(dialog);
    
    // Get pr_id
    var css_pr_id = $("#css_pr_id").val();
    if(!css_pr_id > 0){
        
        qc.dialogError(undefined, "Couldn't find css_pr_id value!");
        
    } else {

        // Fire Ajax to update its contents
        var pars = {
                opt: 'callsheet_add_section',
                css_pr_id: css_pr_id,
                css_id: css_id
            };
         
        // Fire it off
        $.getJSON("/ajax-handler.php", pars, qc.callsheetAddSectionResponse);
        
    }

    return false;
    
}

qc.callsheetAddSectionResponse = function(originalRequest)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.html) != "undefined"
    ) {
        
        // Get dialog and add HTML
        $("#callsheet_add_section")
            .html(result.data.html)
            // Add click functions to the buttons
            .find(".primary_dialog_button")
            .click(function(){
                qc.saveCallsheetSection();
                return false;
            })
            .end()
            .find(".tertiary_dialog_button")
            .click(function(){
                $("#callsheet_add_section").dialog("close");
                return false;
            })
            .end()
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog)
            .end()
            // Focus textarea
            .find("input[name='css_title']")
            .focus()
            .end();
                            
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
    
}

qc.saveCallsheetSection = function()
{
    // Get dialog
    var dialog = $("#callsheet_add_section");
    
    // Put dialog into loading mode
    qc.dialogLoading("callsheet_add_section","Saving...");
    
    // Ajax parameters
    var pars = {
            opt: 'callsheet_save_section'
        };
    
    // Add form field values
    dialog
        .find("input, textarea")
        .each(function(){
            
            var input_name = $(this).attr("name");
            if(input_name != ''){
                
                var value = $(this).val();
                var elem_id = $(this).attr('id');

                // If it's a TinyMCE field we need to get the value in another way...
                if(elem_id != '' && typeof(tinyMCE) != "undefined" && tinyMCE.get(elem_id) != null){
                    value = tinyMCE.get(elem_id).getContent();
                    // Remove the editor once we have the value
                    tinyMCE.get(elem_id).remove();
                }
                
                // If it's a SWFUpload field we need to get the value in another way...
                if(input_name.indexOf("swfu_uploaded_file_guids_") > -1){
                    input_name = input_name.replace(/\[\]/,'');
                    if(typeof(pars[input_name]) == "undefined"){
                        pars[input_name] = new Object();
                    }
                    var size = 0, key;
                    for (key in pars[input_name]) {
                        if (pars[input_name].hasOwnProperty(key)) size++;
                    }
                    pars[input_name][size] = value;
                } else {
                    pars[input_name] = value;
                }
                
            }
            
        });
    
    // Save it using ajax
    $.getJSON("/ajax-handler.php", pars, qc.saveCallsheetSectionResponse);
    
}

qc.saveCallsheetSectionResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        // Success or form error?
        if(typeof(result.data.errors) != "undefined"){
            
            // Form error
            // Fire Ajax to update the form
            var pars = result.data; // Get all the data
            pars.opt = "callsheet_add_section"; // Add the opt
            
            $.getJSON("/ajax-handler.php", pars, qc.callsheetAddSectionResponse);
            
        } else {
            
            // Successful save
            // Append or replace the section
            var css_id = result.data.css_id;
            
            var existing_table = $("#css_" + css_id);
            if(existing_table.size() > 0){
                // Existing
                existing_table
                    .parents(".draggable_panel")
                    .html(result.data.html);
            } else {
                // New
                $("#callsheet_container")
                    .append(result.data.html);
                // TODO: add section collapse/expand JS to title bar
                // Scroll there
                var targetOffset = $("#callsheet_container .draggable_panel:last")
                                        .offset()
                                        .top;
                $('html,body')
                    .animate({scrollTop: targetOffset}, 1000);
            }
            
            // Refresh reorderables
            qc.callsheetDragdropInit();
                                    
            // Close the dialog
            qc.closeDialog("callsheet_add_section");
            
        }
        
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);   
        
    }
}


qc.callsheetDeleteSection = function(css_id)
{

    // Hide content menu
    qc.hideContextMenu();
    
    // Confirmation dialog
    var html = "<p>Are you sure you want to delete this section?<br />All entries on this section will be deleted and they can't be recovered.</p>";
    
    // Buttons
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Yes',opt);
    opt = {
        extra_classes: "secondary_dialog_button"
    };
    button += " " + qc.button(2,'#','No',opt);
    opt = {
        cssClass: "primary"
    };
    html += qc.buttonBlock(button,opt);
    opt = {
        cssClass: "primary loading_container",
        style: "display: none;"
    };
    html += qc.buttonBlock("",opt);
    
    // Dialog
    var title = "Delete section";
    if(typeof(opt) != "undefined" && typeof(opt.title) != "undefined"){
        title = opt.title;
    }
    var dialog = qc.createDialogNode(html, "callsheet_section_delete");
    dialog_id = dialog.attr('id');
    dialog
        .dialog("destroy")
        .dialog({
            dialogClass: "callsheet_dialog",
            title: title
        })
        .find(".primary_dialog_button")
        .click(function(){
            qc.dialogLoading(dialog_id, "Deleting...");
            // Request using Ajax
            var pars = {
                    opt: 'callsheet_delete_section',
                    dialog_id: dialog_id,
                    css_id: css_id
                };
            $.getJSON("/ajax-handler.php", pars, qc.callsheetDeleteSectionResponse);
            return false;
        })
        .focus()
        .end()
        .find(".secondary_dialog_button")
        .click(function(){
            $("#" + dialog_id)
                .dialog('close');
            return false;
        })
        .end();
}

qc.callsheetDeleteSectionResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        // Successful delete
        // Append or replace the section
        var css_id = result.data.css_id;
        
        //remove table
        var existing_table = $("#section_panel_" + css_id);
        if(existing_table.size() > 0){
            existing_table.fadeOut();
        }
        
        // Refresh reorderables
        qc.callsheetDragdropInit();        
        
        // Close the dialog
        qc.closeDialog("callsheet_add_section");
        qc.closeDialog(result.data.dialog_id);
       
                    
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
    
}


/*------------------------------------
 * Workbook interaction
 *------------------------------------*/
 
qc.workbookDeleteFile = function(fileGuid) {
    
 // Hide content menu
    qc.hideContextMenu();
    
    // Confirmation dialog
    var html = "<p>Are you sure that you want to delete this file?</p>";
    
    // Buttons
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Yes',opt);
    opt = {
        extra_classes: "secondary_dialog_button"
    };
    button += " " + qc.button(2,'#','No',opt);
    opt = {
        cssClass: "primary"
    };
    html += qc.buttonBlock(button,opt);
    opt = {
        cssClass: "primary loading_container",
        style: "display: none;"
    };
    html += qc.buttonBlock("",opt);
    
    // Dialog
    var title = "Delete";
    var dialog = qc.createDialogNode(html, "workbook_delete_file");
    dialog_id = dialog.attr('id');
    dialog
        .dialog("destroy")
        .dialog({
            dialogClass: "workBookText_dialog",
            title: title
        })
        .find(".primary_dialog_button")
        .click(function(){
            qc.dialogLoading(dialog_id, "Deleting...");
            // Request using Ajax
            var pars = {
                    opt: 'workbook_delete_file',
                    dialog_id: 'workbook_delete_file',
                    file_guid: fileGuid
            };
            
            $.getJSON("/ajax-handler.php", pars, qc.workbookTextFileDeleteResponse);
            
            return false;
        })
        .focus()
        .end()
        .find(".secondary_dialog_button")
        .click(function(){
            $("#" + dialog_id)
                .dialog('close');
            return false;
        })
        .end();        
 } 

qc.workbookTextFileDeleteResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    
    if (result.status == 1) {
        
        // Successful delete
        
        // Close the dialog
        qc.closeDialog(result.data.dialog_id);
        
        // Redraw the section in question
        $("#file_" + result.data.fileGuid).fadeOut();        
                    
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
    
}

qc.workbookDragdropInit = function() {
    // Sort sections   
    $("#workbook_wrapper")
        .sortable('destroy')
        .sortable({
            items: '.ws_container',
            axis: 'y',
            cursor: 'move',
            handle: '.box_header',
            revert: true,
            stop: function(event, ui) {
        		
        		var ordered_items = $("#workbook_wrapper").sortable('toArray');
        		
	            // Get ws ids in order
	            var new_order = "";
	            for(i=0; i<ordered_items.length; i++){
	            	
	            	ordered_items[i] = ordered_items[i].replace(/ws_container_/, '');
	            	if(ordered_items[i] > 0){
	            		new_order += ordered_items[i] + "|"; // Pipe separated ws_id
	            	}
	            	
	            }
	            	
	            // Fire off Ajax to save new order
	            var pars = {
	                    opt: 'workbook_reorder_sections',
	                    new_order: new_order
	                };
	            $.getJSON("/ajax-handler.php", pars);
        	
           }
        });
}

qc.setWorkbookTargetting = function(wb_id, status) {
    $("input[name^=wb_notifying\[crew\]\[" + wb_id + "\]]").each(function() {
        if(status){
            $(this).attr('checked','checked');
        } else {
            $(this).removeAttr("checked");
        }
    });
}

qc.workbookNotifyingDialog = function() {   
    // Hide context menu...
    qc.hideContextMenu();
    
    // Dialog title
    var dialog_title = 'Notifying';
    
    // Launch loading dialog
    var dialog_id = "workbook_notifying";
    var dialog = qc.createDialogNode("", dialog_id);
    dialog
        .dialog("destroy")
        .dialog({
            title: dialog_title,
            width: 500, 
            resizable: true
        });
    qc.dialogLoading(dialog);
    
     // Fire Ajax to update its contents
     var pars = {
             opt: 'workbook_notifying_dialog',
             wb_guid: $("#wb_guid")
             		     .val()
                         .replace(/guid_/, '')
         };
     
     // Fire it off
     $.getJSON("/ajax-handler.php", pars, qc.workbookNotifyingResponse);

     return false;
}

qc.workbookNotifyingResponse = function(originalRequest) {
    var dialog_id = "workbook_notifying";
   
    
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }        
   
    if (
        result.status == 1 &&
        typeof(result.data.html) != undefined
    ) {
                
        // Get dialog and add HTML
        $("#" + dialog_id)
            .html(result.data.html)
            // Add click functions to the buttons
            .find(".primary_dialog_button")
            .click(function(){
                qc.saveWorkbookNotifying(dialog_id,result.data.workbook_id);
                return false;
            })
            .end()
            .find(".secondary_dialog_button")
            .not("#clear-all-button")
            .click(function(){
                $("#" + dialog_id).dialog("close");
                return false;
            })
            .end()
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog)
            .end();
        
    } else {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(dialog_id, error_msg);
        
    }   
}

qc.saveWorkbookNotifying = function(dialog_id) {
    // Get dialog
    var dialog = $("#" + dialog_id);
    
    // Put dialog into loading mode
    qc.dialogLoading(dialog_id,"Saving...");
    
    // Ajax parameters
    var pars = {
            opt: 'workbook_save_notifying',
            dialog_id: dialog_id,
            wb_guid: $("#wb_guid")
					    .val()
			            .replace(/guid_/, '')
        };
    
    
    // Add form field values
    dialog
        //.find("input[name^=targetting]")
        .find("input:checkbox")
        .each(function(){
            var input_name = $(this).attr("name");
            if(input_name != '' && $(this).attr("checked")){
                
                var value = $(this).val();
                var elem_id = $(this).attr('id');

                // Set value
                pars[input_name] = value;

            }
            
        });
    

    // Save it using ajax
    $.getJSON("/ajax-handler.php", pars, qc.saveWorkbookNotifyingResponse);    
}

qc.saveWorkbookNotifyingResponse = function(originalRequest) {
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
       
    if (result.status == 1) {        
        // Close the dialog
        qc.closeDialog(result.data.dialog_id);             
                    
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
    }
}

qc.workbookDeleteGallery = function(galleryGuid) {
    
    // Hide content menu
   qc.hideContextMenu();
   
   // Confirmation dialog
   var html = "<p>Are you sure that you want to delete this gallery?</p>";

   // Buttons
   var opt = {
       extra_classes: "primary_dialog_button"
   };
   var button = qc.button(1,'#','Yes',opt);
   opt = {
       extra_classes: "secondary_dialog_button"
   };
   button += " " + qc.button(2,'#','No',opt);
   opt = {
       cssClass: "primary"
   };
   html += qc.buttonBlock(button,opt);
   opt = {
       cssClass: "primary loading_container",
       style: "display: none;"
   };
   html += qc.buttonBlock("",opt);
   
   // Dialog
   var title = "Delete";
   var dialog = qc.createDialogNode(html, "workbook_delete_gallery");
   dialog_id = dialog.attr('id');
   dialog
       .dialog("destroy")
       .dialog({
           title: title
       })
       .find(".primary_dialog_button")
       .click(function(){
           qc.dialogLoading(dialog_id, "Deleting...");
           // Request using Ajax
           var pars = {
                   opt: 'workbook_delete_gallery',
                   dialog_id: 'workbook_delete_gallery',
                   gallery_guid: galleryGuid
           };
           
           $.getJSON("/ajax-handler.php", pars, qc.workbookGalleryDeleteResponse);
           
           return false;
       })
       .focus()
       .end()
       .find(".secondary_dialog_button")
       .click(function(){
           $("#" + dialog_id)
               .dialog('close');
           return false;
       })
       .end();        
} 

qc.workbookGalleryDeleteResponse = function(originalRequest)
{
   try {
       var result=originalRequest;
   } catch(exception) {
       alert(exception);
       alert(originalRequest);
   }
   
   if (result.status == 1) {
       
       // Successful delete
       
       // Close the dialog
       qc.closeDialog(result.data.dialog_id);
       
       // Redraw the section in question
       $("#file_" + result.data.galleryGuid).fadeOut();        
                   
   } else if (typeof(result.data.dialog_id) == 'string') {
       
       var error_msg = undefined;
       if(typeof(result.message) == "string"){
           error_msg = "<p>" + result.message + "</p>";
       }
       
       qc.dialogError(result.data.dialog_id, error_msg);
       
   }
}

qc.imageGalleryDeletePhoto = function(imageGuid) {
    
    // Hide content menu
   qc.hideContextMenu();
   
   // Confirmation dialog
   var html = "<p>Are you sure that you want to delete this image?</p>";
   
   // Buttons
   var opt = {
       extra_classes: "primary_dialog_button"
   };
   var button = qc.button(1,'#','Yes',opt);
   opt = {
       extra_classes: "secondary_dialog_button"
   };
   button += " " + qc.button(2,'#','No',opt);
   opt = {
       cssClass: "primary"
   };
   html += qc.buttonBlock(button,opt);
   opt = {
       cssClass: "primary loading_container",
       style: "display: none;"
   };
   html += qc.buttonBlock("",opt);
   
   // Dialog
   var title = "Delete";
   var dialog = qc.createDialogNode(html, "gallery_delete_image");
   dialog_id = dialog.attr('id');
   dialog
       .dialog("destroy")
       .dialog({
           title: title
       })
       .find(".primary_dialog_button")
       .click(function(){
           qc.dialogLoading(dialog_id, "Deleting...");
           // Request using Ajax
           var pars = {
                   opt: 'gallery_delete_image',
                   dialog_id: 'gallery_delete_image',
                   image_guid: imageGuid
           };
           
           $.getJSON("/ajax-handler.php", pars, qc.galleryDeleteImage);
           
           return false;
       })
       .focus()
       .end()
       .find(".secondary_dialog_button")
       .click(function(){
           $("#" + dialog_id)
               .dialog('close');
           return false;
       })
       .end();        
   
   return false;
}

qc.galleryDeleteImage = function(originalRequest)
{
   try {
       var result=originalRequest;
   } catch(exception) {
       alert(exception);
       alert(originalRequest);
   }
   
   if (result.status == 1) {
       
       // Successful delete
       
       // Close the dialog
       qc.closeDialog(result.data.dialog_id);
       
       // Redraw the section in question
       $("#image_" + result.data.imageGuid).fadeOut();        
                   
   } else if (typeof(result.data.dialog_id) == 'string') {
       
       var error_msg = undefined;
       if(typeof(result.message) == "string"){
           error_msg = "<p>" + result.message + "</p>";
       }
       
       qc.dialogError(result.data.dialog_id, error_msg);
       
   }
}

qc.saveImageGalleryName = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (result.status == 1) {
        guid = result.data.imageGuid;
        
        $("#title_holder_" + guid + " img").remove();
        $("#title_holder_" + guid).hide();              
        
        $("#p_" + guid).html(result.data.value);
        $("#p_" + guid).show();
        
    } else  {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(false, error_msg);        
    }
}

qc.toogleWorkbookFileStatus = function(fileGuid, objectType) {
    var pars = {
            opt: 'workbook_set_file_status',
            file_guid: fileGuid,
            object_type: objectType
    };
       
    $.post("/ajax-handler.php", pars, qc.workbookFileStatusReturn, "json");   
    
    return false;
}

qc.workbookToogleFileHistory = function(file_guid) {
    $("#wb_history_" + file_guid + " .wb_history_wrapper").toggle();       
    
    return false;
}

qc.workbookFileStatusReturn = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (result.status == 1) {
        file_guid = result.data.file_guid;
        
           if(result.data.class_set !== false) {
               $("#wb_status_" + file_guid).attr("class", result.data.class_set);
           }                                             
    } else  {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(false, error_msg);        
    }
}

qc.addWorkbookFileNote = function(fileGuid, type) {
    
    // Hide content menu
   qc.hideContextMenu();
   
   // Confirmation dialog
   var html = "";
   html += "<textarea id='wb_file_note' class='large'></textarea>"
       
   // Buttons
   var opt = {
       extra_classes: "primary_dialog_button"
   };
   var button = qc.button(1,'#','Save',opt);
   opt = {
       extra_classes: "secondary_dialog_button"
   };
   button += " " + qc.button(2,'#','Cancel',opt);
   opt = {
       cssClass: "primary"
   };
   html += qc.buttonBlock(button,opt);
   opt = {
       cssClass: "primary loading_container",
   style: "display: none;"
   };
   html += qc.buttonBlock("",opt);

   // Dialog
   var title = "Add note";
   var dialog = qc.createDialogNode(html, "workbook_add_note");
   dialog_id = dialog.attr('id');
   dialog
       .dialog("destroy")
       .dialog({
           title: title
       })
       .find(".primary_dialog_button")
       .click(function(){
           text = $("#wb_file_note").val();
           
               if(text!= "") {
               qc.dialogLoading(dialog_id, "Saving...");
               // Request using Ajax
               var pars = {
                       opt: 'workbook_add_note_to_file',
                       dialog_id: 'workbook_add_note',
                       file_guid: fileGuid,
                       note: text
               };              
               
               $.getJSON("/ajax-handler.php", pars, qc.addWorkbookFileNoteReturn);
           }    
           return false;
       })
       //.focus()
       .end()
       .find(".secondary_dialog_button")
       .click(function(){
           $("#" + dialog_id)
               .dialog('close');
           return false;
       })
       .end();
   
   $("#wb_file_note").focus();
   
   return false;
}

qc.addWorkbookFileNoteReturn = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (result.status == 1) {
        file_guid = result.data.file_guid;
               
        $("#workbook_add_note")
            .dialog('close');

        
        if(result.data.text!="") {
        	var container = $("#wb_history_" + file_guid);
        	if(container.find(".wb_history_wrapper ul").size() == 0){
        		container.find(".wb_history_wrapper").append("<ul></ul>");
        	}
            $(container).find("ul").prepend(result.data.text);
        }
        
    } else  {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(false, error_msg);        
    }
}

qc.addWorkbookDeleteNote = function(noteId) {
    
    // Hide content menu
   qc.hideContextMenu();
   
   // Confirmation dialog
   var html = "<p>Are you sure you want to delete this note?</p>";
   
   // Buttons
   var opt = {
       extra_classes: "primary_dialog_button"
   };
   var button = qc.button(1,'#','Yes',opt);
   opt = {
       extra_classes: "secondary_dialog_button"
   };
   button += " " + qc.button(2,'#','No',opt);
   opt = {
       cssClass: "primary"
   };
   html += qc.buttonBlock(button,opt);
   opt = {
       cssClass: "primary loading_container",
       style: "display: none;"
   };
   html += qc.buttonBlock("",opt);
   
   // Dialog
   var title = "Add note";
   var dialog = qc.createDialogNode(html, "workbook_delete_note");
   dialog_id = dialog.attr('id');
   dialog
       .dialog("destroy")
       .dialog({
           title: title
       })
       .find(".primary_dialog_button")
       .click(function(){          
           qc.dialogLoading(dialog_id, "Deleting...");
           // Request using Ajax
           var pars = {
                   opt: 'workbook_delete',
                   note_id: noteId
           };                        
           
           $.getJSON("/ajax-handler.php", pars, qc.addWorkbookDeleteNoteReturn);
   
           return false;
       })
       .focus()
       .end()
       .find(".secondary_dialog_button")
       .click(function(){
           $("#" + dialog_id)
               .dialog('close');
           return false;
       })
       .end();        
   
   return false;
}

qc.addWorkbookDeleteNoteReturn = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (result.status == 1) {
        note_guid = result.data.note_guid;
        
        $("#workbook_delete_note")
            .dialog('close');        
        
        $("#wb_text_" + note_guid).fadeOut();
        
    } else  {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(false, error_msg);        
    }
}

qc.workbookTargetingChange = function(turn_on, guid)
{
	// Check for values
	if(typeof(guid) == "undefined"){
		qc.dialogError(undefined, "Invalid request.");
		return;
	}
	
	// Make numeric
	if(turn_on == true){
		turn_on = 1;
	} else {
		turn_on = 0;
	}
		
	// Send off to Ajax
    var pars = {
            opt: 'workbook_targeting',
            guid: guid
    };

    $.getJSON("/ajax-handler.php", pars, qc.workbookTargetingChangeReturn);

    return false;
}

qc.workbookTargetingChangeReturn = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (result.status == 1) {
        $("#wb_crew_access_status").html(result.data.text);
        $("#wb_crew_access_link").html(result.data.action);
    } else {
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(false, error_msg);        
    }
}


qc.workbookAddSection = function(ws_id)
{
    
    // Make sure menu is closed after return false;
    qc.closeMainMenus();
    
    // Hide context menu...
    qc.hideContextMenu();
    
    // Get ws_id and title
    var dialog_title = 'Edit Section';
    if(typeof(ws_id) == undefined) {
    	ws_id = false;
    	dialog_title = 'Add Section';
    }
    
    // Launch loading dialog
    var dialog_id = "workbook_add_section";
    var dialog = qc.createDialogNode("", dialog_id);
    dialog
        .dialog("destroy")
        .dialog({
            title: dialog_title,
            dialogClass: "workbook_dialog",
            width: 500
        });
    qc.dialogLoading(dialog);

    // Get wb_id
    var wb_id = $("#wb_id").val();
    if(!wb_id > 0){
        
        qc.dialogError(undefined, "Couldn't find wb_id value!");
        
    } else {

        // Fire Ajax to update its contents
        var pars = {
                opt: 'workbook_add_section',
                wb_id: wb_id,
                ws_id: ws_id
            };
         
        // Fire it off
        $.getJSON("/ajax-handler.php", pars, function (data, textStatus) {
        	qc.workbookAddSectionResponse(data);
        });
        
    }

    return false;
    
}

qc.workbookAddSectionResponse = function(originalRequest)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1 &&
        typeof(result.data.html) != "undefined"
    ) {
        
        // Get dialog and add HTML
        $("#workbook_add_section")
            .html(result.data.html)
            // Add click functions to the buttons
            .find(".primary_dialog_button")
            .click(function(){
                qc.saveWorkbookSection();
                return false;
            })
            .end()
            .find(".tertiary_dialog_button")
            .click(function(){
                $("#workbook_add_section").dialog("close");
                return false;
            })
            .end()
            // Re-center
            .parents(".ui-dialog")
            .each(qc.reCenterDialog)
            .end()
            // Focus textarea
            .find("input[name='ws_title']")
            .focus()
            .end();
                            
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
    
}

qc.saveWorkbookSection = function()
{
    // Get dialog
    var dialog = $("#workbook_add_section");
    
    // Put dialog into loading mode
    qc.dialogLoading("workbook_add_section","Saving...");
    
    // Get wb_id
    var wb_id = $("#wb_id").val();
    if(!wb_id > 0){
        
        qc.dialogError(undefined, "Couldn't find wb_id value!");
        
    } else {
    
	    // Ajax parameters
	    var pars = {
	            opt: 'workbook_save_section',
	            wb_id: wb_id
	        };
	    
	    // Add form field values
	    dialog
	        .find("input, textarea")
	        .each(function(){
	            
	            var input_name = $(this).attr("name");
	            if(input_name != ''){
	                
	                var value = $(this).val();
	                var elem_id = $(this).attr('id');
	
	                // If it's a TinyMCE field we need to get the value in another way...
	                if(elem_id != '' && typeof(tinyMCE) != "undefined" && tinyMCE.get(elem_id) != null){
	                    value = tinyMCE.get(elem_id).getContent();
	                    // Remove the editor once we have the value
	                    tinyMCE.get(elem_id).remove();
	                }
	                
	                // If it's a SWFUpload field we need to get the value in another way...
	                if(input_name.indexOf("swfu_uploaded_file_guids_") > -1){
	                    input_name = input_name.replace(/\[\]/,'');
	                    if(typeof(pars[input_name]) == "undefined"){
	                        pars[input_name] = new Object();
	                    }
	                    var size = 0, key;
	                    for (key in pars[input_name]) {
	                        if (pars[input_name].hasOwnProperty(key)) size++;
	                    }
	                    pars[input_name][size] = value;
	                } else {
	                    pars[input_name] = value;
	                }
	                
	            }
	            
	        });
	    
	    // Save it using ajax
	    $.getJSON("/ajax-handler.php", pars, qc.saveWorkbookSectionResponse);
	    
    }
    
}

qc.saveWorkbookSectionResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        // Success or form error?
        if(typeof(result.data.errors) != "undefined"){
            
            // Form error
            // Fire Ajax to update the form
            var pars = result.data; // Get all the data
            pars.opt = "workbook_add_section"; // Add the opt
            
            $.getJSON("/ajax-handler.php", pars, qc.workbookAddSectionResponse);
            
        } else {

            // Successful save
            // Append a new section or replace the section title
            var ws_id = result.data.ws_id;
            
            var existing_section = $("#ws_container_" + ws_id);
            if(existing_section.size() > 0){
                // Existing
            	existing_section
                    .find("#ws_title_" + ws_id)
                    .html(result.data.html);
            } else {
                // New
    		    var reload_url = String(window.location).replace("#","");;
    		    if(reload_url.search(/\?/) == -1){
    		    	reload_url += "?";
    		    } else {
    		    	reload_url += "&amp;";
    		    }
    		    reload_url += "workbook_scroll=1";
                window.location = reload_url;
                return;
            }
                                    
            // Close the dialog
            qc.closeDialog("workbook_add_section");
        }
        
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);   
        
    }
}

qc.workbookDeleteSection = function(ws_id)
{

    // Hide content menu
    qc.hideContextMenu();
    
    // Confirmation dialog
    var html = "<p>Are you sure you want to delete this section?<br />All entries on this section will be deleted and they can't be recovered.</p>";
    
    // Buttons
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Yes',opt);
    opt = {
        extra_classes: "secondary_dialog_button"
    };
    button += " " + qc.button(2,'#','No',opt);
    opt = {
        cssClass: "primary"
    };
    html += qc.buttonBlock(button,opt);
    opt = {
        cssClass: "primary loading_container",
        style: "display: none;"
    };
    html += qc.buttonBlock("",opt);
    
    // Dialog
    var title = "Delete section";
    if(typeof(opt) != "undefined" && typeof(opt.title) != "undefined"){
        title = opt.title;
    }
    var dialog = qc.createDialogNode(html, "workbook_section_delete");
    dialog_id = dialog.attr('id');
    dialog
        .dialog("destroy")
        .dialog({
            dialogClass: "workbook_dialog",
            title: title
        })
        .find(".primary_dialog_button")
        .click(function(){
            qc.dialogLoading(dialog_id, "Deleting...");
            // Request using Ajax
            var pars = {
                    opt: 'workbook_delete_section',
                    dialog_id: dialog_id,
                    ws_id: ws_id
                };
            $.getJSON("/ajax-handler.php", pars, qc.workbookDeleteSectionResponse);
            return false;
        })
        .focus()
        .end()
        .find(".secondary_dialog_button")
        .click(function(){
            $("#" + dialog_id)
                .dialog('close');
            return false;
        })
        .end();
}

qc.workbookDeleteSectionResponse = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        
        // Successful delete
        // Append or replace the section
        var ws_id = result.data.ws_id;
        
        // remove container
        var existing_table = $("#ws_container_" + ws_id);
        if(existing_table.size() > 0){
            existing_table.fadeOut();
        } 
        
        // Close the dialog
        qc.closeDialog("workbook_add_section");
        qc.closeDialog(result.data.dialog_id);
       
                    
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
    
}

qc.toogleAllWorkbookFilesStatus = function(obj_id, shortlist_all, type) {
    if (shortlist_all == true) {
        shortlist_all = 1;
    } else {        
        shortlist_all = 0;
    }
    
    var pars = {
            opt: 'workbook_set_all_file_status',
            obj_id: obj_id,
            status: shortlist_all,
            type: type
    };
       
    $.post("/ajax-handler.php", pars, qc.workbookAllFilesStatusReturn, "json");   
    
    return false;
}

qc.workbookAllFilesStatusReturn = function(originalRequest)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    if (
        result.status == 1
    ) {
        if(result.data.class_set !== false) {
            for (i=0; i<result.data.files.length; i++) {
                $(document.getElementById("wb_status_" + result.data.files[i])).attr("class", result.data.class_set);                
            }
        }
       
                    
    } else if (typeof(result.data.dialog_id) == 'string') {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(result.data.dialog_id, error_msg);
        
    }
    
}



/*----------------------------------------
 * Project booking interaction functions
 *----------------------------------------*/

qc.bookingAddToProject = function(button, pr_id, availability_percentage, ro_id, obj_guid)
{
     
     // Set button to loading state
     var random_id = qc.generateRandomId();
     $(button)
         .replaceWith("<span id='" + random_id + "' class='add_button add_button_adding' title='Adding...'><img src='/images/loading.gif' alt='Loading' /></span>");
     // Fire off status change request via Ajax
     var pars = {
             opt: 'booking_add',
             pr_id: pr_id,
             ro_id: ro_id,
             availability_percentage: availability_percentage,
             obj_guid: obj_guid
     };
     
     $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
         qc.bookingAddToProjectResponse(data, random_id);
     });
     
}

qc.bookingAddToProjectResponse = function(originalRequest, random_id)
{

    try {
       var result=originalRequest;
   } catch(exception) {
       alert(exception);
       alert(originalRequest);
   }
 
   // Clear the booking on screen
   if (result.status = 1 && typeof(result.data.button_html) == 'string') {
       
       // Show new button
       $("#" + random_id)
           .replaceWith(result.data.button_html);
       
   } else {
       
       // Error
       var error_msg = undefined;
       if(typeof(result.message) == "string"){
           error_msg = "<p>" + result.message + "</p>";
       }
       qc.dialogError(false, error_msg);
       
   }
    
}

qc.toggleUnavailableRows = function(child_elem)
{
    var table = $(child_elem).parents("table");
    if(table.size() > 0){
        table
            .find("tbody tr.toggle_unavailable_row")
            .each(function(){
                if($(this).css("display") == "none"){
                    $(this)
                        .show();
                } else {
                    $(this)
                        .hide()
                        .next(".hidden_row")
                        .hide();
                }
            });
    }
}

qc.bookingGetContainerFromBaseId = function(booking_container_base_id){
     var container = $("#" + booking_container_base_id + "_details");
     if(container.size()){
         return container;
     }
     qc.dialogError(undefined, "Can't find calendar container!");
     return false;
}

qc.bookingClear = function(booking_container_base_id)
{
        
    if((container = qc.bookingGetContainerFromBaseId(booking_container_base_id))){
        
        // Is there a booking ID?
        var bo_id = container
                        .find("#" + booking_container_base_id + "_bo_id")
                        .val();
        
        // Remove any possible BookingTemporary using Ajax
        if(bo_id > 0){
            var pars = {
                    opt: 'booking_clear_prepared',
                    bo_id: bo_id
            };
            
            $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
                qc.bookingClearRespsonse(data, booking_container_base_id, container);
            });
        } else {
            
            // We don't need Ajax, it's never been saved, just clear it
            var result = {
                status: 1
            };
            qc.bookingClearRespsonse(result, booking_container_base_id, container);
            
        }
        
        return true;
        
    }

    return false;
    
}

qc.bookingClearRespsonse = function(originalRequest, booking_container_base_id, container)
{
    try {
       var result=originalRequest;
   } catch(exception) {
       alert(exception);
       alert(originalRequest);
   }
 
   // Clear the booking on screen
   if (result.status = 1) {
       
       container
           // Clear booking note
           .find("#" + booking_container_base_id + "_booking_message")
           .val("")
           // Close booking note
           .parent()
           .hide()
           .end()
           .end()
           // Clear Booking ID
           .find("#" + booking_container_base_id + "_bo_id")
           .val("")
           .end()
           // Reset invite type
           .find("#" + booking_container_base_id + "_invite_type")
           .get(0)
           .selectedIndex = 0;
       
       // Clear invite text
       container
           .prev("tr")
           .find(".booking_invite_details")
           .html("");
           
       // Reset calendar
       qc.minical.clearRow(booking_container_base_id + "_cal");
       
   } else {
       
       var error_msg = undefined;
       if(typeof(result.message) == "string"){
           error_msg = "<p>" + result.message + "</p>";
       }
       
       qc.dialogError(false, error_msg);
       
   }
   
}

qc.bookingSavePreparedBooking = function(booking_container_base_id)
{
    
    if((container = qc.bookingGetContainerFromBaseId(booking_container_base_id))){
        
        // Get project ID
        var pr_id = $("#pr_id")
                        .val();

        // Get booking ID
        var bo_id = container
                        .find("#" + booking_container_base_id + "_bo_id")
                        .val();
        
        // Get role ID
        var ro_id = container
                        .find("#" + booking_container_base_id + "_ro_id")
                        .val();
        
        // Get bookable object ID
        var obj_id = container
                        .find("#" + booking_container_base_id + "_obj_id")
                        .val();
        
        // Get bookable object type
        var obj_type = container
                        .find("#" + booking_container_base_id + "_obj_type")
                        .val();
        
        // Get booking type
        var bo_type = container
                        .find("#" + booking_container_base_id + "_invite_type")
                        .val();
        
        // Get booking note
        var bo_message = container
                        .find("#" + booking_container_base_id + "_booking_message")
                        .val();
        
        // Get selected days
        var selected_days = container
                                .find("#" + booking_container_base_id + "_cal")
                                .find(".pencil, .firm");
                
        // Validate
        if(!obj_id > 0){
            qc.dialogError(undefined, "Couldn't find bookable object ID!");
            return false;
        }
        if(!obj_type.length > 0){
            qc.dialogError(undefined, "Couldn't find bookable object type!");
            return false;
        }
        if(!pr_id > 0){
            qc.dialogError(undefined, "Couldn't find project ID!");
            return false;
        }
        if(!bo_type > 0){
            qc.dialogError(undefined, "Please select an invite type!");
            return false;
        }
        if(selected_days.size() == 0){
            qc.dialogError(undefined, "Please select a day (or days) on the calendar first. Tip: Right-click selection for options.");
            return false;
        }
        
        // Prepare days for Ajax send
        var days = {};
        selected_days
            .each(function(){
                
                var my_date = $(this).find("span").attr("id").substr(0,10);
                if (match = $(this).attr("class").match(/[^A-z](d_[A-z-_]+)/)) {
                    days[my_date] = match[1].substr(2);
                }
                
            });
        
        // Try and save this with Ajax
        var pars = {
                opt: 'booking_save_prepared',
                pr_id: pr_id,
                ro_id: ro_id, 
                obj_id: obj_id,
                obj_type: obj_type,
                bo_type: bo_type,
                bo_id: bo_id,
                bo_message: bo_message,
                days: days
        };
        
        $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
            qc.bookingSavePreparedBookingResponse(data, booking_container_base_id);
        });
        
    }
    
    return false;
    
}

qc.bookingSavePreparedBookingResponse = function(originalRequest, booking_container_base_id)
{
    try {
       var result=originalRequest;
   } catch(exception) {
       alert(exception);
       alert(originalRequest);
   }
 
   if (result.status == 1 && typeof(result.data.bo_id) != "undefined") {

       // Saved...       
       if((container = qc.bookingGetContainerFromBaseId(booking_container_base_id))){
           
           // Update invite details
           container
               .prev("tr")
               .find(".booking_invite_details")
               .html(result.data.invite_details);
           
           // Update booking ID
           container
               .find("#" + booking_container_base_id + "_bo_id")
               .val(result.data.bo_id);
           
           // Close booking
           qc.tableToggleNextRow(container.prev("tr"));
           
       }
       
   } else {
       
       var error_msg = undefined;
       if(typeof(result.message) == "string"){
           error_msg = "<p>" + result.message + "</p>";
       }
       
       qc.dialogError(false, error_msg);
       
   }
}

qc.bookingDeletePrepared = function(row_id)
{
        
    // Get BookingTemporary ID
    if(typeof(row_id) == "string"){
        var bt_id = row_id.replace(/bt_id_/,'');
    } else {
        // TODO
        // This happens when the function is called from a generic
        // link above the table
        var bt_id = qc.tableGetSelectedRowValue(row_id);
        alert("todo");
    }
    
    // Delete with Ajax
    var pars = {
            opt: 'booking_delete_prepared',
            bt_id: bt_id
    };
    
    $.getJSON("/ajax-handler.php", pars, function(data, textStatus){
        qc.bookingDeletePreparedResponse(data, row_id);
    });
    
}

qc.bookingDeletePreparedResponse = function(originalRequest, row_id)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
  
    if (result.status == 1) {

        // Try and remove the row in question
        $("#" + row_id)
            .remove()
            .next("tr")
            .remove()
            // Re-stripe
            .parents("tbody")
            .find("tr")
            .removeClass("stripe")
            .end()
            .find("tr.visible_row:odd, tr.hidden_row:odd")
            .addClass("stripe");
        
    } else {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(false, error_msg);
        
    }
}

qc.bookingToggleSearchOptions = function(link_elem)
{
    // Get search options container
    var options_container = $("#booking_find_step_search_options");
    if(options_container.size()){
        
        // Show it
        if(options_container.css("display") == "none"){
            
            $(link_elem).html("Hide search options");
            options_container.fadeIn();
            
        // Hide it
        } else {

            $(link_elem).html("Show search options");
            options_container.fadeOut();

        }

    }

}

qc.bookingResizePanelsToFitCalendars = function()
{
    
    // Get first calendar
    var minical = $(".minical_for_user:first");
    
    // And only proceed if there one
    if(minical.size()){
        
        // Count number of days
        var number_of_days = minical.find(".d").size();
                
        // Calculate width
        qc.vars.minicalPanelTotalWidth = (number_of_days*qc.vars.minicalCellWidth) + minical.find(".invite_options").width() + 40;
        
        // Set the width of all panels, only if we need to increase the width
        var current_panel_width = $(".panel").width();
        if(current_panel_width < qc.vars.minicalPanelTotalWidth){
        
            // Resize panel
            $(".panel, .box_header, .box_footer")
                .width(qc.vars.minicalPanelTotalWidth);
            
            // Resize top nav
            $(".horizontal_sub_nav")
                .width(qc.vars.minicalPanelTotalWidth + 42);
            
        }
        
        // Resize any status messages underneath the calendars
        $(".invited_checked, .if_calendar, .if_invite")
            .width(minical.find(".minical").width() + minical.find(".invite_options").width());
        
    }
    
}

qc.bookingRemoveAllAdded = function(pr_guid)
{
    
    // Confirmation dialog
    var html = "<p>Are you sure you wish to remove all the uninvited crew and rentals from the project?</p>";
    var opt = {
        extra_classes: "primary_dialog_button"
    };
    var button = qc.button(1,'#','Remove',opt);
    opt = {
        extra_classes: "secondary_dialog_button"
    };
    button += " " + qc.button(2,'#','Cancel',opt);
    opt = {
        cssClass: "primary"
    };
    html += qc.buttonBlock(button,opt);
    opt = {
        cssClass: "primary loading_container",
        style: "display: none;"
    };
    html += qc.buttonBlock("",opt);
   
    var title = "Remove All";
    var dialog = qc.createDialogNode(html, "project_new_window");
    dialog_id = dialog.attr('id');
    dialog
        .dialog("destroy")
        .dialog({
            title: title
        })
        .find(".primary_dialog_button")
        .click(function(){
            qc.bookingRemoveAllAddedConfirm(pr_guid, dialog_id);
        })
        .focus()
        .end()
        .find(".secondary_dialog_button")
        .click(function(){
            $("#" + dialog_id)
                .dialog('close');
        })
        .focus()
        .end();
    
}

qc.bookingRemoveAllAddedConfirm = function(pr_guid, dialog_id)
{
    
    // Set dialog to loading mode
    qc.dialogLoading(dialog_id,"Removing...");
    
    // Send Ajax request
    var pars = {
            opt: 'booking_remove_all_added',
            pr_guid: pr_guid
    };
    $.post("/ajax-handler.php", pars, function(data, textMessage){
        qc.bookingRemoveAllAddedConfirmResponse(data,dialog_id);
    },"json");
    
}

qc.bookingRemoveAllAddedConfirmResponse = function(originalRequest, dialog_id)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    if (result.status == 1) {
        // Redirect to current page with success message
        var strLocation = window.location.toString();
        window.location = strLocation.substring(0, strLocation.indexOf("?")) + "?successmsg=Successfully removed all uninvited crew and rentals.";
    } else {
        qc.dialogError(false, result.message);
    }
    
}

qc.bookingRemove = function(bo_guid)
{
    // Send Ajax request
    var pars = {
            opt: 'booking_remove_single',
            bo_guid: bo_guid
    };
    $.post("/ajax-handler.php", pars, qc.bookingRemoveResponse,"json");
}

qc.bookingRemoveResponse = function(originalRequest)
{

    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    if (result.status == 1) {
        // Redirect to current page with success message
        var strLocation = window.location.toString();
        window.location = strLocation.substring(0, strLocation.indexOf("?")) + "?successmsg=Successfully removed uninvited crew or rental.";
    } else {
        qc.dialogError(false, result.message);
    }
    
}

qc.addChangeMessage = function(link, ch_id, dialog_title)
{
	// Launch dialog
    var dialog = qc.createDialogNode("", "change_message_dialog");
    dialog
        .dialog("destroy")
        .dialog({
            width: 450,
            title: dialog_title
        });
    
    // Set dialog to loading mode
    qc.dialogLoading("change_message_dialog","Loading...");
	
    // Send Ajax request to update dialog contents
    var pars = {
            opt: 'change_load_add_message',
            ch_id: ch_id
    };
    $.post("/ajax-handler.php", pars, function(data, textMessage) {
    	qc.addChangeMessageResponse(data, link, ch_id);
    },"json");
}

qc.addChangeMessageResponse = function(originalRequest, link, ch_id)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    if (	result.status == 1
    		&& typeof(result.data.html) != undefined
    ) {
            
            // Get dialog and add HTML
            $("#change_message_dialog")
                .html(result.data.html)
                // Add click functions to the buttons
                .find(".primary_dialog_button")
                .click(function(){
                    qc.saveChangeMessage(link, ch_id);
                    return false;
                })
                .end()
                .find(".secondary_dialog_button")
                .click(function(){
                    $("#change_message_dialog").dialog("close");
                    return false;
                })
                .end()
                // Focus textarea
                .find("textarea[name='ch_message']")
                .focus()
                .end()
                // Re-center
                .parents(".ui-dialog")
                .each(qc.reCenterDialog);
            
        } else {
            
            qc.closeDialog("#change_message_dialog");
            qc.dialogError(undefined,result.message);
            
        }
}

qc.saveChangeMessage = function(link, ch_id)
{
    // Get dialog
    var dialog = $("#change_message_dialog");
    
    // Get message value
    var message = dialog
        .find("textarea[name='ch_message']")
        .val();
    
    // Put dialog into loading mode
    qc.dialogLoading("change_message_dialog","Saving...");

    // Save it using ajax
    var pars = {
            opt: 'save_change_message',
            ch_id: ch_id,
            message: message
        };
        
    $.post("/ajax-handler.php", pars, function(data, textMessage){
    	qc.saveChangeMessageResponse(data, link, ch_id, dialog);
    },"json");
}

qc.saveChangeMessageResponse = function(originalRequest, link, ch_id, dialog)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    if (	result.status == 1
    		&& typeof(result.data.icon_html) != undefined
    ) {
    	
    	// Update icon
    	$(link)
    		.replaceWith(result.data.icon_html);
    	
    	// Close dialog
    	qc.closeDialog(dialog);
    	
    } else {
        
        qc.closeDialog(dialog);
        qc.dialogError(undefined,result.message);
        
    }
	
}


/*------------------------------------
 * Sharing pages functions
 *------------------------------------*/

//
//Called when a crew is clicked
//
qc.mailShareAdd = function(text){ 
    text = $.trim(text);
    
    var form_wrapper = $("#like_to_work_form_wrapper");
    form_wrapper.removeClass("error");
    
    var error_container = $("#mail_share_error");
    error_container.css("display","none");

    if(text == ""){        
        error_container
            .css("display","")
            .html("Please enter an e-mail address");
        form_wrapper
            .addClass("error");    
    } else {       
        $("#mail_share_list")
            .append("<li><input type='hidden' name='email_share[]' value='" + text + "' /> " + text + " <a href='#' onclick='qc.mailShareDelete(this); return false;'><small>Remove</small></a></li>");
        $('#mail_share_text')
            .val('');
    }
}


qc.mailShareDelete = function(a_obj) {
    $(a_obj)
        .parent("li")
        .remove(); 
}

qc.setPublicProject = function(guid, new_status) {
    
    var pars = {
            opt: 'project_set_public',
            value: new_status,
            pr_guid: guid
    };
    
    $.getJSON("/ajax-handler.php", pars, qc.publicStatusResponse);
    
    return false;
}

qc.publicStatusResponse = function(originalRequest)
{
    try {
       var result=originalRequest;
   } catch(exception) {
       alert(exception);
       alert(originalRequest);
   }
 
   
   if (result.status == 1) {
       $("#public-status").html(result.data.html);        
       if(result.data.isPublic) {
           $("#form-wrapper").fadeIn();
       } else {
           $("#form-wrapper").fadeOut();
       }
   } else {
       
       var error_msg = undefined;
       if(typeof(result.message) == "string"){
           error_msg = "<p>" + result.message + "</p>";
       }
       
       qc.dialogError(false, error_msg);
       
   }
}

/*------------------------------------
 * Profile sharing
 *------------------------------------*/

qc.getCrewIdFromContainer = function(container_id) {
    var row = qc.tableGetSelectedRow(container_id);
    if(row.size()) {
        row = row.attr("id");
        // Try and get container
        var container = $("#" + row);
        if(container.size() == 0){
            qc.dialogError(undefined, "Couldn't find row " + row + " in container " + container_id + "!");
            return false;
        }
        
        // Manually added crew?
        if(container.hasClass("manually_added")){
            qc.dialogError(undefined, "Sorry, this doesn't work for manually added crew.");
            return false;
        }
        
        // Try and get favourite_obj_id
        var user_container = container.find(".user_container");
        if(user_container.size() == 0){
            qc.dialogError(undefined, "Couldn't find crew id for " + container_id + "!");
            return false;
        }
        
        user_id = user_container.attr("id").replace(/user_id_/, "");
         
        return user_id;       
    }
    
    return false;
}

qc.shareCrewFromList = function(container_id) {
    qc.hideContextMenu();
          
    var crew_id = qc.getCrewIdFromContainer(container_id)
    
    if(crew_id) {
        qc.shareCrew(crew_id, false, null);
    }
}

qc.shareCrew = function(crewId, read_field, opt) {
    email_value = "";
    if(read_field != undefined && read_field != "") {
        email_value = $("#crew_share_profile_page").val();
    }
    
    mail_error = false;
    invalid_mail = false;
    
    if(opt != undefined) {
        if(opt.email != undefined && opt.email!="") {
            email_value = opt.email
        }
        
        if(opt.mail_error != undefined && opt.mail_error == true) {
            mail_error = true;
        }
        
        if(opt.invalid != undefined && opt.invalid == true) {
            invalid_mail = true;
        }        
    }
    
    // Hide context menu...
    qc.hideContextMenu();
    
    // Dialog title
    var dialog_title = 'E-mail profile to';
    var dialog_id = "crew_email_profile";
    
    // Launch loading dialog
    var dialog = qc.createDialogNode("", dialog_id);
    dialog
        .dialog("destroy")
        .dialog({
            title: dialog_title,
            width: 500, 
            resizable: true
        });
    qc.dialogLoading(dialog);
    
    // Fire Ajax to update its contents
    var pars = {
            opt: 'crew_share_get_html',
            share_profile_id: crewId,
            email: email_value,
            mail_error: mail_error,
            invalid_mail: invalid_mail
        };
     
    // Fire it off
    $.getJSON("/ajax-handler.php", pars, function(data, text){
        qc.shareCrewHTML(data, crewId);
    });
    
    return false;
}

qc.shareCrewHTML = function(originalRequest, crewId)
{
    try {
       var result=originalRequest;
   } catch(exception) {
       alert(exception);
       alert(originalRequest);
   }
 
   var dialog_id = "crew_email_profile"; 
   if (result.status == 1) {
    // Get dialog and add HTML
       $("#" + dialog_id)
           .html(result.data.html)
           // Add click functions to the buttons
           .find(".primary_dialog_button")
           .click(function(){
               qc.sendCrewInvite(dialog_id, crewId);
               return false;
           })
           .end()
           .find(".secondary_dialog_button")
           .click(function(){
               $("#" + dialog_id).dialog("close");
               return false;
           })
           .end()
           // Re-center
           .parents(".ui-dialog")
           .each(qc.reCenterDialog)
           .end()
           // Focus textarea
           .find("input[name='wo_txt_title']")
           .focus()
           .end();  
       
   } else {
       
       var error_msg = undefined;
       if(typeof(result.message) == "string"){
           error_msg = "<p>" + result.message + "</p>";
       }
       
       qc.dialogError(false, error_msg);
       
   }
}

qc.sendCrewInvite = function(dialog_id, crewId)
{
    // Get dialog
    var dialog = $("#" + dialog_id);
    
    // Put dialog into loading mode
    qc.dialogLoading(dialog_id,"Saving...");
    
    // Ajax parameters
    var pars = {
            opt: 'crew_share_send',
            dialog_id: dialog_id
        };
    
    // Add form field values
    dialog
        .find("input, textarea")
        .each(function(){
            
            var input_name = $(this).attr("name");
            if(input_name != ''){
                
                var value = $(this).val();
                var elem_id = $(this).attr('id');
                                
                // Set value
                pars[input_name] = value;

            }
            
        });

    // Save it using ajax
    $.getJSON("/ajax-handler.php", pars, function(data, text){
        qc.sendCrewResponse(data, crewId);
    });
    
    return false;
    
}

qc.sendCrewResponse = function(originalRequest, crewId)
{
    try {
        var result=originalRequest;
    } catch(exception) {
        alert(exception);
        alert(originalRequest);
    }
    
    var dialog_id = "crew_email_profile";
    
   
    if (result.status == 1) {
        
        // Successful share?

        if(result.data.success == true) {
            $("#crew_share_profile_page").val("");
            
            // Success dialog
            var opt = {
                onclick: '$("#' + dialog_id + '").dialog("close"); return false;'
            };
            var html = "<p>Email successfully sent!</p>";
            html += qc.buttonBlock(qc.button(1,"#","Close",opt));
            $("#" + dialog_id)
                .html(html)
               // Add click functions to the buttons
               .find(".primary_dialog_button")
               .click(function(){
                   $("#" + dialog_id).dialog("close");
                   return false;
               })
               .focus()
               .end();
        } else {
            opt = {
                    mail_error: result.data.mail_error,
                    email: result.data.email,
                    invalid: result.data.invalid_mail                    
            }
            qc.shareCrew(crewId, false, opt);                        
        }
       
                    
    } else {
        
        var error_msg = undefined;
        if(typeof(result.message) == "string"){
            error_msg = "<p>" + result.message + "</p>";
        }
        
        qc.dialogError(undefined, error_msg);
        
    }
    
}

/*------------------------------------
 *  Booked objects functions
 *------------------------------------*/

qc.goToSendMessagePage = function(pr_url, type, container_id, recipient_type) {
    var crew_id = qc.getCrewIdFromContainer(container_id);
        
    var obj_type = "";
    if(recipient_type == "crew") {
        obj_type = "auth_user_links";
    } else if(recipient_type == "rental") {
        obj_type = "rental_links";
    }
    
    if(crew_id && obj_type!="") {     
        window.location = pr_url + "/" + type + "/send/?" + obj_type + "["+ crew_id +"]=1";
    } else {
        error_msg = "<p>You can't send messages to manually added crew or rentals.</p>";
        qc.dialogError(undefined, error_msg);
    }
    
    return false;
    
}

/*------------------------------------
 *  Production Stills
 *------------------------------------*/

qcProductionStills_pictureShowing = null;
qcProductionStills_pictureShowingNumber = null;

qc.showProductionStills = function(direction) {
    if(qcProductionStills_pictureShowing == null) {
        qcProductionStills_pictureShowing = $(".production-stills:first");
        qcProductionStills_pictureShowingNumber = 1;
    }
       
    qcProductionStills_pictureShowing.hide();
    
    if(direction == "next") {
        qcProductionStills_pictureShowing = qcProductionStills_pictureShowing.next();
        qcProductionStills_pictureShowingNumber++;
    } else if(direction == "previous") {
        qcProductionStills_pictureShowing = qcProductionStills_pictureShowing.prev();
        qcProductionStills_pictureShowingNumber--;
    }
    
    if(qcProductionStills_pictureShowing.length < 1) {
        if(direction == "next") {
            qcProductionStills_pictureShowing = $(".production-stills:first");
            qcProductionStills_pictureShowingNumber = 1;
        } else if(direction == "previous") {
            qcProductionStills_pictureShowing = $(".production-stills:last");
            qcProductionStills_pictureShowingNumber = $(".production-stills").length;
        }        
    }
    
    qcProductionStills_pictureShowing.show();  
    $("#production-stills-photo-number").html(qcProductionStills_pictureShowingNumber);
       
    return false;
}
 
qc.showHowItWorksVideo = function(url, title) 
{
    video_holder = $("#flash_video_holder");
    
    video_holder.html("<span id='swf_video_holder'></span>");
    
    var flashvars = {
            video_url:              url
    };
    var params = {          
            allowscriptaccess       : "sameDomain",
            wmode                   : "transparent"            
    };
    var attributes = {
      id:   "swf_video",
      name: "swf_video"
    };

    swfobject.embedSWF("/images/videos/video_player.swf", "swf_video_holder", "640", "480", "9.0.0", false, flashvars, params, attributes);
    
    
    $('#videos_dialog1').dialog("option", "title", title);
    $('#videos_dialog1').dialog('open');
}



/*------------------------------------
 * onDOMReady code
 *------------------------------------*/

$(document).ready(function(){
    
    
    /*
     * Add some handy CSS classes
     */
    $('table.planner_head tr th:first-child, table.planner_body tr td:first-child').addClass('first');
    $('table.planner_head tr th:last-child, table.planner_body tr td:last-child').addClass('last');
    $('table.listing tr th:first-child, table.listing tr td:first-child').not(".has_handle").addClass('first');
    $('table.listing tr th:last-child, table.listing tr td:last-child').addClass('last');

    
    /* 
     * Main navigation
     */
     
     $('ul.sf-menu')
         .superfish({
             firstOnClick:  true,
             speed:         0,
             autoArrows:    false,
             dropShadows:   false,
             hoverClass:    "active",
             onBeforeShow:  function(){
                 if(qc.vars.contextShowing == true){
                     qc.hideContextMenu();
                 }
             }
         })
         // Disable clicks on the main level items
         .children('li:not(.no_sub)')
         .children('a')
         .click(function(){
             return false;
         });
    
    
    /*
     * Context menu init
     */
     
     $("#contextMenu").hide();
     
     /*
      * Modifier keys
      *
      * If we're on a Mac, replace the modifier key with "command" (the default is "control" for Win and Linux)
      */
      
      if(typeof(navigator.platform) == "string" && /Mac/.test(navigator.platform)){
          $(".modifier_key").html("command");
      }
      
      
     /*
      * Resize calendar panels to fit minical width on booking process
      */
     
     if(typeof(qc.vars.bookingResizePanels) != "undefined"){
         qc.bookingResizePanelsToFitCalendars();
     }

    

});












