// JavaScript Document

/*===============================================================


	INITIALISE JAVASCRIPT


==================================================================*/

/*===============================================================


	VERSION 2 OBJECTS


==================================================================*/

function LightBox()
{
    this.id = 'lightBox';
    this.contentType = null;
    this.youtubePlayerRef = null;
    this.html = '<div id="lightBoxOverlay" class="fsOverlay fsLightbox"><div id="lightBox" class="faAnimateStart fsOverlayBubbleShadow"><div class="fsOverlayBubble"><div id="lightBoxContentHolder" style="display:none;">loading...</div></div></div></div>';
    this.closeButtonHtml = '<span class="fsOverlayCloseButton"></span>';
    this.dimensions = {
        youtube: {
            width: 640,
            height: 360
        },
        image: {
            width: 600,
            height: 400
        }
    }

    this.open = function(contentType,contentId)
    {
        this.contentType = contentType;

        var width = this.dimensions[contentType].width;
        var height = this.dimensions[contentType].height;

        // add the HTML to the DOM
        $('#fsStatic').append(this.html);

        // get current margin top value
        var margin = $('#'+this.id).css('marginTop');
        margin = parseInt(margin.replace('px',''));

        // set the margin to be half the height of the lightbox further down the page
        $('#'+this.id).css('marginTop',(margin + (height / 2))+'px');

        // animate the lightbox window to expand vertically, then horizontally, then add the content
        $('#'+this.id).animate({
            height: height,
            marginTop: margin
        },
        {
            duration: 300,
            complete: function(){
                $(this).animate({
                    width: width
                },
                {
                    duration: 500,
                    complete: function(){

                        $('#lightBoxContentHolder').show();

                        if(contentType == 'youtube')
                        {
                            /*
									var params = { allowScriptAccess: "always", wmode: "transparent" };
									var atts = { id: "lightBoxVideoSwf" };
									swfobject.embedSWF("http://www.youtube.com/e/"+contentId+"?enablejsapi=1&playerapiid=youtubePlayer","lightBoxContentHolder", "640", "360", "8", null, null, params, atts);
									*/

                            $('#lightBoxContentHolder').html('<iframe title="YouTube Video Player" width="640" height="360" src="http://www.youtube.com/embed/'+contentId+'" frameborder="0" allowfullscreen></iframe>');
                        }
                        else if(contentType == 'image')
                        {
                            $('#lightBoxContentHolder').html('<img src="'+contentId+'" alt="" />');

                        }
                        // Add close button
                        $('#'+window.lightBox.id).append(window.lightBox.closeButtonHtml);
                        $('#'+window.lightBox.id).find('.fsOverlayCloseButton').bind('click',window.lightBox.close);

                    }
                });
            }
        });
    }

    this.close = function()
    {
        var lightBox = window.lightBox;

        var width = lightBox.dimensions[lightBox.contentType].width;
        var height = lightBox.dimensions[lightBox.contentType].height;

        // remove the close button
        $('#'+window.lightBox.id).find('.fsOverlayCloseButton').remove();

        // get the current top margin, then add half the height of the lightbox window to it
        // this gives us the point to which we want to shrink the window
        var margin = $('#'+window.lightBox.id).css('marginTop');
        margin = parseInt(margin.replace('px','')) + (height / 2);

        // fade out the content of the lightbox, then shrink the lightbox window horizontally, then vertically, then remove it
        $('#'+window.lightBox.id).find('div.fsOverlayBubble').fadeOut(500,function(){
            $('#'+window.lightBox.id).animate({
                width: 10
            },
            {
                duration: 500,
                complete: function(){
                    $(this).animate({
                        height: 10,
                        marginTop: margin
                    },
                    {
                        duration: 300,
                        complete: function(){
                            $('#'+window.lightBox.id+'Overlay').remove();
                        }
                    });
                }
            });
        });
    }

    this.setYoutubePlayerRef = function(playerId)
    {
        this.youtubePlayerRef = playerId;

    }

}

function AdminWizard(params){
    this.id = params.id;
    this.steps = params.steps;
    this.stepsCount = 0;
    this.currentStep = params.currentStep;
    this.completed = params.completed;

    for(i in this.steps){
        this.stepsCount++;
    }

    this.nextStep = function(){

        // check for validation required for this step
        if(window.adminWizard.steps[window.adminWizard.currentStep].requiredFields != null){

            for(i in window.adminWizard.steps[window.adminWizard.currentStep].requiredFields){

                var field = window.adminWizard.steps[window.adminWizard.currentStep].requiredFields[i];

                if($('#'+field).attr('type') == 'text' || $('#'+field).attr('type') == 'hidden'){
                    if($('#'+field).val() == ''){
                        alert(window.adminWizard.steps[window.adminWizard.currentStep].errorMessage);
                        return false;
                        break;
                    }
                }else if($('#'+field).attr('type') == 'checkbox'){

            }
            }
        }

        // check if there is a form to be submitted in this step
        if(window.adminWizard.steps[window.adminWizard.currentStep].form != null){
            if(window.adminWizard.steps[window.adminWizard.currentStep].form == 'close'){

                for(n=window.adminWizard.currentStep; n>=1; n--){
                    if(window.adminWizard.steps[n].form != null){
                        if(window.adminWizard.steps[n].form.id != null){
                            window.submitForm(window.adminWizard.steps[n].form.id,true);
                            return false;
                        }
                    }
                }
            }else if(window.adminWizard.steps[window.adminWizard.currentStep].form.close != null){
                var submitFormId = window.adminWizard.steps[window.adminWizard.currentStep].form.id;
            }

            if(submitFormId != null){
                window.submitForm(submitFormId,true);
                return false;
            }
        }

        if(window.adminWizard.steps[window.adminWizard.currentStep].nextStepUrl != null){
            window.siteBar.requestContent(window.adminWizard.steps[window.adminWizard.currentStep].nextStepUrl,false,true);
            return false;
        }

        if(window.adminWizard.steps[parseInt(window.adminWizard.currentStep) + 1] != null){
            window.adminWizard.showStep(parseInt(window.adminWizard.currentStep) + 1);
        }
        return false;
    }

    this.showStep = function(step){

        // update the breadcrumb

        // set the state class of the steps after the selected one
        var remainingStepsClass = 'Restricted';
        if(this.completed == 1){
            remainingStepsClass = 'Allowed';
        }

        // set the state class of the selected step
        $('#fsAppWizardBreadcrumbStep'+step).addClass('fsAppWizardBreadcrumbCurrent',true);
        $('#fsAppWizardBreadcrumbStep'+step).removeClass('fsAppWizardBreadcrumbCompleted fsAppWizardBreadcrumb'+remainingStepsClass);

        // remove current state from the other steps
        $('#'+this.id+' ul.fsAppWizardBreadcrumbs li:not(#fsAppWizardBreadcrumbStep'+step+')').toggleClass('fsAppWizardBreadcrumbCurrent',false);

        // set previous steps state to completed
        $('#'+this.id+' ul.fsAppWizardBreadcrumbs li:lt('+(step - 1)+')').toggleClass('fsAppWizardBreadcrumb'+remainingStepsClass,false);
        $('#'+this.id+' ul.fsAppWizardBreadcrumbs li:lt('+(step - 1)+')').toggleClass('fsAppWizardBreadcrumbCompleted',true);

        // set remaining steps state
        $('#'+this.id+' ul.fsAppWizardBreadcrumbs li:gt('+(step - 1)+')').toggleClass('fsAppWizardBreadcrumbCompleted',false);
        $('#'+this.id+' ul.fsAppWizardBreadcrumbs li:gt('+(step - 1)+')').toggleClass('fsAppWizardBreadcrumb'+remainingStepsClass,true);

        this.addBreadcrumbEventHandlers();

        // update the content
        $('#'+this.id+' .fsAppWizardStep').hide();
        $('#'+this.id+' .fsAppWizardStep:eq('+(step - 1)+')').show();

        this.currentStep = step;

        return false;
    }

    this.breadcrumbHandler = function(){
        var index = $('#'+window.adminWizard.id+' ul.fsAppWizardBreadcrumbs li').index(this) + 1;
        window.adminWizard.showStep(index);
        return false;
    }

    this.saveAndGoToStep = function(formId,step){

    }

    this.addBreadcrumbEventHandlers = function(){
        $('#'+this.id+' ul.fsAppWizardBreadcrumbs li').unbind('click',this.breadcrumbHandler);
        $('#'+this.id+' ul.fsAppWizardBreadcrumbs li:not(.fsAppWizardBreadcrumbRestricted,.fsAppWizardBreadcrumbCurrent)').bind('click',this.breadcrumbHandler);
    }


    this.addBreadcrumbEventHandlers();

    $('#'+this.id+' div.fsAppWizardButtons .fsWizBtnNext').bind('click',this.nextStep);
}

function Page(pageContentCount){
    this.pageContentCount = pageContentCount;
    this.pageContentSelectorPrefix = '#PageContent';
    this.contentRequest = null;

    this.addContent = function(type){
        this.contentRequest = new AjaxRequest1('dc/page_contents/edit/'+type+'/'+this.pageContentCount);
        this.contentRequest.setSuccessCallback('window.page.loadContent(data);');
        this.contentRequest.quickExecute(this.pageContentSelectorPrefix+this.pageContentCount,false);
        return false;
    }

    this.loadContent = function(data){

        // add another content place holder
        $($(this.pageContentSelectorPrefix+this.pageContentCount))
        .clone()
        .attr('id',this.pageContentSelectorPrefix.replace('#','')+(this.pageContentCount + 1))
        .insertAfter(this.pageContentSelectorPrefix+this.pageContentCount);

        // load the content
        window.contentHandler.load(data);

        // show the content
        $(this.pageContentSelectorPrefix+this.pageContentCount).removeClass('fsHidden');

        // increment the content count for the page
        this.pageContentCount++;

        return false;
    }

    this.removeContent = function(index,id){

        if(id != null){
            // record the id of the removed content
            var removedContents = $('#PageRemovedContent').val();
            var separator = '';
            if(removedContents != ''){
                separator = ',';
            }
            $('#PageRemovedContent').val(removedContents+separator+id);
        }

        // remove content at selected index
        $(this.pageContentSelectorPrefix+index).remove();

        return false;
    }
}

function Order(id)
{
    this.id = id;
    this.timer = null;
    this.refreshCountDownSeconds = 10;

    this.refreshOrder = function()
    {
        window.overlayWindow.requestContent('/admin/orders/invoice/'+this.id);
        return false;
    }

    this.displayRefreshCount = function(seconds)
    {
        if(this.timer != null){
            clearTimeout(this.timer);
        }
        if(seconds != null){
            this.refreshCountDownSeconds = seconds;
        }
        $('#orderRefreshCounter').html(this.refreshCountDownSeconds);
        if(this.refreshCountDownSeconds < 1){
            this.refreshOrder();
        }else{
            this.timer = setTimeout("window.order.displayRefreshCount();",1000);
            this.refreshCountDownSeconds = this.refreshCountDownSeconds - 1;
        }
        return false;
    }
}

function UploadManager()
{
    this.uploads = {};
    this.pollTimer = null;
    this.uploadInfoClass = 'jsUploadInfo';

    this.addUpload = function(id) {
        this.uploads[ id ] = true;
    }

    this.getUploads = function() {
        return this.uploads;
    }

    this.removeUpload = function(id) {
        delete this.uploads[id];
    }

    this.getPollTimer = function() {
        return this.pollTimer;
    }

    this.setPollTimer = function() {
        this.pollTimer = setTimeout(this.pollForUploadProgress, 500);
    }

    this.clearPollTimer = function() {
        this.pollTimer = null;
    }

    this.getUploadInfoClass = function() {
        return this.uploadInfoClass;
    }

    this.getCurrentUploadsCount = function() {
        var uploads = this.getUploads();
        var count = 0;
        for(var prop in uploads) {
            if(uploads.hasOwnProperty(prop))
                    count++;
        }
        return count;
    }

    this.isUploadInProgress = function(uploadId) {
        var uploads = this.getUploads();
        return uploads.hasOwnProperty(uploadId);
    }

    this.initiate = function(event, id, form) {
        // create new
        uploadManager.addUpload(id);
        // if the poll timer has not already been set up, then do so
        if (uploadManager.getPollTimer() == null) {
            uploadManager.pollForUploadProgress();
        }
    }

    this.pollForUploadProgress = function() {
        // convert the uploads object into a numerically indexed onbject
        var data = {};
        var i = 0;
        for (uploadId in uploadManager.getUploads()) {
            data[ i ] = uploadId;
            i++;
        }
        // set an ajax request to get the progress data for any uploads
        var ajaxOptions = {
            type: 'POST',
            url: 'http://' + document.domain + '/dc/media_files/getUploadProgress',
            dataType: 'json',
            data: data,
            success: uploadManager.uploadProgressResponseHandler
        };
        $.ajax(ajaxOptions);
    }

    this.uploadProgressResponseHandler = function(data, textStatus, jqXHR) {
        var self = uploadManager;

        for (i in data) {

            // check that the upload not already finished
            if (self.isUploadInProgress(i)) {
                // check there are not any errors
                if (data.error == null && data[i].error == null) {
                    console.log('display progress for: ' + i);

                    // check the bytes total is an int value
                    if (isNaN(data[i]['bytes_total'])) {
                        data[i]['bytes_total'] = 0;
                    }

                    // calculate progress
                    var percent = Math.floor(100 * parseInt(data[i]['bytes_uploaded'])/parseInt(data[i]['bytes_total']));

                    // calulate time remaining
                    var seconds = data[i]['est_sec'];
                    var minutes = 0;
                    //format the time into minutes
                    if (seconds > 59) {
                        for (seconds=seconds; seconds>59; minutes++) {
                            seconds-= 60;
                        }
                    }
                    //add leading 0 to seconds if needed
                    seconds = String(seconds);
                    if (seconds.length == 1) {
                        seconds = '0' + seconds;
                    }


                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadInitialise').hide();
                    //$('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadCancel').show();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadProgress').show();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadProgressBar').css('width', percent + '%');
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadText').html(data[i]['filename']).show();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadPercent').html(percent + '%').show();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadTime').html(minutes + ':' + seconds + ' remaining').show();
                } else {
                    console.log('no progress data returned for: ' + i);
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadInitialise').hide();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadProgress').hide();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadPercent').hide();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadTime').hide();
                    $('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadText').html('processing').show();
                    //$('.' + self.getUploadInfoClass() + '[name="' + i + '"]').find('.jsUploadCancel').show();
                }
            }
        } 

        // set up a timer to poll for more progress data
        if (uploadManager.getCurrentUploadsCount() > 0) {
            uploadManager.setPollTimer();
        } else {
            uploadManager.clearPollTimer();
        }
            
    }

    this.cancelUpload = function() {
        console.log($('iframe[id^="jqForm"]'));
        $('iframe[id^="jqForm"]').remove();
        console.log($('iframe[id^="jqForm"]'));
    }

    this.cancelUploadButtonHandler = function(event) {
        console.log('CANCEL:');
        console.log($(event.target).parents('.' + uploadManager.getUploadInfoClass()).attr('name'));
        uploadManager.cancelUpload($(event.target).parents('.' + uploadManager.getUploadInfoClass()).attr('name'));
    }

    this.uploadFinishedHandler = function(event, response, statusText, form) {
        if (response.upload_identifier != null) {
            uploadManager.removeUpload(response.upload_identifier);
        }
    }

    $(document).bind('aboutToStart.fileUpload.ctrl', this.initiate);

    $(document).bind('hasFinished.fileUpload.ctrl', this.uploadFinishedHandler);

    $('.uploadCancel').live('click', this.cancelUploadButtonHandler);
}

function MediaBrowser() {

    this.mediaType = null;
    this.selectedItems = {
        Track: [],
        Image: [],
        Video: []
    };
    this.newItemWithoutFileDisabled = false;

    var self = this;

    this.setMediaType = function(mediaType) {
        this.mediaType = mediaType;
    }

    this.getMediaType = function() {
        return this.mediaType;
    }

    this.disableNewItemWithoutFile = function() {
        this.newItemWithoutFileDisabled = true;
    }

    this.enableNewItemWithoutFile = function() {
        this.newItemWithoutFileDisabled = false;
    }

    this.isNewItemWithoutFileDisabled = function() {
        return this.newItemWithoutFileDisabled;
    }

    this.clearSelectedItems = function() {
        this.selectedItems.Track = [];
        this.selectedItems.Image = [];
        this.selectedItems.Video = [];
    }

    this.load = function(mediaType) {
        this.setMediaType(mediaType);
        this.clearSelectedItems();

        $(document).bind('ctrl:contentDidLoad', this.setNewItemClass);

        window.overlayWindow.requestContent('/media_browsers/' + mediaType);
    }

    this.close = function() {
        window.overlayWindow.hide();
    }
    
    this.setNewItemClass = function(event, target) {
        $(document).unbind('ctrl:contentDidLoad', self.setNewItemClass);
        
        $('#MediaBrowserNewItemTitleNoFile').attr('name', 'data[' + self.getMediaType() + '][title]');
        
        $('#MediaBrowserNewItemTitleWithFile').attr('name', 'data[' + self.getMediaType() + '][title]');
        
    }
    
    /**
     * shows the new item title input prepopulating it with the selected file name
     */
    this.showNewItemTitleForFile = function() {
        // get the path of the selected file, and extract the file name
        var title = $('#MediaBrowserFile').val().replace(/\\/g,'/').replace( /.*\//, '' );
        // remove the extension
        title = title.substring(0, title.lastIndexOf('.'));
        // set the value of the title input
        $('#MediaBrowserNewItemTitleWithFile').val(title);
        // hide the file select and show the title input
        $('#MediaBrowserFile').parent('div').hide();
        $('#MediaBrowserNewItemTitleWithFile').parent('div').show();
    }

    this.newItemUploadAboutToStartHandler = function(event, uploadId, form) {
        
        var data = {
            upload: true
        };

        data[self.getMediaType()] = {
            id: uploadId,
            title: form.find('input[name="data[' + self.getMediaType() + '][title]"]').val()
        };
        
        // add the new item element to the library
        window.mediaBrowser.addItemToLibrary(data);
    }

    this.newItemUploadStartedHandler = function(event, uploadId, form) {
        // revert the form back to its initial state
        mediaBrowser.showNewItemFileSelect();
    }

    /**
     * processes the response form the server from the new item file upload form submission
     */
    this.newItemWithFileResponseHandler = function(event, response, statusText, form) {
        if (response.Error != null) {
            // display the error
            alert(response.Error.message);
            // remove the new item element from the library
            $('#' + response.upload_identifier).remove();
        } else {
            // update the new item element
            //
            // update the status element within the new item so that it displays that the upload is complete
            $('#' + response.upload_identifier).find('.jsUploadInfo[name="' + response.upload_identifier + '"]').find(':not[.jsUploadComplete]').hide();
            $('#' + response.upload_identifier).find('.jsUploadInfo[name="' + response.upload_identifier + '"]').find('.jsUploadComplete').show();
            
            // set the id input with the new item's id
            $('#' + response.upload_identifier).find('input[name$="id]"]').val(response[self.getMediaType()].id);
            // set the has_file input within the new item to 1
            $('#' + response.upload_identifier).find('input[name$="[has_file]"]').val(1);

            // change the mp3 file icon to a tick
            $('#' + response.upload_identifier).find('span.icoCross').switchClass('icoCross', 'icoTick');
        }
    }

    /**
     * displays the new item file select
     */
    this.showNewItemFileSelect = function() {
        // hide the form without file
        $('#MediaBrowserNewItemNoFileForm').hide();
        // hide the title input in the form with file
        $('#MediaBrowserNewItemTitleWithFile').parent('div').hide();
        // clone the file input, remove the value, then replace the existing input wuth the cloned one
        // need to do this or the change event will be fired afterward if the same file is selected
        $('#MediaBrowserFile').replaceWith($('#MediaBrowserFile').clone().removeAttr('value'));
        // show file input
        $('#MediaBrowserFile').parent('div').show();
        // show the form with file
        $('#MediaBrowserNewItemWithFileForm').show();
    }

    /**
     * shows the form for adding a new item without a file
     */
    this.skipNewItemFileSelect = function() {
        // hide new item form with file input
        $('#MediaBrowserNewItemWithFileForm').hide();
        // show new item form without file input
        $('#MediaBrowserNewItemNoFileForm').show();
    }

    /**
     * submits new item without file data via ajax
     */
    this.createNewItemWithoutFile = function() {
        //
        if (!this.isNewItemWithoutFileDisabled()) {
            contentHandler.turnOnLoadingCursor();
            this.disableNewItemWithoutFile();
            // configure form plugin for ajax submission
            var options = {
                url: $('#MediaBrowserNewItemNoFileForm').attr('action'),
                beforeSubmit: window.form.validate,
                success: mediaBrowser.newItemWithoutFileResponseHandler,
                dataType: 'json',
                resetForm: true,
                validation: true
            };
            // submit
            $('#MediaBrowserNewItemNoFileForm').ajaxSubmit(options);
        }
    }

    /**
     * processes the response from createNewItemWithoutFile
     */
    this.newItemWithoutFileResponseHandler = function(response, statusText, xhr, form) {
        // check if the new item was created ok
        if (response[self.getMediaType()] != null) {
            // add an element to the library for the new item
            window.mediaBrowser.addItemToLibrary(response);
        } else {
            // display the error
            alert(response.errors.title);
        }
    }

    /**
     * creates a new entry in the library
     */
    this.addItemToLibrary = function(data) {
        // count current items to determine index of new item
        var nextIndex = $('#mediaBrowserLibrary .countableItem').length - 1;

        // get new item placeholder HTML
        var newItem = $('#mediaBrowserNewItemPlaceholder').clone();
        // clone placeholder
        newItem.attr('id', data[this.getMediaType()].id);
        // insert into the table
        newItem.prependTo('#mediaBrowserLibrary table');
        // add the new item title
        newItem.find('.title').html(data[this.getMediaType()].title);

        var name;
        // select all the inputs within the new item and update the indexes in the name attribute for each one
        newItem.find('input').each(function() {
            // get the name attribute of the input
            name = $(this).attr('name');
            if (name != null) {
                // replace the numeric index and then overwrite the name attribute
                $(this).attr('name', name.replace(':index', nextIndex));
            }
        });

        // update the id input and check the new item so it will be selected
        newItem.find('input[name$="id]"]').val(data[this.getMediaType()].id).attr('checked', 'checked');
        // show the new item
        newItem.show();

        if (data.upload != null) {
            // set the name attribute to the upload id so it can be targeted by the upload manager
            newItem.find('.jsUploadInfo').attr('name', data[this.getMediaType()].id).show();
        } else {
            // revert the new item form back to normal
            this.showNewItemFileSelect();
            this.enableNewItemWithoutFile();
            contentHandler.turnOffLoadingCursor();
        }
    }

    this.getSelectedItems = function() {
        // get all the ids of the selected items in the library
        var checkedItems = $('#mediaBrowserLibrary').find('.countableItem:has(input:checked)');

        checkedItems.each(function(index, element) {
            window.mediaBrowser.selectedItems[window.mediaBrowser.mediaType].push(
            {
                id: $(this).find('input[name$="id]"]').val(),
                title: $(this).find('.title').html(),
                hasFile: $(this).find('input[name$="[has_file]"]').val()
            }
            );
        });
        
        return window.mediaBrowser.selectedItems;
    }

    this.makeSelection = function(event) {
        // check that there are no uploads in progress
        console.log('uploads in progress: ' + uploadManager.getCurrentUploadsCount());
        if (uploadManager.getCurrentUploadsCount() == 0) {
            // check that some items were selected
            if ($('#mediaBrowserLibrary').find('.countableItem:has(input:checked)').length > 0) {
                // trigger event signalling a selection has been made
                $(document).trigger('selectionConfirmed.mediaBrowser.ctrl', [window.mediaBrowser.getSelectedItems()]);
                // close the media browser
                window.mediaBrowser.close();
            } else {
                alert('Please make a selction before clicking the Add button');
            }
        } else {
            alert('There are file uploads in progress. Please wait until they\'re complete')
        }
        
        return false;
    }

    this.cancelSelection = function(event) {
        // trigger event signalling the selecrio has been cancelled
        $(document).trigger('selectionCancelled.mediaBrowser.ctrl');
        // close the mdeia browser
        window.mediaBrowser.close();
        return false;
    }

    $('#MediaBrowserFile').live('change', function() {
        window.mediaBrowser.showNewItemTitleForFile();
    });

    $('#MediaBrowserSkipFileSelect').live('click', function() {
        window.mediaBrowser.skipNewItemFileSelect();
        return false;
    });

    $('.mediaBrowserShowToFileSelect').live('click', function() {
        window.mediaBrowser.showNewItemFileSelect();
        return false;
    });

    $('#mediaBrowserSelectBtn').live('click', this.makeSelection);

    $('#mediaBrowserCancelBtn').live('click', this.cancelSelection);
}

function Form()
{
    this.forms = new Array();
    this.options = null;
    this.errors = [];

    this.setErrors = function(value) {
        this.errors = value;
    }

    this.addError = function(name, rule, value) {
        this.errors.push(
        {
            name: name,
            rule: rule,
            value: value
        }
        );
    }

    this.getErrors = function() {
        return this.errors;
    }

    this.ajax = function(id,target) {
        var url = $(id).attr('action');

        if($(id).find('input:file').length > 0 && target == null)
        {
            target = '#'+$(id).next('.uploadInfo').attr('id');
        }

        this.options = {
            url: url,
            success: window.form.success,
            beforeSubmit: window.form.beforeSubmit,
            dataType: 'json',
            resetForm: true
        };

        if(target != null)
        {
            this.options.context = $(target);
            this.options.data = {
                _returnTo: target
            };
        }
        $(id).ajaxForm(this.options);
    }

    this.validate = function(arr, form, options) {

        $(document).trigger('aboutToStart.' + form.attr('id') + '.formValidation.ctrl');

        window.form.setErrors([]);
        var result = false;

        // check for validation config
        if (options.validation != null) {
            // loop thru validation config array
            for (index in options.validation) {
                // loop thru the specified validation rules
                for (ruleIndex in options.validation[index].rule) {
                    // check a rule has been specified
                    if (options.validation[index].rule[ruleIndex] != null) {
                        // check the rule method exists
                        if (window.form[options.validation[index].rule[ruleIndex]] != null) {
                            // call the validation rule method passing the value of the field
                            if (!window.form[options.validation[index].rule[ruleIndex]](
                                form.find('[name="' + options.validation[index].name + '"]').val(), // value of the form element
                                form, // jQuery wrapped form object
                                form.find('[name="' + options.validation[index].name + '"]') // jQuery wrapped form element
                                )) {
                                // put the field name, value and the rule that it didn't pass into an object, then add it to the errors array
                                window.form.addError(
                                    options.validation[index].name,
                                    options.validation[index].rule[ruleIndex],
                                    form.find('[name="' + options.validation[index].name + '"]').val()
                                    );
                            }
                        }
                    }
                }
            }

            // check if errors were returned
            if (window.form.getErrors().length > 0) {
                // trigger the unsuccessful validation event
                window.form.triggerValidationFailedEvent(form);
                return false;
            }
        }

        // trigger successful validation event, passing the jquery wrapped form object with it
        $(document).trigger('passed.' + form.attr('id') + '.formValidation.ctrl', [form]);

        return true;
    }

    /**
     * trigger the unsuccessful validation event, passing the jquery wrapped form and array of failed validation rules
     */
    this.triggerValidationFailedEvent = function(form) {
        $(document).trigger('failed.' + form.attr('id') + '.formValidation.ctrl', [form, this.getErrors()]);
    }

    this.notEmpty = function(value, form, field) {
        if (value != null && value != '') {
            return true;
        } else {
            return false;
        }
    }

    this.fileType = function(value, form, field) {
        // get the file types from the accepts attribute of the file input
        var accepts = field.attr('accepts');
        // check the accepts attribute was found, and wasn't empty
        if (accepts != null && accepts != '') {
            // check if there is more than one extension specified by looking for a comma in the accepts value
            if (accepts.indexOf(',') != -1) {
                // convert the comma seperated list of file types into an array
                var fileTypes = accepts.split(',');
                // loop thru the array checking if the selected file has one of the accepted extensions
                for (i in fileTypes) {
                    if (fileTypes[i] != null && fileTypes[i] != '') {
                        if (value.indexOf('.' + fileTypes[i]) != -1) {
                            return true;
                        }
                    }
                }
            } else {
                // check if the extension in the accepts value matches the extension of the selected file
                if (value.indexOf('.' + accepts) != -1) {
                    return true;
                }
            }

        }

        return false;
    }
}


/*===============================================================

	AJAX REQUEST

==================================================================*/
function AjaxRequest1(url){
    this.id = null;
    this.request = null;
    this.options = {};
    this.successCallback = 'window.contentHandler.load(data);';
    this.completeCallback = 'window.contentHandler.turnOffLoadingCursor();';//'window.ajaxManager.clearRequest(id);';
    this.errorCallback = 'window.alert(\'The requested content could not be loaded due to a technical error.\\n\\nPlease clear your browser\'s cache and try again\');';//\\n\\nSystem Request ID: \'+id+\'\\n\\nError details: \'+textStatus);';
    this.context = null;

    this.quickExecute = function(context,replaceContent){
        if(context != null){
            this.setContext(context);
        }
        if(replaceContent != null){
            this.addData('_replaceContent',replaceContent);
        }
        this.execute();
        return false;
    }

    // finishes setting the options, and then performs the request
    this.execute = function(){
        // ensure the url is set before continuing
        if(this.options['url'] != null){
            // set up a custom callback by including it in the requests success callback
            var ajaxRequest = this;
            var id = this.id;
            var successCallback = this.successCallback;
            var errorCallback = this.errorCallback;
            var completeCallback = this.completeCallback;
            // if the success callback is not null then set it
            if(successCallback != null){
                this.options.success = function(data,textStatus,request){
                    //alert('eval callback: '+successCallback);
                    eval(successCallback);
                //return true;
                }
            }
            // if the success callback is not null then set it
            if(completeCallback != null){
                this.options.complete = function(request,textStatus){
                    //alert('eval callback: '+successCallback);
                    eval(completeCallback);
                //return true;
                }
            }
            // if the error callback is not null then set it
            if(errorCallback != null){
                // set the error callback
                this.options.error = function(request,textStatus){
                    //alert('eval callback: '+successCallback);
                    eval(errorCallback);
                //return true;
                }
            }
            // loop through the data values and convert them into a query string
            // create a variable to hold the query string
            var dataQueryString = '';
            var separator = '';
            for(i in this.options.data){
                // append the key value pair to the query string
                dataQueryString+= separator+i+'='+this.options.data[i];
                // ensure the separator is set to an ampersand after the first loop
                separator = '&';
            }
            // update the data in the options with generated query string
            this.options.data = dataQueryString;
            // perform request
            this.request = $.ajax(this.options);
        }
        return false;
    }

    this.setContext = function(selector){
        if(selector != null){
            this.context = $(selector);

            // TEMPORARY
            this.addData('_returnTo',selector);
        }
        return false;
    }

    this.setOption = function(option,value){
        this.options[option] = value;
        return false;
    }

    this.addData = function(key,value){
        eval('this.options.data.'+key+' = value;');
        return false;
    }

    this.setData = function(data){
        this.options.data = data;
        return false;
    }

    this.setUrl = function(url){
        if(url != null){
            /*if(url.indexOf('://') != -1 && url.indexOf('www.') != -1){
				alert('modify: '+url);
				hash = url.replace('#/','');
				hash = hash.replace('#','');
				if(hash.indexOf('/') != 0){
					hash = '/'+hash;
				}
				url = 'http://'+document.domain+'/dc'+hash;
			}*/
            //alert('request url set to '+url);
            this.setOption('url',url);
        }
        return false;
    }

    this.clearSuccessCallback = function(){
        this.successCallback = null;
        return true;
    }

    this.setSuccessCallback = function(script){
        if(script != null){
            this.successCallback = script;
        }
        return false;
    }

    this.setCompleteCallback = function(script){
        if(script != null){
            this.completeCallback = script;
        }
        return false;
    }

    this.setErrorCallback = function(script){
        if(script != null){
            this.errorCallback = script;
        }
        return false;
    }

    this.setId = function(id){
        if(id != undefined){
            this.id = id;
        }
        return false;
    }

    // initialise the object
    this.options.type = 'POST';
    this.options.data = new Array();
    this.options.beforeSend = function(){
        window.contentHandler.turnOnLoadingCursor();
        return true;
    };
    /*this.options.dataType = 'json';*/
    this.options.dataFilter = window.jsonFilter;
    if(url != null){
        this.setUrl(url);
    }else{
        this.options['url'] = null;
    }
}

function jsonFilter(data)
{
    // remove any debugging data generated by cake from the ajax response
    // before the JSON string
    if(data.indexOf('{') != 0){
        data = data.slice(data.indexOf('{'));
    //alert('new data = '+data);
    }
    // time data after the JSON data
    if(data.indexOf('}<!--') != -1){
        data = data.split('}<!--',1);
        data = data[0]+'}';
    }

    // strip out any characters that will cause an error when parsing the JSON data
    data = data.replace('\\x','\\');
    /*alert(data);
	// data = data.replace(' type="\\&quot;text\\/javascript\\&quot;"','');
	while(data.indexOf('"\\&quot;') != -1 && data.indexOf('\\&quot;"') != -1){
		data = data.replace('"\\&quot;','\\"');
		data = data.replace('\\&quot;"','\\"');
	}
	alert(data);*/
    // check for a native JSON parser object in the browser. If one cannot be found in the browser then default the eval() method to parse the JSON
    if (typeof (JSON) !== 'undefined' && typeof (JSON.parse) === 'function'){
        //alert('use native JSON');
        return JSON.parse(data);
    }else{
        return eval('(' + data + ')');
    }
}

/*===============================================================

	CONTENT HANDLER

==================================================================*/
function ContentHandler(){
    this.defaultDestinationSelector = '#fsca1';
    this.defaultReplaceContent = false;
    this.fadeInElement = null;
    this.transitionTimer = null;
    this.fadeTransitionAction = null;

    this.updateContent = function(content,target,replace)
    {
        if(replace){
            target = $(target).replaceWith(content);
        }else{
            target = $(target).html(content);
        }

        $(document).trigger('ctrl:contentDidLoad', [$(target)]);
    }

    this.fadeTransition = function(outElement,inElement,action)
    {
        this.fadeInElement = inElement;
        /*if(inElement == null){
			this.fadeInElement = outElement;
		}
		if(action != null){
			this.fadeTransitionAction = action;
		}*/
        /*alert('out: '+outElement.attr('id'));
		alert('in: '+window.fadeInElement.attr('id'));*/
        outElement.fadeOut(500,function(){
            /*if(window.contentHandler.fadeTransitionAction != null){
				eval(window.contentHandler.fadeTransitionAction);
				window.contentHandler.fadeTransitionAction = null;
			}*/
            window.contentHandler.transitionTimer = setTimeout('window.contentHandler.fadeInContent();',500);
        });
    }

    this.fadeInContent = function()
    {
        this.fadeInElement.fadeIn(1000,function(){
            window.contentHandler.transitionTimer = null;
            return true;
        });
    }

    this.load = function(data,callback){
        /*alert(data['html']);
		alert(data['returnTo']);*/
        // check if a user session is currently active
        if(data['userSessionActive'] == 1){
            if(data['siteBar'] != null){
                window.siteBar.load(data['siteBar']);
            }
        }else{
            window.sideBar.close();
            window.siteBar.remove();
        }

        //check to see if the address bar url should be changed
        if(data['set_url'] == 1){
            if(data['url'] != null){
                window.navigation.setAddressBarUrl(data['url']);
            }
        }

        // load the HTML into the DOM
        // check if the destination element should be replaced
        if(data['replaceContent'] == 1){
            data['replaceContent'] = true;
        }else{
            data['replaceContent'] = false;
        }
        // make the sure destination element (in the form of a JQuery selector) for returned HTML is set
        if(data['returnTo'] == null || data['returnTo'] == ''){
            data['returnTo'] = this.defaultDestinationSelector;
        }
        //alert(data['returnTo']+', replace element: '+data['replaceContent']+'\n\n'+data['html']);
        // load the HTML
        if(data['html'] != null){
            /*if(data['replaceContent']){
				$(data['returnTo']).replaceWith(data['html']);
			}else{
				$(data['returnTo']).html(data['html']);
			}*/
            window.contentHandler.updateContent(data['html'],data['returnTo'],data['replaceContent']);
        //this.fadeTransition($(data['returnTo']));
        }

        // reset the flag for edited data that has not been saved if the HTML was loaded in the main content area
        if(data['returnTo'] == this.defaultDestinationSelector){
            window.formInputEditedFlag = false;
        }

        //set the page title
        if(data['pageTitle'] != ''){
            document.title = data['pageTitle'];
        }

        //set the page description
        if(data['pageDescription'] != '' && data['returnTo'] == this.defaultDestinationSelector){
            $('meta[name=description]').attr("content",data['pageDescription']);
            window.navigation.setPageDescription(data['pageDescription']);
        }
        // set the page short url
        if(data['shortUrl'] != null && data['returnTo'] == this.defaultDestinationSelector){
            window.navigation.setPageShortUrl(data['shortUrl']);
        }

        //activate any newly loaded tool tips
        //		window.activateToolTips();

        window.inputDefaults();

        if(data['loadOverlayWindow'] != null){
            window.overlayWindow.requestContent(data['loadOverlayWindow']);
        }

        if(data['reloadPage'] != null){
            window.navigation.requestPage(window.navigation.getHashFromUrl(window.location.href));
        }

        if(data['reloadWidgets'] != null){
            window.widgets.reload();
        }

        if(data['reloadBasket'] != null){
            window.widgets.reloadBasket();
        }

        if(data['reloadMediaPlayer'] != null){
            window.mediaPlayer.reloadPlayer(window.mediaPlayer.getCurrentlyPlaying(),1);
        }

        if(data['reloadUserProfileWidget'] != null){
            window.widgets.reloadUserProfile();
        }

        if(data['reloadEventsWidget'] != null){
            window.widgets.reloadEvents();
        }

        if(data['reloadNewsWidget'] != null){
            window.widgets.reloadNews();
        }

        if(data['closeOverlayWindow'] != null){
            window.overlayWindow.hide();
        }

        if(data['facebookConnected'] != null){
            window.facebook.hideAccountConnect();
        }

        if(data['updateEditMode'] != null){
            window.editMode.updateStatus(false);
        }

        if(data['refreshSiteImageOverview'] != null){
            window.siteBar.refreshSiteImageOverview();
        }

        if(data['userSessionActive'] == 1){
            if(data['loadSiteBarContent'] != null){
                window.siteBar.requestContent(data['loadSiteBarContent']);
            }
        }

        // if the wizard is active then ensure the wizard object is started
        if(data['wizardActive'] != null){
            window.wizard.check();
        }else{
            window.wizard.close();
        }

        // execute callback
        if(callback != null){
            if(callback['name'] != null){
                if(typeof(callback['name']) == 'function'){
                    alert('run method: '+callback['name']);
                }
            }
        }

        return false;
    }

    this.turnOnLoadingCursor = function(){
        $('body').toggleClass('loadingCursor',true);
        return false;
    }

    this.turnOffLoadingCursor = function(){
        $('body').removeClass('loadingCursor');
        return false;
    }
}

/*===============================================================

	EDIT MODE

==================================================================*/
function EditMode(){
    this.isOn = false;
    this.status = 'off';
    this.isLoading = false;
    this.previewOn = false;
    this.setToOnAfterPreview = false;
    this.openSideBarAfterPreview = false;
    this.bodyId = '#fsBody';
    this.errorMessage = 'The requested content could be loaded due to a technical error. Please refresh the page.'

    this.updateStatus = function(isOn){
        if(isOn){
            $('#sbEditmode').toggleClass('active',true);
            this.isOn = isOn;
            this.status = 'on';
            $('#fsEditmodeOverlay').show();
        }else{
            $('#sbEditmode').toggleClass('active',false);
            this.isOn = false;
            this.status = 'off';
            $('#fsEditmodeOverlay').hide();
        }
        return false;

        $(document).trigger('ctrl:editModeDidChange');
    }

    this.toggle = function(){
        if(this.isOn){
            this.off();
        }
        else{
            this.on();
        }
        return false;
    }

    this.on = function(url,updateUrl){
        if(this.isOn != true && this.isLoading != true){
            $('#sbEditmode').toggleClass('active',true);
            if(updateUrl == null){
                updateUrl = false;
            }
            this.setupRequest('on',url,updateUrl);
        }
        return false;
    }

    this.off = function(url,updateUrl){
        if(this.isOn && this.isLoading != true){
            $('#sbEditmode').toggleClass('active',false);
            if(updateUrl == null){
                updateUrl = false;
            }
            this.setupRequest('off',url,updateUrl);
        }
        return false;
    }

    this.setupRequest = function(switchModeTo,url,updateUrl){
        // set the loading status to prevent double clicks etc
        this.isLoading = true;
        // get the current page's url hash
        this.currentUrlHash = window.navigation.getHashFromUrl(window.location.href);
        // if the current hash is empty (just a /) then set it to the default homepage, otherwise the loading message will be loaded into the content
        if(this.currentUrlHash == '/'){
            this.currentUrlHash = '/home';
        }
        // ensure the url for the ajax request is set
        // if no url has been set then use the browser's current url
        if(url == null){
            //window.setRefererUrl();
            url = 'http://'+document.domain+this.currentUrlHash;
        }else{
            // ensure passed url doesn't contaion the hash because we want to get the whole template reloaded
            url = window.navigation.formatUrlHash(url);
            url = 'http://'+window.location.hostname+url;
        }

        //var request = window.ajaxManager.createRequest(url);
        var request = new AjaxRequest1(url);

        request.addData('_refererUrl',this.currentUrlHash);
        request.addData('editModeOn',switchModeTo);
        //request.addData('_returnTo',this.bodyId);
        request.setContext(this.bodyId);

        if(updateUrl){
            url = window.navigation.getHashFromUrl(url);
            request.setSuccessCallback('window.editMode.convertDom(data,\''+url+'\');');
        }else{
            request.setSuccessCallback('window.editMode.convertDom(data);');
        }

        request.setErrorCallback('window.editMode.errorHandler(request,textStatus);');

        request.execute();
        return false;
    }

    this.convertDom = function(data,updateUrl){
        if(data != null){
            if(this.isOn){
                this.isOn = false;
                this.status = 'off';
                $('#fsEditmodeOverlay').hide();
            }else{
                this.isOn = true;
                this.status = 'on';
                $('#fsEditmodeOverlay').show();
            }
            // ensure the url in the address bar is updated to reflect the loaded content
            if(updateUrl != null){
                data['url'] = updateUrl;
                data['set_url'] = 1;
            }

            window.contentHandler.load(data);
            // update the loading status so edit can be turned off
            this.isLoading = false;
        }
        else{
            this.errorHandler();
        }
        return false;
    }

    this.errorHandler = function(request,textStatus){
        alert(this.errorMessage);
        // update the loading status so edit can be turned off
        this.isLoading = false;
        return false;
    }

    this.preview = function(){
        // check the preview is not already on
        if(this.previewOn != true){
            // if edit mode is on then turn it off
            if(this.isOn){
                // record theat edit mode was on, so when the preview is turned off it will be turned back on
                this.setToOnAfterPreview = true;
                this.off();
            }
            // if the side bar is open then close it
            if(window.sideBar.isOpen){
                // record that the side bar was open so that when the preview is turned off it will opened again
                this.openSideBarAfterPreview = true;
                window.sideBar.close();
            }
            // hide the site bar
            window.siteBar.hide();
            // update the preview status
            this.previewOn = true;
        }
        return false;
    }

    this.closePreview = function(){
        // check the preview is on
        if(this.previewOn == true){
            // check if edit mode needs to be turned on
            if(this.setToOnAfterPreview){
                this.on();
                this.setToOnAfterPreview = false;
            }
            // show the site bar
            window.siteBar.show();
            // check if the sideBar needs to be opened
            if(this.openSideBarAfterPreview){
                window.sideBar.open();
                this.openSideBarAfterPreview = false;
            }
            // update the preview status
            this.previewOn = false;
        }
        return false;
    }

    // listeners
    // siteBar toggle button
    $('#sbEditmode').live('click',function(){
        window.editMode.toggle();
        return false;
    });
    // inline edit button
    $('span.fsEditmode').live('click',function(e){
        // get the destination url form the href attribute of the a tag the button is wrapped with
        var url = $(this).parents('a').attr('href');
        if(window.editMode.isOn){
            window.navigation.requestHandler(url);
        }else{
            window.editMode.on(url,true);
        }
        e.stopPropagation();
        return false;
    });
    // cancel edit button
    $('.fsEditmodeOff').live('click',function(e){
        // get the destination url form the href attribute of the a tag the button is wrapped with
        var url = $(this).attr('href');
        window.editMode.off(url,true);
        e.stopPropagation();
        return false;
    });
    // preview links
    $('.fsPreviewsite').live('click',function(e){
        //previewSite('on');
        window.editMode.preview();
        e.stopPropagation();
        return false;
    });
    // preview off
    $('#fsSitePreview').live('click',function(){
        window.editMode.closePreview();
        return false;
    });

    $('.fsOutlineEditable').live('mouseover',function(){
        $(this).has('span.fsEditFloat:not(.fsInactive)').css('outline','2px solid #ffee00');
        $('span.fsEditFloat:not(.fsInactive)',this).css('display','block');
    });

    $('.fsOutlineEditable').live('mouseout',function(){
        $(this).css('outline','none');
        $('span.fsEditFloat:not(.fsInactive)',this).css('display','none');
    });

    $('.ctrlEditable').live('mouseover',function(){
		$(this).addClass('ctrlEditableDisplay');
    });

    $('.ctrlEditable').live('mouseout',function(){
		$(this).removeClass('ctrlEditableDisplay');
    });

}

/*===============================================================

	GALLERY

==================================================================*/
function Gallery(id){
    this.dom = null;
    this.id = null;
    this.galleryItems = new Array();
    this.imageSelector = null;
    this.uploads = new Array();
    this.galleryItemsPerRow = 4;
    this.nextGalleryItemIndex = 0;

    // checks for existing GalleryItems in the DOM, and adds them to the galleryItems array
    this.setGalleryItems = function(){
        this.galleryItems = new Array();
        var i = 0;
        var items = new Array();
        // loop thru existing items and add to array
        $(this.dom).find('div.items').children('div.item').each(function(){
            // create a new GalleryItem object for each item
            var galleryItem = new GalleryItem(this);
            galleryItem.setIndex(i);
            items.push(galleryItem);
            i++;
        });
        this.galleryItems = items;
        // update nextIndex
        this.nextGalleryItemIndex = i;
        return false;
    }

    this.uploadImage = function(uploadId){
        var gallery = this;
        var galleryItem = null;
        $('#MediaFileId-'+uploadId).parents('div.item').each(function(){
            for(i in gallery.galleryItems){
                if(gallery.galleryItems[i].dom == this){
                    galleryItem = gallery.galleryItems[i];
                    gallery.uploads[uploadId] = galleryItem;
                    galleryItem.updateUploadingStatus(true);
                    // get a new GalleryItem selector
                    gallery.getNewGalleryItemSelector();
                }
            }
        });
        return false;
    }

    $('.ctrlEditable').live('mouseover',function(){
		$(this).addClass('ctrlEditableDisplay');
    });

    $('.ctrlEditable').live('mouseout',function(){
		$(this).removeClass('ctrlEditableDisplay');
    });

}

/*===============================================================

	GALLERY

==================================================================*/
function Gallery(id){
    this.dom = null;
    this.id = null;
    this.galleryItems = new Array();
    this.imageSelector = null;
    this.uploads = new Array();
    this.galleryItemsPerRow = 4;
    this.nextGalleryItemIndex = 0;

    // checks for existing GalleryItems in the DOM, and adds them to the galleryItems array
    this.setGalleryItems = function(){
        this.galleryItems = new Array();
        var i = 0;
        var items = new Array();
        // loop thru existing items and add to array
        $(this.dom).find('div.items').children('div.item').each(function(){
            // create a new GalleryItem object for each item
            var galleryItem = new GalleryItem(this);
            galleryItem.setIndex(i);
            items.push(galleryItem);
            i++;
        });
        this.galleryItems = items;
        // update nextIndex
        this.nextGalleryItemIndex = i;
        return false;
    }

    this.uploadImage = function(uploadId){
        var gallery = this;
        var galleryItem = null;
        $('#MediaFileId-'+uploadId).parents('div.item').each(function(){
            for(i in gallery.galleryItems){
                if(gallery.galleryItems[i].dom == this){
                    galleryItem = gallery.galleryItems[i];
                    gallery.uploads[uploadId] = galleryItem;
                    galleryItem.updateUploadingStatus(true);
                    // get a new GalleryItem selector
                    gallery.getNewGalleryItemSelector();
                }
            }
        });
        return false;
    }

    this.addUploadedImage = function(uploadId){
        var galleryItem = null;

        if(this.uploads[uploadId] != null){

            galleryItem = this.uploads[uploadId];

            galleryItem.updateUploadingStatus(false);

            galleryItem.setImage();
            // remove the upload from the uploads array
            delete this.uploads[uploadId];
        }
        return false;
    }

    this.addImageFromLibrary = function(thumbnail){
        var gallery = this;
        var galleryItem = null;
        $(thumbnail).parents('div.item').each(function(){

            for(i in gallery.galleryItems){
                if(gallery.galleryItems[i].dom == this){
                    galleryItem = gallery.galleryItems[i];
                }
            }
        });

        if(galleryItem != null){
            // get a new GalleryItem selector
            this.getNewGalleryItemSelector();
            // remove the image selector
            galleryItem.setImage();
        }
        return false;
    }

    this.getNewGalleryItemSelector = function(){
        // make a request to return the image selector
        //ajaxRequest('/gallery_items/add/'+this.id+'/'+this.nextGalleryItemIndex,'#GalleryItemPlaceHolder',true,'gallery.addNewGalleryItem');
        this.itemSelectorRequest = new AjaxRequest1('/dc/gallery_items/add/'+this.id+'/'+this.nextGalleryItemIndex);
        this.itemSelectorRequest.setSuccessCallback('window.gallery.addNewGalleryItemSelector(data);');
        this.itemSelectorRequest.quickExecute('#GalleryItemPlaceHolder',true);
        return false;
    }

    this.addNewGalleryItemSelector = function(data){
        window.contentHandler.load(data);
        this.addNewGalleryItem();
        return false;
    }

    this.addNewGalleryItem = function(){
        var gallery = this;
        $(this.dom).find('div.item:last').each(function(){
            var galleryItem = new GalleryItem(this);
            galleryItem.setIndex(gallery.nextGalleryItemIndex);
            gallery.galleryItems.push(galleryItem);
            var lastGalleryItemDomIndex = gallery.galleryItems.length - 1;
            gallery.updateLayout(lastGalleryItemDomIndex);
            gallery.nextGalleryItemIndex++;
        });
        return false;
    }

    this.removeGalleryItem = function(galleryItemIndex){
        this.galleryItems.splice(galleryItemIndex,1);

        this.updateLayout(galleryItemIndex);
        return false;
    }

    this.updateLayout = function(updateFromIndex){
        var x = 0;
        for(i in this.galleryItems){
            if(i >= updateFromIndex){
                this.galleryItems[i].setIndex(parseInt(i));

                x = parseInt(i) + 1;

                x = x % this.galleryItemsPerRow;
                if(x == 0){
                    //alert(i+' = '+x+': add clearer');
                    this.galleryItems[i].removeClearer();
                    this.galleryItems[i].addClearer();
                }else{
                    //alert(i+' = '+x+': remove clearer');
                    this.galleryItems[i].removeClearer();
                }
            }
        }
        return false;
    }

    this.viewItem = function(galleryTitle,galleryItemId){
        // set the address bar url
        window.navigation.setAddressBarUrl('/gallery/'+galleryTitle+'/'+galleryItemId);
        // hide the other items
        $(this.dom).next('div.gallery').children('div.article').addClass('fsHidden');
        // show the requested item
        $(this.dom).next('div.gallery').children('#'+galleryItemId).removeClass('fsHidden');
        // get the comments for the item
        this.getItemComments(galleryItemId);
        // hide the album view
        $(this.dom).addClass('fsHidden');
        // show the item view
        $(this.dom).next('div.gallery').removeClass('fsHidden');
        return false;
    }

    this.getItemComments = function(galleryItemId){
        $('#GalleryItemComments').html('Loading...');
        this.commentsRequest = new AjaxRequest1('/dc/gallery_items/view/'+galleryItemId);
        this.commentsRequest.quickExecute('#GalleryItemComments',true);
        return false;
    }

    // initialise the object
    if(id != undefined){
        this.dom = $('#'+id);
        this.id = id;
    }else{
        this.dom = $('div.component.galleryAlbum');
    }
    this.setGalleryItems();

}

/*===============================================================

	GALLERY ITEM

==================================================================*/
function GalleryItem(dom){
    this.dom = null;
    this.id = null;
    this.imageSet = false;
    this.uploading = false;
    this.index = 0;

    this.setIndex = function(index){
        this.index = index;
        return false;
    }

    this.removeImageSelector = function(){
        // remove the item's image selector from the DOM
        $(this.dom).find('div.fsFileselect').remove();
        return false;
    }

    this.remove = function(e){
        // prevent the event from propagating to any parent elements
        e.stopPropagation();
        // confirm the delete request
        if(confirm('Are you sure want to remove this picture?')){
            if($(e.data.galleryItem.dom).next('div.clearer').length == 1){
                $(e.data.galleryItem.dom).next('div.clearer').remove();
            }
            // remove the element from the dom
            $(e.data.galleryItem.dom).remove();
            // check if this item is followed by a clearer div. If so, then move to after the next item

            // update the GalleryItem array within the Gallery object
            gallery.removeGalleryItem(e.data.galleryItem.index);
        }
        return false;
    }

    this.updateImageIdInputIndex = function(index){
        $(this.dom).children('input').attr('id','GalleryItem.'+index+'.ImageId]');
        $(this.dom).children('input').attr('name','data[GalleryItem]['+index+'][image_id]');
        return false;
    }

    this.addClearer = function(){
        $(this.dom).after('<div class="clearer"></div>');
        return false;
    }

    this.removeClearer = function(){
        $(this.dom).next('div.clearer').remove();
        return false;
    }

    this.view = function(galleryTitle,id){
        // set the address bar url
        window.navigation.setAddressBarUrl('/gallery/'+galleryTitle+'/'+id);
        $(gallery.dom).next('div.gallery').children('div.article').addClass('fsHidden');
        $(gallery.dom).next('div.gallery').children('#'+id).removeClass('fsHidden');
        //$('div.galleryAlbum').next('div.gallery').children('div.article').html($('#'+id).html());
        $(gallery.dom).addClass('fsHidden');
        $(gallery.dom).next('div.gallery').removeClass('fsHidden');
        return false;
    }

    this.setImage = function(){
        this.imageSet = true;

        this.removeImageSelector();

        if($(this.dom).children('span.image').length == 1){
            $(this.dom).children('span.image').addClass('thumbnail');
            $(this.dom).children('span.thumbnail').removeClass('image');
            $(this.dom).find('span.fsEditIndicator').removeClass('fsInactive');
        }

        // attach an onclick listener to the delete button for the GalleryItem
        $(this.dom).find('span.fsEditIndicator').bind('click',{
            galleryItem: this
        },this.remove);
    }

    this.updateUploadingStatus = function(value){
        this.uploading = value;
        return false;
    }

    // initialise the object
    if(dom != undefined){
        this.dom = dom;
        if($(dom).attr('id') != ''){
            this.id = $(dom).attr('id');
            this.setImage();
        }
    }
}

/*===============================================================

	HELP

==================================================================*/
function Help(){
    this.currentPage = null;

    // loads a help page into the sideBar
    this.loadPage = function(page){
        // check if the requested help page is already loaded
        if(this.currentPage != page){
            // set the url for the help page
            var url = '/helps/view/'+page;
            // set the callback action
            var callback = null;
            // load using the sideBar object
            window.sideBar.requestContent(url,callback);
            // update the currentPage var so
            this.currentPage = page;
        }else{
            // if the content is already loaded then ensure the sideBar is open
            window.sideBar.open();
        }
        return false;
    }

    // get the first parameter form the ajax url
    this.getAjaxUrlRoot = function(){
        var url = window.location.hash;
        url = url.replace('#/','');
        if(url.indexOf('/') != -1){
            url = '/'+url.substr(0,url.indexOf('/'));
        }else{
            url = '/'+url.substr(0);
        }
        return url;
    }

    // set listeners
    // help buttons that load help pages
    $('.fsBtnHelp').live('click',
        function(){
            window.help.loadPage($(this).attr('href'));
            return false;
        }
        );
    // highlight buttons
    $('.helpHighlight').live('click',
        function(){
            var element = $(this).attr('title');
            helpHighlight(element);
            return false;
        }
        );
    // close help bubble
    $('#fsHelp .fsOverlayBubble span.fsAlertClose').live('click',function(){
        $('#fsHelp .fsOverlay').fadeOut(100,function(){
            $('#fsHelp .fsOverlay .fsOverlayBubble').html(null);
        });
        return false;
    });
}

/*===============================================================

	NAVIGATION

==================================================================*/

function Navigation(){
    this.isAjax = false;
    this.isLoading = false;
    this.currentPageUrl = 'http://'+window.location.hostname+'/';
    this.currentPageShortUrl = null;
    this.currentPageDescription = null;
    this.nextRequestIndex = 1;
    this.requests = new Array();
    this.defaultContextSelector = '#fsca1';
    this.googleAnalytics = false;
    this.stopNextRequest = false;

    this.usesAjax = function() {
        return this.isAjax;
    }

    this.getCurrentUrlHash = function()
    {
        return this.getHashFromUrl(window.location.href);
    }

    this.setPageShortUrl = function(shortUrl){
        if(shortUrl != ''){
            this.currentPageShortUrl = shortUrl;
        }else{
            this.currentPageShortUrl = null;
        }
        return false;
    }

    this.setPageDescription = function(pageDescription){
        this.currentPageDescription = pageDescription;
        return false;
    }

    this.getCurrentPageShortUrl = function(){
        return this.currentPageShortUrl;
    }

    this.getCurrentPageDescription = function(){
        return this.currentPageDescription;
    }

    this.stopRequest = function(){
        this.stopNextRequest = true;
        return false;
    }

    this.useGoogleAnalytics = function(){
        this.googleAnalytics = true;
        return false;
    }

    this.createAjaxRequest = function(url){
        if(url == undefined){
            url = null;
        }
        var request = new AjaxRequest1(url);
        request.setId(this.nextRequestIndex);
        this.requests[this.nextRequestIndex] = request;
        this.nextRequestIndex++;
        return request;
    }

    this.formatUrlHash = function(hash){
        if (hash != null) {
            hash = hash.replace('#/','');
            hash = hash.replace('#','');
            if(hash.indexOf('/') != 0){
                hash = '/'+hash;
            }
        }
        return hash;
    }

    this.getHashFromUrl = function(url){
        if(url != null){
            // strip out the protocol
            url = url.replace(window.location.protocol+'//','');
            // strip out the host name
            url = url.replace(window.location.hostname,'');
        }
        // format the hash
        hash = this.formatUrlHash(url);

        return hash;
    }

    this.requestPage = function(hash){
        // if navigation is set to ajax then set up and perform a request
        if(this.isAjax){
            //hash = null;
            if(hash == null){
                hash = '/';
            }
            // set the loading status to prevent double clicks etc causing unpredictable behaviour
            this.isLoading = true;
            // format the url hash to make sure the url will work
            hash = this.formatUrlHash(hash);
            // create the url using the current domain and the hash
            url = 'http://'+window.location.hostname+'/dc'+hash;
            // create a new ajax request object
            this.request = this.createAjaxRequest(url);
            // set the referring url so the PHP session is upto date
            this.request.addData('_refererUrl',this.getHashFromUrl(this.currentPageUrl));
            // set the context (the DOM element the HTML is loaded into to)
            this.request.setContext(this.defaultContextSelector);
            // set the success callback to load the returned data
            this.request.setSuccessCallback('window.navigation.loadPage(\''+this.request.id+'\',data);');
            // set the error callback to call the errorHandler method
            this.request.setErrorCallback('window.navigation.errorHandler(request,textStatus);');
            // perform the request
            this.request.execute();

            // check if google analytics is being used
            if(this.googleAnalytics){
                //alert('report to google: '+hash);
                pageTracker._trackPageview(hash);
            }
        }else{
            //alert('navigation is not ajax! redirect browser without hash');
            hash = this.formatUrlHash(hash);
            window.location.href = 'http://'+document.domain+hash;
        }
    }

    this.loadPage = function(requestId,data){
        // update the current page url
        this.currentPageUrl = window.location.href;
        // load the returned data using the content handler object
        window.contentHandler.load(data);
        // update the loading status
        this.isLoading = false;
        return false;
    }

    this.errorHandler = function(request,textStatus){
        alert('The page cannot be loaded due to a technical error: '+textStatus);
        this.isLoading = false;
        return false;
    }

    this.setAddressBarUrl = function(url){
        // call the history plugin, but pass true for the second parameter to block the ajax request
        $.historyLoad(url,true);
        return false;
    }

    // simply a pass thru method to set the parent context to the navigation object
    this.requestPagePassThru = function(url,blockRequest){
        // SAFARI HACK CHECK...
        if(window.navigation.stopNextRequest != true){
            // check if the request should be carried out
            if(blockRequest != null){
                if(blockRequest){
                    return false;
                }
            }
            window.navigation.requestPage(url,false);
        }else{
            window.navigation.stopNextRequest = false;
        }
        return false;
    }

    this.flashBannerRequest = function(url){
        if(window.wizard.isRunning()){
            window.wizard.navigationAlert();
        }else{
            this.requestHandler(url);
        }
    }

    // receives a url hash for a page and decides wether or not to (and how to) load it,
    this.requestHandler = function(url,loadInNewWindow){
        // check if a page is not already being loaded before requesting a new page
        if(this.isLoading != true){
            // check if the requested url is for an external site
            if(this.isExternalUrl(url) != true){
                // format the url before passing it to the history plugin
                url = this.getHashFromUrl(url);
                // update the loading status
                this.isLoading = true;
                // pass the page url hash to the history plugin so it can be recorded
                // the history plugin will then pass the url hash to the method defined using $.historyInit()
                $.historyLoad(url);
            }else{
                // if the wizard is active, then ensure the external page is opened in a new window/tab so the wizard is not interrupted
                if(window.wizard.isRunning()){
                    loadInNewWindow = true;
                }
                // redirect the browser to the url
                this.redirectToExternalUrl(url,loadInNewWindow);
                /*if(loadInNewWindow){
					window.open(url);
				}else{
					window.location.href = url;
				}*/
                return false;
            }
        }else{
        //alert('loading!');
        }
        // do not return anything here because this method is called by the flash banners, and flash will output whatever this method returns!
        return;
    }

    // checks if the supplied url is for a page in the system
    this.isExternalUrl = function(url){
        if(url != null){
            if(url != '/'){
                // check if the url is a full url (contains a protocol or domain)
                if(url.indexOf('://') != -1 && url.indexOf('.') != -1){
                    // check that the url does not contain the current page's domain
                    if(url.indexOf(window.location.hostname) == -1){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    this.redirectToExternalUrl = function(url,loadInNewWindow){
        if(loadInNewWindow){
            window.open(url);
        }else{
            window.location.href = url;
        }
        return false;
    }

    // sets the navigation of the site to ajax
    this.setToAjax = function(){
        // check the url in the browser's address bar is in the correct format for ajax navigation (http://domain/#/...)
        if(window.location.pathname != '/'){
            // redirect browser to ajax navigation formatted url for the current page
            window.location.href = window.location.protocol+'//'+window.location.hostname+'/#'+window.location.pathname;
            return false;
        }
        if(window.navigation.isAjax != true){
            // set navigation object to use ajax navigation
            window.navigation.isAjax = true;
            // initialise the JQuery History plugin
            // this will tell the $.historyLoad() what method to call after it adds a url hash to the history
            $.historyInit(window.navigation.requestPagePassThru);
            // if the navigation is set to ajax and there isn't a url hash, then pass / as the url
            if(window.location.hash == ''){
                this.requestHandler('/');
            }
            // set up a listener for a tags in the main body of the site
            //$('#fsBody a:not(a.tip,a.fsBtn,a.sbBtn,a.styledBtn,a.btn,a.logout,a.successClose)').live('click',function(){
            $('#fsBody a:not(a.tip,a.fsButton,a.logout,a.successClose)').live('click',function(){

                // if the href value is a mailto: link, then return true to initiate the expected behaviour
                if($(this).attr('href') != null && $(this).attr('href').indexOf('mailto:') != -1){
                    return true;
                }

                // check if the wizard restricts this link from being used
                if(window.wizard.isRunning() && $(this).parents('div.component').length == 0){
                    window.wizard.navigationAlert();
                }else{

                    // check if the link needs to be opened in a new window
                    this.newWindow = false;
                    if($(this).attr('target') == '_blank'){
                        this.newWindow = true;
                    }
                    // pass the link's url hash to the request handler method which will decide wether or not to proceed with the request
                    window.navigation.requestHandler($(this).attr('href'),this.newWindow);
                }
                return false;
            });
        }
        return false;
    }

    this.logout = function(){
        if(window.wizard.isRunning()){
            if(window.wizard.cancelLogoutPrompt()){
                return false;
            }
        }
        this.logoutRequest = new AjaxRequest1('/dc/users/logout');
        this.logoutRequest.quickExecute('#wUserProfile',true);
        return false;
    }

    // set listeners
    //logout button
    $('a.logout').live('click',function(){
        // check if the user has requested to be logged out of Facebook too
        if($('#LogoutWithFacebook:checked').length == 1){
            FB.Connect.logout(window.navigation.logout);
        }else{
            window.navigation.logout();
        }
        return false;
    });

}

/*===============================================================

	SIDE BAR

==================================================================*/
function SideBar(){
    this.dom = null;
    this.contentDom = null;
    this.id = 'fsHelp';
    this.isOpen = false;
    this.errorMessage = 'The requested content could not be loaded due to a technical error.';

    // shows the sideBar
    this.open = function(){
        // check the sideBar is closed before opening it
        if(this.isOpen != true){

            // TEMPORARY!!!
            $('body').addClass('helpopen');

            // show the DOM element
            $(this.dom).show();
            // update the status of the sideBar
            this.isOpen = true;
        }
        return false;
    }

    // hides the sideBar
    this.close = function(){
        // check the sideBar is open before closing it
        if(this.isOpen){
            // hide the DOM element
            $(this.dom).fadeOut(300);

            // TEMPORARY!!!
            $('body').removeClass('helpopen');
            //			toggleWizardInfo('off')

            // update the status of the sideBar
            this.isOpen = false;
        }
        return false;
    }

    // loads content into the sideBar
    this.requestContent = function(url,callback){
        // load using the ajaxRequest method, pass the open function as a callback to ensure the sideBar is shown once the content is loaded
        this.request = new AjaxRequest1('/dc'+url);
        this.request.setContext('#'+$(this.contentDom).attr('id'));
        this.request.setSuccessCallback('window.sideBar.loadContent(data);');
        this.request.setErrorCallback('window.sideBar.errorHandler(request,textStatus);');
        this.request.execute();
        return false;
    }

    this.loadContent = function(data){
        window.contentHandler.load(data);
        this.open();
        return false;
    }

    this.errorHandler = function(request,textStatus){
        alert(this.errorMessage);
        return false;
    }

    // set listeners
    // close button
    $('span.fsHelpClose').live('click',
        function(){
            window.sideBar.close();
            return false;
        }
        );

    // initialise the object
    if(this.id != null){
        this.dom = $('#'+this.id);
        this.contentDom = $(this.dom).children('#fsHelpContent');
    }

}

/*===============================================================

	SITE BAR

==================================================================*/
function SiteBar(){
    this.dom = null;
    this.contentDom = null;
    this.placeHolderDom = null;
    this.id = 'fsSitebar';
    // show if the siteBar HTML has been loaded into the DOM
    this.isLoaded = false;
    // shows if the siteBar's content area is open
    this.isOpen = false;
    // records if the site bar is hidden
    this.isHidden = false;
    //
    this.openAfterShow = false;
    // name of the object currently loaded into the content area
    this.currentSectionUrl = null;
    // url of the content that is currently loaded into the content area of the site bar
    this.currentContentUrl = null;
    // message displayed when content cannot be loaded
    this.errorMessage = 'The requested content could not be loaded due to a technical error.';

    // add a class to highlight the current section's button
    this.highlightSectionButton = function(){
        //alert('highlight: '+this.currentSectionUrl);
        this.unHighlightSectionButtons();
        $(this.dom).children('#sbNavigation').children('a.sbMainbutton[href='+this.currentSectionUrl+']').toggleClass('active',true);
        return false;
    }

    // remove the highlightling class from all section buttons
    this.unHighlightSectionButtons = function(){
        $(this.dom).children('#sbNavigation').children('a.sbMainbutton').toggleClass('active',false);
        return false;
    }

    // update the site bar object when the DOM elements have already been loaded
    this.syncWithDom = function(editModeOn){
        this.load();
        // update the status of the edit mode object
        window.editMode.updateStatus(editModeOn);
        return false;
    }

    // loads the sitebar HTML (not the content of the sitebar)
    this.load = function(html){
        // check the siteBar is not loaded before loading it
        if(this.isLoaded != true){
            // check that the site bar HTML has been passed
            if(html != null){
                // attach the admin CSS stylesheet
                $('link[rel=stylesheet]:first').after('<link id="adminStyles" rel="stylesheet" type="text/css" href="/css/admin.css" />');
                // prepend the HTML to contents of the body tag
                $('body').prepend(html);
            }
            // set up the DOM references
            this.dom = $('#fsSitebar');
            this.contentDom = $('#sbSitebarContent');
            this.placeHolderDom = $('#fsSitebarPos');
            // update the isLoaded status of the siteBar
            this.isLoaded = true;
        }
        return false;
    }

    // removes the siteBar HTML completely
    this.remove = function(){
        // check the site bar is loaded before removing it
        if(this.isLoaded){
            // if the content area is currently open, then close it first
            if(this.isOpen){
                this.close(true);
            }else{
                // remove the site bar and its placeholder
                $(window.siteBar.placeHolderDom).slideUp(300);
                $(this.dom).fadeOut(500,function(){
                    $(window.siteBar.placeHolderDom).remove();
                    $(window.siteBar.dom).remove();
                    $('#adminStyles').remove();
                });
                // update the site bar variables
                this.isLoaded = false;
                this.currentSectionUrl = null;
                this.currentContentUrl = null;

                // temporary
                window.widgets.reload();
            }
        }
        return false;
    }

    this.hide = function(){
        // check the site bar isn't already hidden
        if(this.isHidden != true){
            // if the site bar is open, then close, passing this method (hide) as a callback
            if(this.isOpen){
                // set this var to true so that the site bar will be opened again when shown
                this.openAfterShow = true;
                this.close('window.siteBar.hide();');
            }else{
                // hide the site bar
                $(this.dom).slideUp(500,function(){
                    // resize the site bar placeholder div
                    $(window.siteBar.placeHolderDom).css('height','16px');
                    // show the preview bar
                    $('#fsSitePreview').show();
                });
                this.isHidden = true;
            }
        }
        return false;
    }

    this.show = function(){
        if(this.isHidden){
            $('div#fsSitePreview').hide();
            $(this.dom).slideDown(500,function(){
                $(window.siteBar.placeHolderDom).attr('style',null);
                if(window.siteBar.openAfterShow){
                    window.siteBar.open();
                    window.siteBar.openAfterShow = false;
                }
            });
            this.isHidden = false;
        }
        return false;
    }

    // displays the siteBar content area
    this.open = function(){

        // check the sideBar is closed before opening it
        if(this.isOpen != true){

            // TEMPORARY!!!
            $('body').addClass('sitebaropen');

            // highlight the relevant navigation button
            this.highlightSectionButton();

            // show the DOM element
            $(this.contentDom).slideDown(500,function(){
                window.siteBar.resizeSitebar(window.siteBar.currentContentUrl);
            });
            // update the status of the sideBar
            this.isOpen = true;
        }else{
            this.resizeSitebar(this.currentContentUrl);
            // highlight the relevant navigation button
            this.highlightSectionButton();
        }
        return false;
    }

    // hides the siteBar content area
    this.close = function(callback){

        // check the sideBar is open before closing it
        if(this.isOpen){
            // hide the DOM element
            $(this.contentDom).slideUp(500,function(){
                // unhighlight the navigation buttons
                window.siteBar.unHighlightSectionButtons();
                // update the status of the sideBar
                window.siteBar.setIsOpen(false);
                // check if the site bar needs to be removed after being closed
                /*if(removeSiteBar != undefined){
					if(removeSiteBar == true){
						window.siteBar.remove();
					}
				}*/

                window.siteBar.resizeSitebar('closeSitebar');

                if(callback != null){
                    eval(callback);
                }
            });

            // TEMPORARY!!!
            $('body').removeClass('sitebaropen');

        }
        return false;
    }

    this.resizeSitebar = function(url){

        if(url=='closeSitebar'){

            $('#fsSitebar').css('height','');
            $('#fsBody').css('height','');
            $('#fsBody').css('top','');
            $('#sbSitebarContent').css('height','');

            $('body.helpopen div#fsBody').css('width','');

        }else{

            var windowHeight = $(window).height();

            if(url=='/sites/templateAndTheme'){
                var fsSitebarHeight = 257;
            }else if(url=='/ios_apps/view'){
                var fsSitebarHeight = 730;
            }else if(url=='/facebook_apps/settings'){
                var fsSitebarHeight = 710;
            }else{
                var fsSitebarHeight = 540;
            }

            var fsSitebarHeightTotal = fsSitebarHeight + 90;

            // this just ensures that the height of the SB is never larger than the actual window size!!
            if(fsSitebarHeightTotal > windowHeight){
                fsSitebarHeight = windowHeight - 20;
            }

            var fsSitebarContentHeight = fsSitebarHeight-90;

            var fsBodyHeight = windowHeight - fsSitebarHeight;

            $('#fsSitebar').css('height',fsSitebarHeight+'px');
            $('#fsBody').css('height',fsBodyHeight+'px');
            $('#fsBody').css('top',fsSitebarHeight+'px');
            $('#sbSitebarContent').css('height', fsSitebarContentHeight+'px');

            //alert('Make the SB '+fsSitebarContentHeight+'px');

            $('body.helpopen div#fsBody').css('width',($(window).width() - 230)+'px');

        }



    }

    // a pass thru function to requestContent that also updates the currentSectionUrl
    this.loadSection = function(url,contentUrl){
        // check the requested section isn't already open
        if(this.currentSectionUrl != url){
            // update the current section url
            this.currentSectionUrl = url;
            // load the content
            if(contentUrl != null){
                url = contentUrl;
            }
            this.requestContent(url);
        }else{
            // if the requested section is already loaded, then display it
            this.open();
        }

        return false;
    }

    // loads content into the sideBar
    this.requestContent = function(url,loadInNewWindow,forceRefresh){
        // check if the url is for an external site
        if(window.navigation.isExternalUrl(url)){
            window.navigation.redirectToExternalUrl(url,loadInNewWindow);
        }else{
            url = window.navigation.getHashFromUrl(url);
            // check if the requested content is already loaded into the content area
            if(this.currentContentUrl != url || forceRefresh != null){
                this.request = new AjaxRequest1('/dc'+url);
                this.request.setContext('#'+$(this.contentDom).attr('id'));
                this.request.setSuccessCallback('window.siteBar.loadContent(data,"'+url+'");');
                this.request.setErrorCallback('window.siteBar.errorHandler(request,textStatus);');
                this.request.execute();

            }else{
                //alert('already loaded');
                // if the requested content is already loaded, then display it
                this.open();
            }
        }
        return false;
    }

    this.loadContent = function(data,url){

        //alert(url+' => '+data['url']);

        window.contentHandler.load(data);

        // update the currentContentUrl
        this.currentContentUrl = url;

        this.open();

        return false;
    }

    this.errorHandler = function(request,textStatus){
        // update the currentContentUrl
        this.currentContentUrl = null;
        alert(this.errorMessage);
        return false;
    }

    // sets the isOpen variable
    this.setIsOpen = function(isOpen){
        if(isOpen != undefined){
            this.isOpen = isOpen;
        }
        return false;
    }

    this.refreshSiteImageOverview = function(){
        this.request = new AjaxRequest1('/dc/sites/imageOverview');
        this.request.setContext('#siteImageOverview');
        this.request.setSuccessCallback('window.contentHandler.load(data);');
        //this.request.setErrorCallback('window.siteBar.errorHandler(request,textStatus);');
        this.request.execute();
        return false;
    }

    // selects tabbed content
    this.selectTab = function()
    {
        $('#SbTabs span').removeClass('active');
        $(this).addClass('active');
        var tabIndex = $('#SbTabs span').index(this);
        window.contentHandler.fadeTransition($('#SbTabs').next('div').children('div'),$('#SbTabs').next('div').children('div:eq('+tabIndex+')'));
        return false;
    }

    // set listeners
    // navigation buttons
    $('#sbNavigation a.sbMainbutton:not(#sbEditmode,#sbWizard)').live('click',function(){
        if(window.wizard.isRunning() != true){
            window.siteBar.loadSection($(this).attr('href'));
        }else{
            window.wizard.navigationAlert();
        }
        return false;
    });

    // site bar menus
    $('#sbMenu li a, #sbContent a:not(.tip,.fsBtn,.sbBtn,.styledBtn,.btn,.successClose,.disabled)').live('click',function(event){
        // check if the link needs to be opened in a new window
        if ($(this).attr('target') == '_blank') {
            // if the href value is not for an external url, then include the hash if this site uses ajax navigation
            if (window.navigation.isExternalUrl($(this).attr('href')) != true && window.navigation.usesAjax()) {
                $(this).attr('href','http://' + window.location.hostname + '/#' + window.navigation.getHashFromUrl($(this).attr('href')));
            }
            // return true to allow the normal behaviour of the link to continue
            return true;
        }

        // depreciated:
        this.newWindow = false;
        if($(this).attr('target') == '_blank'){
            this.newWindow = true;
        }
        // :end

        window.siteBar.requestContent($(this).attr('href'),this.newWindow);
        return false;
    });

    // site bar close button
    $('#sbClose').live('click',function(){
        if(window.wizard.isRunning() != true){
            window.siteBar.close();
        }else{
            window.wizard.navigationAlert();
        }
        return false;
    });

    // tabs
    $('#SbTabs span').live('click',this.selectTab);

    // template and themes
    // template selector
    $('#sbSitebarContent #sbTemplateSelect a').live('click',selectTemplate);
    // theme selector
    $('#sbSitebarContent #sbThemeSelect a').live('click',selectTheme);

    // background image radio selections
    $('input#SiteBackgroundOption1').live('click',function(){
        $('.sbBackgroundActions').addClass('fsHidden');
        $('#fsBgStock').removeClass('fsHidden');
    });

    $('input#SiteBackgroundOption2').live('click',function(){
        $('.sbBackgroundActions').addClass('fsHidden');
        $('#fsBgUpload').removeClass('fsHidden');
    });

    $('input#SiteBackgroundOption0').live('click',function(){
        $('.sbBackgroundActions').addClass('fsHidden');
    });

    // initialise the object
    window.editMode = new window.EditMode();
//window.sideBar = new window.SideBar();
}

/*===============================================================

	WIZARD

==================================================================*/
function Wizard(){
    this.running = false;
    this.currentStep = 0;
    this.isThemeSet = false;
    this.steps = new Array();
    // this is the alert message displayed when a user clicks on something that is restricted during the wizard
    this.navigationErrorMessage = 'Some functionality of ctrl is disabled during the set up of your site.\n\nDon\'t worry though!\n\nIt will be available once the set up wizard is complete!';
    this.setThemeErrorMessage = 'You must set up the appearance of your site before continuing.\n\nPlease select a layout and a theme, then click on the Save button.';

    // initialises the steps array which is the map for the wizard navigation (in the futur this should be passed through from the PHP to allow the wizard to be customised)
    this.setSteps = function(){
        this.steps[0] = {
            url:'/setup-your-site',
            topic:'themes',
            actions:''
        };
        this.steps[1] = {
            url:'/home',
            topic:'home'
        };
        this.steps[2] = {
            url:'/biography',
            topic:'biography'
        };
        this.steps[3] = {
            url:'/news',
            topic:'news'
        };
        this.steps[4] = {
            url:'/events',
            topic:'events'
        };
        this.steps[5] = {
            url:'/gallery',
            topic:'gallery'
        };
        this.steps[6] = {
            url:'/music',
            topic:'music'
        };
        this.steps[7] = {
            url:'/video',
            topic:'video'
        };
        this.steps[8] = {
            url:'/contact',
            topic:'contact'
        };
        return false;
    }

    this.navigationAlert = function(){
        alert(this.navigationErrorMessage);
        // don't return anything here because this method will be called by the flash banners if a menu link is clicked during the wizard
        return;
    }

    this.setThemeAlert = function(){
        alert(this.setThemeErrorMessage);
        return false;
    }

    this.themeSet = function(){
        this.isThemeSet = true;
        return false;
    }

    this.cancelLogoutPrompt = function(){
        if(confirm('Are you sure you want to exit the site setup?') != true){
            return true;
        }else{
            return false;
        }
    }

    // returns the running status as a true/false boolean value
    this.isRunning = function(){
        return this.running;
    }

    // navigates the browser to the specified step of the wizard
    this.loadStep = function(step){
        // check the step exists in the steps array
        if(this.steps[step] != undefined){
            // load the help page using the help object
            window.help.loadPage(this.steps[step]['topic']);
            // update the current step var
            this.currentStep = step;
            // load the coresponding page of the site so that the content matches the help content
            if(this.steps[step]['url'] != null){
                //loadPage(this.steps[step]['url']);
                window.navigation.requestHandler(this.steps[step]['url'],false);
            }
            // check if the step contains any actions to be carried out
            if(this.steps[step]['topic'] == 'themes'){
                // open the template and theme section of the site bar
                window.siteBar.loadSection('/sites/templateAndTheme');
                window.siteBar.resizeSitebar('/sites/templateAndTheme');
            }else{
                // ensure the site bar is closed
                window.siteBar.close();
            }
        }
        return false;
    }

    // checks that the wizard is running and that the page and help content match
    this.check = function(){
        // start the wizard if it isn't already running
        if(this.running != true){
            this.start();
        }else{
            // get the first part of the ajax url
            var url = window.help.getAjaxUrlRoot();
            // loop thru the steps
            for(i in this.steps){
                // check if the step's url matches the current ajax url
                if(this.steps[i]['url'] == url){
                    // if the wizard is not currently set to this step, then load it
                    if(this.currentStep != i){
                        this.loadStep(i);
                    }
                }
            }
        }
        return false;
    }

    // initialises the wizard
    this.start = function(step){
        // if a step was not specified to start on then set one
        if(step == undefined){
            // default to the objects current step (this will be 0)
            step = this.currentStep;
            // check if the first part of the url is linked to a step in the wizard
            // get the first part of the ajax url
            var url = window.help.getAjaxUrlRoot();
            // loop thru the steps checking the step's url matches the current ajax url
            for(i in this.steps){
                // if the ajax url matches then set the current step to this step
                if(this.steps[i]['url'] == url){
                    step = i;
                }
            }
        }

        // TEMPORARY!!! - add a class to the body so that CSS for the wizard alerts works correctly
        $('body').toggleClass('fsWizardrunning',true);

        // load the wizard step
        this.loadStep(step);
        // update the wizard running status to true
        this.running = true;
        return false;
    }

    // loads the previous step of the wizard if there is one
    this.previousStep = function(){
        // check the wizard is running
        if(this.isRunning){
            // check a step exists before the current step
            var step = parseInt(this.currentStep) - 1;
            if(this.steps[step] != undefined){
                // load the step
                this.loadStep(step);
            }
        }
        return false;
    }

    // loads the next step of the wizard if there is one
    this.nextStep = function(){
        // check the wizard is running
        if(this.running == true){
            // if the current step is when the user selects a template & theme, then check they have saved their choice before allowing them to continue
            if(this.steps[this.currentStep].topic == 'themes' && this.isThemeSet != true){
                this.setThemeAlert();
            }else{
                // check if the current step of the wizardis the last step
                var lastStep = this.steps.length - 1;
                if(this.currentStep == lastStep){
                    // load the final step
                    this.finalStep();
                }else{
                    // check a step exists after the current step
                    var step = parseInt(this.currentStep) + 1;

                    if(this.steps[step] != undefined){
                        // load the step
                        this.loadStep(step);
                    }
                }
            }
        }
        return false;
    }

    // shows the final step of the wizard
    this.finalStep = function(){

        // TEMPORARY!!!! - unhighlight all the buttons in the site bar
        //$('#sbNavigation a.sbMainbutton:not(#sbEditmode,#sbWizard)').removeClass('active');
        window.siteBar.close();

        // load the final step of the wizard using the sideBar object
        window.sideBar.requestContent('/sites/wizardFinish');
        return false;
    }

    // deactivates the wizard
    this.close = function(){
        // update the running status, and load the help index into the sideBar content to replace any wizard content
        if(this.running){
            this.running = false;
            if(window.sideBar.isOpen){
                window.help.loadPage('index');
            }

            // TEMPORARY!!! - remove class from the body that was used for the CSS for the wizard alerts
            $('body').toggleClass('fsWizardrunning',false);

        }
        return false;
    }

    // set listeners
    // previous step buttons
    $('.fsBtnWizardPrev:not(.fsDisabled)').live('click',
        function(){
            window.wizard.previousStep();
            return false;
        }
        );
    // next step buttons
    $('.fsBtnWizardNext:not(.fsDisabled)').live('click',
        function(){
            window.wizard.nextStep();
            return false;
        }
        );

    // initialise the object
    this.setSteps();
}


// NEW

/*function FormHandler(){
	this.forms = new Array();
}

function Form(id){
	this.id = id;
}
*/
function News(){
    this.deletePromptMessage = 'Are you sure you want to delete this news post?';

    this.deletePrompt = function(event){
        return confirm(event.data.text);
    }

    // set listeners
    $('a.delete',$('div.news.component')).bind('click',{
        text: this.deletePromptMessage
        },this.deletePrompt);
}

function Playlist(){
    this.deletePromptMessage = 'Are you sure you want to delete this track?';

    this.deletePrompt = function(event){
        return confirm(event.data.text);
    }

    // set listeners
    $('a.delete',$('div.component.playlist')).bind('click',{
        text: this.deletePromptMessage
        },this.deletePrompt);
}

function Track(){
    this.deletePromptMessage = 'Are you sure you want to delete this track?';

    this.deletePrompt = function(event){
        return confirm(event.data.text);
    }

    this.checkDownloadOptions = function(){
        this.download = 0;
        if($('#TrackDownload:checked').length == 1 && $('#TrackSell:checked').length == 1){
            if($('#TrackDownloadMembersOnly:checked').length == 1 && $('#Product0MembersOnly:checked').length == 1){
                alert('free & paid for for members??');
            }
            if($('#TrackDownloadMembersOnly:checked').length == 0 && $('#Product0MembersOnly:checked').length == 0){
                alert('free & paid for??');
            }
            if($('#TrackDownloadMembersOnly:checked').length == 0 && $('#Product0MembersOnly:checked').length == 1){
                alert('only members have to pay??');
            }
        }
    }

    // set listeners
    $('a.delete',$('div.component.music')).bind('click',{
        text: this.deletePromptMessage
        },this.deletePrompt);

//$('#TrackDownload, #TrackDownloadMembersOnly, #TrackSell, #Product0MembersOnly',$('div.component.music')).bind('click',this.checkDownloadOptions);
}

function Video(){
    this.deletePromptMessage = 'Are you sure you want to delete this video?';

    this.deletePrompt = function(event){
        return confirm(event.data.text);
    }

    // set listeners
    $('a.delete',$('div.videos.component')).bind('click',{
        text: this.deletePromptMessage
        },this.deletePrompt);
}

function Events(){
    this.dom = $('div.events.component');
    this.eventItem = new EventItem();

    this.confirmDeleteEventItem = function(e){
        return window.events.eventItem.deletePrompt();
    }
}

function EventItem(id){
    this.id = null
    if(id != null){
        this.id = id;
    }
    this.dom = $('div.events.component');
    this.venues = new Array();
    this.venueCities = new Array();
    this.deletePromptMessage = 'Are you sure you want to delete this event?';

    this.deletePrompt = function(event){
        return confirm(event.data.text);
    }

    this.addVenueAutocomplete = function(){
        // set the autocomplete for  the venue name input
        $("#VenueName").autocomplete(this.venues,
        {
            width: 260,
            selectFirst: false,
            matchContains: true,
            formatItem: function(row,i,n,searchTerm){
                //return venue name and town
                return row[1]+", "+row[2];
            },
            formatMatch: function(row,i,n,searchTerm){
                return row[1];
            }
        });
        // set a method to be run when an autocomplete option is selected
        $("#VenueName").result(function(event,data,formatted) {
            window.eventItem.loadVenue(data[0]);
            return false;
        });
        // set the autocomplete for  the venue town_city input
        $("#VenueTownCity").autocomplete(this.venueCities,
        {
            width: 260,
            selectFirst: false,
            matchContains: true,
            formatItem: function(row,i,n,searchTerm){
                //return venue town
                return row[0];
            }
        });
        return false;
    }

    this.loadVenue = function(venueId){
        var venueRequest = new AjaxRequest1('/dc/venues/view/'+venueId);
        venueRequest.quickExecute('#fsca1 div.venueinfo',false);
        return false;
    }

    this.updateGoogleMap = function(){
        this.postCode = $('input#VenuePostCode').val();
        this.postCode.replace(' ','+');
        $('#EventItemVenueMap').attr('src','http://'+window.location.hostname+'/dc/event_items/map/'+this.postCode);
        return false;
    }

    // set listeners
    $('input#VenuePostCode').bind('blur',this.updateGoogleMap);

    $('a.delete',$('div.events.component')).bind('click',{
        text: this.deletePromptMessage
        },this.deletePrompt);
}

function AlertsManager(){
    this.alerts = new Array();

    this.add = function(key){
        if(key != null){
            if(this.alerts[key] != null){
                this.alerts[key].destroy();
            }
            this.alerts[key] = new Alert(key);
        }else{
    //alert('no key');
    //this.alerts.push();
    }
    }

    this.createAndAdd = function(key,html){
        if(html != null && key != null){
            $('#fsBody').append(html);
            this.add(key);
        }
        return false;
    }

    this.remove = function(id){
        if(id != null){
            delete this.alerts[id];
        }
        return false;
    }

    // set listeners
    $('div.fsAlert-fadeOnClick').live('click',function(){
        if($(this).parent().is('div.otherActions')){
            window.alertsManager.alerts[$(this).parent('div.otherActions').parent('div').attr('id')].fadeOut();
        }else{
            window.alertsManager.alerts[$(this).attr('id')].fadeOut();
        }
        return false;
    });
}

function Alert(id){
    this.id = null;
    this.dom = null;
    this.fadeOutTimer = null;

    this.destroy = function(){
        this.dom.remove();
        window.alertsManager.remove(this.id);
        return false;
    }

    this.addFadeOutTimer = function(){

        var alertId = this.id

        //window.alertsManager.alerts[alertId].addFadeOutOnAnyClickListener();

        this.fadeOutTimer = setTimeout("window.alertsManager.alerts['"+alertId+"'].fadeOut();",1000);

        return false;
    }

    this.fadeOut = function(){
        var thisAlert = this;
        $('#'+this.id).fadeOut(1000,function(){
            // check if the alert has been rendered in an overlay div
            if(thisAlert.dom.parent().is('div.fsOverlay')){
                thisAlert.dom.parent('div.fsOverlay').fadeOut(500);
            }
            thisAlert.dom.remove();
            window.alertsManager.remove(thisAlert.id);
        });
        return false;
    }

    this.addFadeOutOnAnyClickListener = function(){
        var id = this.id;
        $('body').bind('click',{
            id: id
        },window.alertsManager.alerts[id].fadeOutOnAnyClick);
        return false;
    }

    this.fadeOutOnAnyClick = function(event){
        var clicked = $(event.target); // get the element clicked
        if(clicked.is('.socialInteractions') || clicked.parents().is('.socialInteractions') || clicked.is('.fsOverlay') || clicked.parents().is('.fsOverlay')) {

        }else{
            if(window.alertsManager.alerts[event.data.id] != null){
                $('body').unbind('click',window.alertsManager.alerts[event.data.id].fadeOutOnAnyClick);
                window.alertsManager.alerts[event.data.id].fadeOut();
            }
        }
    // do not return false because it will prevent the clicked elements onclick event from triggering
    }

    // initialise the object
    if(id != null){
        this.id = id;
        this.dom = $('#'+id);
    }
}

function OverlayWindow(){
    this.id = 'fsSocialNetworkUI';
    this.dom = $('#'+this.id);
    this.contentId = 'fsSocialnetworkBubble';
    this.contentDom = $('#'+this.contentId);
    this.defaultContentClass = this.contentDom.attr('class');
    this.visible = false;

    this.setVisible = function(value){
        this.visible = value;
        return false;
    }

    this.show = function(){
        if(this.visible != true){
            this.dom.fadeIn(100,function(){
                window.overlayWindow.setVisible(true);
            });
        }
        return false;
    }

    this.hide = function(){
        if(this.visible){
            $(this.dom).fadeOut(100,function(){
                window.overlayWindow.contentDom.html(null);
                window.overlayWindow.setVisible(false);
                window.overlayWindow.setContentClass();
            });
        }
        return false;
    }

    this.setContentClass = function(contentClass){
        if(contentClass != null){
            this.contentDom.attr('class',contentClass);
        }else{
            this.contentDom.attr('class',this.defaultContentClass);
        }
        return false;
    }

    this.requestContent = function(url,callback){
        this.request = new AjaxRequest1('/dc'+url);
        if(callback != null){
            this.request.setSuccessCallback(callback);
        }else{
            this.request.setSuccessCallback('window.overlayWindow.loadContent(data);');
        }
        this.request.quickExecute('#'+this.contentId,false);
        return false;
    }

    this.loadContent = function(data){
        window.contentHandler.load(data);
        if(data['closeOverlayWindow'] != null){
            this.hide();
        }else{
            this.show();
        }
        return false;
    }

    this.saveSiteImageSettings = function(){
        window.reloadTemplateAfterSave = true;
        window.submitForm('SiteImageSettings',false);
        return false;
    }

    // set listeners
    $('#fsSocialNetworkUI .fsOverlayBubble span.fsAlertClose').live('click',function(){
        window.overlayWindow.setVisible(true);
        window.overlayWindow.hide();
    });
    // image tabs
    $('#fsSocialNetworkUI .fsOverlayBubble div.sbTabs span.sbTab').live('click',function(){
        $('#fsSocialNetworkUI .fsOverlayBubble div.sbTabs span.sbTab').toggleClass('active',false);
        $(this).toggleClass('active',true);
        // get the text in the tab label as this corresponds to the class name of the div for that tab
        var tabClass = $(this).html();
        tabClass = tabClass.replace(' ','');
        $('#fsSocialNetworkUI .fsOverlayBubble div.sbTemplate'+tabClass).toggleClass('fsHidden',false);
        $('#fsSocialNetworkUI .fsOverlayBubble form').children('div:not(.btns,.sbTemplate'+tabClass+')').toggleClass('fsHidden',true);
    //$('#fsSocialNetworkUI .fsOverlayBubble div.sbTemplateHeaderImage, #fsSocialNetworkUI .fsOverlayBubble div.sbTemplateBackgroundImage').toggleClass('fsHidden');
    });

    /*$('#SiteImageId').live('change',function(){
		alert($(this).val());
		$('#SiteCustomHeader1').attr('checked',true);
		return false;
	});*/
    // background image selector
    $('#fsSocialNetworkUI .fsOverlayBubble div.sbTemplateBackgroundImage div.sbTemplateBackgroundSelector a').live('click',function(){
        $('#SiteBackgroundOption1').attr('checked','checked');
        $('#SiteBackgroundId').val($(this).attr('id'));
        $('#fsSocialNetworkUI .fsOverlayBubble div.sbTemplateBackgroundImage div.sbTemplateBackgroundSelector a').removeClass('selected');
        $(this).addClass('selected');
        return false;
    });
    $('#fsSocialNetworkUI .fsOverlayBubble div.sbTemplateBackgroundImage #BackgroundImageId').live('change',function(){
        $('#SiteBackgroundOption2').attr('checked','checked');
    });

    $('div.socialInteractions span[title!=facebook]').live('click',function(e){
        if($(this).attr('title') == 'facebookNew'){
            window.overlayWindow.requestContent('/interactions/facebookNew');
        }else{
            socialInteraction($(this).attr('title'));
        }
        return false;
    });

}

function popUp(params){
    if(popUpWindow != null){
        popUpWindow.close();
    }
    var  screenX    = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft,
    screenY    = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop,
    outerWidth = typeof window.outerWidth != 'undefined' ? window.outerWidth : document.body.clientWidth,
    outerHeight = typeof window.outerHeight != 'undefined' ? window.outerHeight : (document.body.clientHeight - 22),
    width    = params.width,
    height   = params.height,
    left     = parseInt(screenX + ((outerWidth - width) / 2), 10),
    top      = parseInt(screenY + ((outerHeight - height) / 2.5), 10),
    features = (
        'width=' + width +
        ',height=' + height +
        ',left=' + left +
        ',top=' + top
        );
    popUpWindow = window.open(params.url,'socialNetworkSignIn',features);
    if (window.focus){
        popUpWindow.focus()
    }
    return false;
}

function SocialNetwork(){
    this.connect = function(type){
        window.overlayWindow.requestContent('/social_network_accounts/connect/'+type,'window.socialNetwork.loadContent(data,"'+type+'");');
        return false;
    }

    this.login = function(type){
        window.overlayWindow.requestContent('/social_network_accounts/connectLogin/'+type,'window.socialNetwork.loadContent(data,"'+type+'");');
        return false;
    }

    this.register = function(type){
        window.overlayWindow.requestContent('/social_network_accounts/connectRegister/'+type,'window.socialNetwork.loadContent(data,"'+type+'");');
        return false;
    }

    this.navigationContinue = function(type,url){
        window.overlayWindow.requestContent(url,'window.socialNetwork.loadContent(data,"'+type+'",true);');
        return false;
    }

    this.loadContent = function(data,type,resetContentClass){
        if(resetContentClass != null){
            window.overlayWindow.setContentClass(window.overlayWindow.defaultContentClass);
        }else{
            window.overlayWindow.setContentClass(window.overlayWindow.defaultContentClass+' fsOverlayBubble-'+type);
        }
        window.overlayWindow.loadContent(data);
        return false;
    }

    this.hideConnectButton = function(type){
        $('div.'+type+'Connect').hide();
        $('div.'+type+'Disconnect').show();
        var camelisedType = type.charAt(0).toUpperCase()+type.slice(1);
        $('#'+camelisedType+'Disconnect').parent('div').hide();
        return false;
    }

    this.setUpFacebookPostObject = function(){
        $('#FacebookPostLink').attr('value',document.location.href.replace('/#',''));

        $('#FacebookPostDescription').attr('value',window.navigation.getCurrentPageDescription());

        var pageTitle = document.title.replace('[Edit Mode On]','');
        $('#FacebookPostName').attr('value',pageTitle);

        if($('div.component').hasClass('galleryAlbum')){
            if($('div.component div.item:first img').attr('src') != null){
                $('#FacebookPostImagePreview img').attr('src',$('div.component div.item:first img').attr('src'));
                $('#FacebookPostImagePreview').removeClass('fsHidden');
            }else{
                $('#FacebookPostImagePreview').toggleClass('fsHidden',true);
            }
        }else{
            if($('div.component img.primary').attr('src') != null){
                $('#FacebookPostImagePreview img').attr('src',$('div.component img.primary').attr('src'));
                $('#FacebookPostPicture').val($('div.component img.primary').attr('src'));
                $('#FacebookPostImagePreview').removeClass('fsHidden');
            }else{
                $('#FacebookPostImagePreview').toggleClass('fsHidden',true);
            }
        }
        return false;
    }
}

function Facebook(){
    this.key = 'b35ba28da46540572e5346c6a6b516df';

    this.setKey = function(key){
        if(key != null && key != ''){
            this.key = key;
        }
        return false;
    }

    this.getKey = function(){
        return this.key;
    }

    this.initFB = function(){
        if($('#FBJSSDK').length == 1){
            FB_RequireFeatures(["XFBML"], function(){
                FB.init(window.facebook.getKey(), "/connect/xd_receiver.htm");
            });
        }
        return false;
    }

    this.loadContent = function(data){
        window.overlayWindow.setContentClass(window.overlayWindow.defaultContentClass);
        window.overlayWindow.loadContent(data);
        return false;
    }

    this.connect = function(){
        window.overlayWindow.requestContent('/users/facebookConnect/','window.facebook.loadContent(data);');
        //window.facebook.requestContent('/users/facebookConnect/');
        return false;
    }

    this.register = function(){
        window.overlayWindow.requestContent('/users/facebookConnect/1','window.facebook.loadContent(data);');
        //this.requestContent('/users/facebookConnect/1');
        return false;
    }

    this.disconnect = function(){
        if(confirm('Are you sure you want to disconnect your account from your Facebook account?')){
            FB.Facebook.apiClient.revokeAuthorization(FB.Connect.get_loggedInUser(),window.facebook.disconnectAccount);
            window.facebook.showAccountConnect();
        }
        return false;
    }

    this.disconnectAccount = function(){
        this.request = new AjaxRequest1('/dc/users/facebookDisconnect');
        this.request.setSuccessCallback('window.contentHandler.load(data);');
        this.request.quickExecute();
        return false;
    }

    this.hideAccountConnect = function(){
        $('div.profile div.article div.profile_data div.facebookConnect').toggleClass('fsHidden',true);
        $('div.profile div.article div.profile_data div.facebookDisconnect').toggleClass('fsHidden',false);
        return false;
    }

    this.showAccountConnect = function(){
        $('div.profile div.article div.profile_data div.facebookConnect').toggleClass('fsHidden',false);
        $('div.profile div.article div.profile_data div.facebookDisconnect').toggleClass('fsHidden',true);
        return false;
    }

    this.showPostWindow = function(){
        window.overlayWindow.requestContent('/interactions/facebook');
        return false;
    }

    this.getPublishStreamPermission = function(){
        FB.Connect.showPermissionDialog('publish_stream',window.facebook.updatePublishStreamInput,true);
        return false;
    }

    this.updatePublishStreamInput = function(){
        $('#FacebookStreamPublish').val(1);
        window.facebook.publish();
        return false;
    }

    this.publish = function(){

        if($('#FacebookStreamPublish').val() != 1){
            this.getPublishStreamPermission();
        }else{

            this.message = $('#FacebookPostMessage').val();

            if($('div.component img.primary').attr('src') != null && $('#FacebookPostImage:checked').length == 1){
                this.attachment = {
                    'name':$('#FacebookPostName').val(),
                    'href':$('#FacebookPostHref').val(),
                    //'caption':$('#FacebookPostCaption').val(),
                    'description':$('#FacebookPostDescription').val(),
                    'media':[{
                        'type':'image',
                        'src':'http://'+window.location.hostname+$('div.component img.primary').attr('src'),
                        'href':$('#FacebookPostHref').val()
                    }]
                };
            }else{
                this.attachment = {
                    'name':$('#FacebookPostName').val(),
                    'href':$('#FacebookPostHref').val(),
                    //'caption':$('#FacebookPostCaption').val(),
                    'description':$('#FacebookPostDescription').val()
                };
            }

            //if($('#FacebookShowPreview:checked').length == 1){
            this.autoPublish = false;
            /*}else{
				this.autoPublish = true;
			}*/

            this.actionLinks = null;
            this.actorId = $('#FacebookTargetId').val();
            this.userPromptMessage = 'Please check the preview of your post below is correct, then click the Publish button.';

            FB.Connect.streamPublish(this.message,this.attachment,this.actionLinks,null,this.userPromptMessage,window.facebook.publishCallback,this.autoPublish,this.actorId);
        }
        return false;
    }

    this.publishCallback = function(postId,exception){
        window.overlayWindow.hide();
        return false;
    }

    this.setUpPostObject = function(){
        $('#FacebookPostHref').attr('value',document.location.href.replace('/#',''));

        $('#FacebookPostDescription').attr('value',window.navigation.getCurrentPageDescription());

        var pageTitle = document.title.replace('[Edit Mode On]','');
        $('#FacebookPostName').attr('value',pageTitle);

        if($('div.component').hasClass('galleryAlbum')){
            if($('div.component div.item:first img').attr('src') != null){
                $('#FacebookPostImagePreview img').attr('src',$('div.component div.item:first img').attr('src'));
                $('#FacebookPostImagePreview').removeClass('fsHidden');
            }else{
                $('#FacebookPostImagePreview').toggleClass('fsHidden',true);
            }
        }else{
            if($('div.component img.primary').attr('src') != null){
                $('#FacebookPostImagePreview img').attr('src',$('div.component img.primary').attr('src'));
                $('#FacebookPostImagePreview').removeClass('fsHidden');
            }else{
                $('#FacebookPostImagePreview').toggleClass('fsHidden',true);
            }
        }
        return false;
    }

//$('#FacebookDisconnect').live('click',this.disconnect);
}

function Widgets(){

    this.reload = function(){
        window.mediaPlayer.reloadPlayer(window.mediaPlayer.getCurrentlyPlaying(),1);
        this.reloadUserProfile();
        this.reloadEvents();
        this.reloadNews();
        return false;
    }

    this.reloadBasket = function(){
        this.basketRequest = new AjaxRequest1('/dc/orders/basket');
        this.basketRequest.quickExecute('#wBasket',true);
        return false;
    }

    this.reloadEvents = function(){
        this.eventsWidgetRequest = new AjaxRequest1('/dc/events/widget/');
        this.eventsWidgetRequest.quickExecute('#wEvents',true);
        return false;
    }

    this.reloadNews = function(){
        this.newsWidgetRequest = new AjaxRequest1('/dc/news/widget/');
        this.newsWidgetRequest.quickExecute('#wNews',true);
        return false;
    }

    this.reloadUserProfile = function(){
        this.userProfileRequest = new AjaxRequest1('/dc/user_profiles/widget');
        this.userProfileRequest.quickExecute('#wUserProfile',true);
        return false;
    }

    this.reloadMediaPlayer = function(id){
        window.mediaPlayer.reloadPlayer(window.mediaPlayer.getCurrentlyPlaying(),1);
        /*if(id != null){
			if(id == ''){
				id = 0;
			}
		}else{
			id = 0;
		}
		this.mediaPlayerRequest = new AjaxRequest1('/dc/playlists/player/'+id+'/'+window.mediaPlayer.isPlaying());
		this.mediaPlayerRequest.quickExecute('#wMediaplayer',true);*/
        return false;
    }

}

function SystemOverview(){

    this.toggleCountryFilter = function(event){
        $('#Filter'+event.data.filterType).toggleClass('fsHidden');
        if($(this).html() == 'Show'){
            $(this).html('Hide');
        }else{
            $(this).html('Show');
        }
        return false;
    }

    this.checkAllFilters = function(event){
        $('#Filter'+event.data.filterType+' input:checkbox').attr('checked',true);
        return false;
    }

    this.uncheckAllFilters = function(event){
        $('#Filter'+event.data.filterType+' input:checkbox').attr('checked',false);
        return false;
    }

    // listeners
    $('#FilterCountryToggle').bind('click',{
        filterType: 'Country'
    },this.toggleCountryFilter);
    $('#FilterGenreToggle').bind('click',{
        filterType: 'Genre'
    },this.toggleCountryFilter);
    $('#FilterCountryAll').bind('click',{
        filterType: 'Country'
    },this.checkAllFilters);
    $('#FilterCountryNone').bind('click',{
        filterType: 'Country'
    },this.uncheckAllFilters);
    $('#FilterGenreAll').bind('click',{
        filterType: 'Genre'
    },this.checkAllFilters);
    $('#FilterGenreNone').bind('click',{
        filterType: 'Genre'
    },this.uncheckAllFilters);

}



function MediaPlayer(path)
{
    this.autoPlayID = false;
    this.playerType = 'FLASH';
    this.playing = false;
    this.currentTrack = '0';
    this.path = '/';
    this.config = 'normal';

    this.setAutoPlay = function(value){
        this.autoPlayID = value;
        return false;
    }

    this.setConfig = function(config){
        this.config = config;
        return true;
    }

    this.setPath = function(path){
        this.path = path;
        return false;
    }

    this.isPlaying = function(){
        return this.playing;
    }

    this.getCurrentlyPlaying = function(){
        return this.currentTrack;
    }

    this.autoPlay = function(){
        if($('object#fsConstantPlayer').length < 1){
            setTimeout("window.mediaPlayer.autoPlay();",500);
        }else{
            this.playMedia(this.autoPlayID,true);
            this.autoPlayID = null;
        }
        return false;
    }

    this.loadPlayer = function() {

        // create a HTML5 audio tag
        var myAudio = document.createElement('audio');

        // check if the browser has audio tag support
        if (!!myAudio.canPlayType) {

            // check if the audio tag is compatable with mp3
            // *** Currently canPlayType(type) returns: "", "maybe" or "probably"
            if (myAudio.canPlayType('audio/mpeg') != "") {

                // FIXME: Chrome doesn't seem to be able to stream mp3s from the test or live servers so don't use native audio for it
                if (navigator.userAgent.indexOf('Chrome') == -1 && (navigator.userAgent.indexOf('Mobile') != -1 || navigator.userAgent.indexOf('iPad') != -1)) {
                    this.playerType = 'HTML5';
                }
            }

        // check if the audio tag is compatable with ogg
        /*if (myAudio.canPlayType('audio/ogg; codecs="vorbis"') != "") {

				alert('can play ogg');
			}*/
        }

        if (this.playerType == 'FLASH') {

            this.loadFlashAudioPlayer();
        }
    }

    this.loadFlashAudioPlayer = function(){
        if(window.swfobject !== undefined){
            var flashvars = {};
            flashvars.player_type = "music";
            var params = {};
            params.menu = "false";
            params.scale = "noscale";
            var attributes = {};
            attributes.name = "fsMediaplayer";
            window.swfobject.embedSWF("/flash/mediaplayer.swf", "fsConstantPlayer", "1", "1", "8.0.0", false, flashvars, params, attributes);
            if(this.autoPlayID != false){
                setTimeout('window.mediaPlayer.autoPlay();',500);
            }
        }
        return false;
    }

    this.playMedia = function(id,stopReload){
        // Reset all the other buttons first, as they can't be playing too
        this.resetButtons();

        if (this.playerType == 'HTML5') {

            // get the audio DOM object
            var audio = $('#fsConstantPlayer audio').get(0);

            // set the src attribute to the path to the file
            $(audio).attr('src', '/files/audio/' + this.path + '/' + id + '.mp3');

            audio.load();

            // bind the timeupdate event so that the time display is updated as the track plays
            $(audio).bind('timeupdate', function() {

                // format the current time and duration into minutes and seconds
                var currentTime = parseInt(audio.currentTime, 10),
                currentTimeMins = Math.floor(currentTime/60,10),
                currentTimeSecs = currentTime - currentTimeMins*60,
                time = currentTimeMins + '.' +  (currentTimeSecs > 9 ? currentTimeSecs :  '0' + currentTimeSecs);
                // update the time display
                window.mediaPlayer.updateTimeStamp(time);

            });

            // bind the ended event to trigger the playNextMedia method
            $(audio).bind('ended', function() {
                window.mediaPlayer.playNextMedia();
            });

            // play the source
            audio.play();

        } else {

            // Send a message to the flash to play this item
            window.getFlashMovie("fsConstantPlayer").sendToFlash(this.path+'/'+id+'.mp3');
        }

        this.mediaPlaying = true;
        // record the id of the MediaFile
        $('#currentlyPlaying').html(id);
        this.currentTrack = id;
        if(stopReload == null){
            // reload player widget with new media info
            this.reloadPlayer(id);
        }
        // Tell the play button to fuck off and show the stop button
        this.swapPlayButton(id);
        return false;
    }

    this.playNextMedia = function(){
        if($('#fsBtnMediaPlayerNext span.icoNext').hasClass('disabled') != true){
            $('#fsBtnMediaPlayerNext span.icoNext').trigger('click');
        }else{
            this.resetButtons();
        }
        return false;
    }

    this.stopMedia = function(){
        this.resetButtons();
        //update the server session
        //$.get('http://'+document.domain+'/dc/playlists/stop');
        var stopRequest = new AjaxRequest1('/dc/playlists/stop');
        stopRequest.clearSuccessCallback();
        stopRequest.execute();
        this.playing = false;
        return false;
    }

    this.swapPlayButton = function(id){
//		alert('swapit = '+id);
/*        $('.fsMediaPlayer span.icoPlay').hide();
        $('.fsMediaPlayer span.icoStop').css('display','block');
        // Highlight the row we are playing
        $("#PlaylistItemTrack_"+id).addClass("currently_playing");
        // Switch the visibility of this rows buttons
        $("#PlaylistItemTrack_"+id+" span.icoPlay").hide();
        $("#PlaylistItemTrack_"+id+" span.icoStop").show();
        $("#Track_"+id+" span.icoPlay").hide();
        $("#Track_"+id+" span.icoStop").css('display','block');
		
		// Highlight the row we are playing
        $("#MediaItemTrack_"+id).addClass("currently_playing");
        // Switch the visibility of this rows buttons
        $("#MediaItemTrack_"+id+" span.icoPlay").hide();
        $("#MediaItemTrack_"+id+" span.icoStop").show();
*/
		$(".jsMedia_"+id+" span.icoPlay").hide();
		$(".jsMedia_"+id+" span.icoStop").css('display','block');
		
		$("tr.jsMedia_"+id).addClass("currently_playing");
		
		/*
		$(".jsTrack_4decda4c-e3d4-4e1f-97c6-12c1ae6d8f0d span.icoPlay").hide();
		$(".jsTrack_4decda4c-e3d4-4e1f-97c6-12c1ae6d8f0d span.icoStop").css('display','block');
		*/
		
        return false;
    }

    this.toggleMute = function(action){

        if (this.playerType == 'HTML5') {

            // get the audio DOM object
            var audio = $('#fsConstantPlayer audio').get(0);

            // set the volume accordingly
            if (action == 'unmute') {
                audio.volume = 1;
            } else {
                audio.volume = 0;
            }

        } else {
            // Tell the flash to do the action
            window.getFlashMovie("fsConstantPlayer").sendToFlash(action);
        }

        if(action == "unmute"){
            // Switch the visibility of the buttons
            $("span.icoMute").hide();
            $("span.icoVolume").show();
        }else if(action == "mute"){
            // Switch the visibility of the buttons
            $("span.icoVolume").hide();
            $("span.icoMute").show();
        }
        return false;
    }

    this.updateTimeStamp = function(time){
        $('span.fsTimestamp').html(time);
        return false;
    }

    this.resetButtons = function(){

        if (this.playerType == 'HTML5') {

            // stop the audio
            $('#fsConstantPlayer audio').get(0).pause();

        } else {

            // Actually stop all other flash content
            window.getFlashMovie("fsConstantPlayer").sendToFlash("stop");
        }

        this.updateTimeStamp('0.00');

        $('#currentlyPlaying').empty();
        // Reset the currently playing TR
        $("tr.item").removeClass("currently_playing");
        // Reset all the play buttons to be shown and the stop buttons to be hidden
        $("span.icoPlay").show();
        $("span.icoStop").hide();
        return false;
    }

    this.checkCurrentlyPlaying = function(){
        var current = $('#currentlyPlaying').html();
        var current = this.currentTrack;
        if(current != '0'){
            this.swapPlayButton(current);
        }
        return false;
    }

    this.showInfo = function(id){
        // Display the correct info box
        $("#Track_"+id+"_details").toggle();
        return false;
    }

    if(path != null){
        this.path = path;
    }

    this.reloadPlayer = function(id,isRefresh){
        if(id == null){
            id = this.getCurrentlyPlaying();
        }
        if(isRefresh == null){
            isRefresh = '';
        }
        if(this.config == 'facebook'){
            var url = '/dc/playlists/facebookPlayer/';
        }else{
            var url = '/dc/playlists/player/';
        }
        this.mediaPlayerRequest = new AjaxRequest1(url+id+'/'+this.isPlaying()+'/'+isRefresh);
        this.mediaPlayerRequest.quickExecute('#wMediaplayer',true);
        return false;
    }
}


















/*===============================================================


	VERSION 1


==================================================================*/

//initialise global vars
var siteParams = new Array();
siteParams.ajaxNavigation = true;
//the site id
var siteId = 0;

var debugMode = false;

var reloadTemplateAfterSave = false;

var popUpWindow;

// INITIALISE OBJECTS
//window.ajaxManager = new AjaxManager();
window.siteBar = new SiteBar();
window.uploadManager = new UploadManager();
window.navigation = new Navigation();
window.contentHandler = new ContentHandler();
window.widgets = new Widgets();
window.alertsManager = new AlertsManager();
window.form = new Form();
window.facebook = new Facebook();
window.socialNetwork = new SocialNetwork();
window.mediaPlayer = new MediaPlayer();
// initialise ajax navigation - this needs to be called from the PHP dependinfg on the navigation settings
//window.navigation.setToAjax();


/*var siteBar = new Object();
siteBar.cancelLoad = false;*/

var imageBrowser = new Object();
imageBrowser.keepOpen = false;

//used to detect if ajax navigation should be activated
//var ajaxNavigation = true;
var historyPluginInitialised = false;
//records the url before ajax requests are made
var refererUrl = '';
//JQuery selector for destination element of returned HTML
var returnTo = '#fsca1';
//if true, then all activity that takes place is for the site bar
var siteBarContent = false;
//url used by the AjaxForm helper
//var formReturnUrl;
//used to set the title of the page
var pageTitle;
var pageDescription;
//used by the ajaxRequest function to decide if a request should be made
var makeAjaxRequest = true;
//JQuery selector for the default destination of HTML returned by ajax requests
var defaultContentArea = '#fsca1';
//HTML to be displayed in the content whilst ajax requests retrieve data
var loading = 'Loading...';
//initialise the state of edit mode
var editModeOLD = 'off';

var loggedInStatus = 0;

//holds an array of instance names for the current nicEdit text editors on the page
var textEditors = new Array();
//playlist
//var mediaPlaylist = new Array();

var mediaPlaying = 0;

var ajaxForms = new Array();

var wizard = new Object();
wizard.load = false;
wizard.running = false;

var onLoadSendToHomePage = false;

var formInputEditedFlag = false;

var formInputEditedPrompt = 'Are you sure you want leave this page without saving any changes you\'ve made?';

var uploading = 0;
var timerSet = 0;
var uploadProgressTimer;
var nullUploadProgressDataCount = 0;

var europeanCountryCodes = null;

//when set to true, the data returned from the server after an ajax request will be displayed in an alert before being rendered
var debugRawAjaxResponse = false;
var debugFormattedAjaxResponse = false;


$(document).ready(function(){

    // load the media player
    window.mediaPlayer.loadPlayer();

    init();
    //show loading icon in main content area??

    //check to see if this site uses ajax navigation
    //alert('check nav mode');
    if(siteParams.ajaxNavigation){

    //activateAjaxNavigation();

    }

    inputDefaults();

    //file slector tabs
    fileBrowserTabEvents();

    // set all forms to submit when the return key is pressed when an input is selected
    returnKeySubmission();

    function showhideEditmodeActions(e) {

        var clicked = $(e.target); // get the element clicked

        if(clicked.is('.fsEditDropdown') || clicked.parents().is('.fsEditDropdown')) {
            e.stopPropagation();
        }else{
            $('.fsEditDropdown').fadeOut(300);
            $(document).unbind('click',showhideEditmodeActions);
        }
    }

    $('.fsBtnEditDropdown').live('click',function(){
        //$('.fsEditDropdown',this).show();
        //$('.fsEditDropdown').show();
        $(this).parent().children('.fsEditDropdown').show();
        $(document).bind('click',showhideEditmodeActions);
    });

    $('table.items.members tr.item td span').live('click',function(){
        $('table.items.members tr.item').removeClass('highlight');
        $(this).parents('tr:first').addClass('highlight');
    });

    $('div.showMore').live('click',function(){
        $(this).parents().children('div.showMore').toggle();
    });

    $('.showContent').live('click',function(){
        $(this).parents().children('.hiddenContent').toggle();
    });

    $('.slideToggle').live('click',function(){
        var toggleElement = $(this).attr('id').replace('toggle','cs');
        $('#'+toggleElement).slideToggle();
        $(this).toggleClass('fsToggled')
    });

    function showhideCtrlSettings(e) {

        var clicked = $(e.target); // get the element clicked

        if(clicked.is('.ctrlSettings') || clicked.parents().is('.ctrlSettings')) {
            e.stopPropagation();
        }else{
			$('.ctrlSettings').removeClass('ctrlSettingsOpen');
            $(document).unbind('click',showhideCtrlSettings);
        }		
    }

    $('.ctrlSettingsButton').live('click',function(){
		$(this).parents('.ctrlSettings').addClass('ctrlSettingsOpen');
        $(document).bind('click',showhideCtrlSettings);
    });

    $('.fsToggleComments').live('click',function(){
        $(this).parents('div.component').children('div.items').toggle();
        if($(this).html()=='(Show)'){
            $(this).html('(Hide)');
        }else{
            $(this).html('(Show)');
        }
    });


    function showhideSharer(e) {

        var clicked = $(e.target); // get the element clicked

        if(clicked.is('.fsSharer') || clicked.parents().is('.fsSharer')) {
            e.stopPropagation();
        }else{
            $('.fsShare').fadeOut(300);
            $(document).unbind('click',showhideSharer);
        }
    }

    $('.fsSharer').live('click',function(){
        $('div.fsShare',this).show();
        $(document).bind('click',showhideSharer);
    });

    $('input.fsShareInput,textarea.fsShareTextarea').live('click',function(){
        $(this).select();
    });

    $('span.fsShareCopy').live('click',function(){
        var widgetEmbedCode = $(this).parents("div.fsShareCode").children('textarea').attr('value');
        alert('Copy the "widgetEmbedCode" to the clipboard.  We have to use a flash function or similar (http://plugins.jquery.com/project/clipboard) to do it, so it might be a good idea to include this in the media player constant .swf');
    });

    $('.fsQuestion').live('click',function(){
        $('.fsAnswer').hide();
        $('.fsQuestionOpen').removeClass('fsQuestionOpen');
        $(this).addClass('fsQuestionOpen');
        $('span',this).toggleClass('icoPlus');
        $(this).parents().children('.fsAnswer').toggle();
    });

    /*	$('h3.fsQuestion').live('click',function(){
		//$('div.fsAnswer').slideUp(200);
		$('span',this).toggleClass('icoPlus');
		$(this).parents().children('div.fsAnswer').toggle();
	});*/

    // NEW OBJECT CONSTRUCTORS
    window.sideBar = new SideBar();
    window.help = new Help();
    window.overlayWindow = new OverlayWindow();
    window.wizard = new Wizard();
    // initialise the Facebook object
    window.facebook.initFB();
    window.mediaBrowser = new MediaBrowser();

    window.datepickerDateFormat = 'd MM yy';
}); 

function addFormInputOnChangeListeners(id){
    removeFormInputOnChangeListeners(id);
    $('form#'+id+' input, form#'+id+' div.fsEditable textarea').bind('change',{
        formId: id
    },flagEditedInput);
    // nicEditors
    $('form#'+id+' textarea').prev('div').children('div').bind('keyup',{
        formId: id
    },flagEditedInput);
    return false;
}

function removeFormInputOnChangeListeners(id){
    $('form#'+id+' input, form#'+id+' div.fsEditable textarea').unbind('change',flagEditedInput);
    // nicEditors
    $('form#'+id+' textarea').prev('div').children('div').unbind('keyup',flagEditedInput);
    return false;
}

function flagEditedInput(event){
    formInputEditedFlag = true;
    removeFormInputOnChangeListeners(event.data.formId);
    return false;
}

function init(){
    //eval('siteParams = '+siteParams);
    for(key in siteParams){
        //alert(key+' = '+siteParams[key]);
        if(siteParams[key] == null){
            eval(key+' = false;');
        }else{
            eval(key+' = \''+siteParams[key]+'\';');
        }
    }
    return;
}

/*===============================================================


	SHOPPING BASKET HELPER FUNCTIONS


==================================================================*/

function addToBasket(productId){
    //alert('add '+productId);
    //ajaxRequest('/order_lines/create/'+productId,'#wBasket',true);
    var addToBasketRequest = new AjaxRequest1('/dc/order_lines/create/'+productId);
    addToBasketRequest.quickExecute('#wBasket',true);
    return false;
}

function removeFromBasket(productId){
    //alert('delete '+productId);
    //ajaxRequest('/order_lines/delete/'+productId,'#wBasket',true);
    var delFromBasketRequest = new AjaxRequest1('/dc/order_lines/delete/'+productId);
    delFromBasketRequest.quickExecute('#wBasket',true);
    return false;
}

function refreshOrder(orderId){
    //setTimeout("ajaxRequest('/orders/complete/"+orderId+"/');",3000);
    //alert('refresh order: '+orderId);
    setTimeout("window.navigation.requestHandler('/orders/complete/"+orderId+"/');",3000);
    return;
}

/*===============================================================


	HELP WINDOW & WIZARD HELPER FUNCTIONS


==================================================================*/




function adjustTemplate(windowstatus,resizeWindow){
    //alert('adjusting template = '+windowstatus);
    if(windowstatus=='helpopen'){
        $('body').addClass('helpopen');
        //$('#fsHelp').fadeIn(400);
        $('#fsHelp').show();
    }else if(windowstatus=='helpclose'){
        $('#fsHelp').fadeOut(300);
        $('body').removeClass('helpopen');
        toggleWizardInfo('off')
    }else if(windowstatus=='pushbody'){
        //		alert('push body and adjust to '+resizeWindow);
        $('body').addClass('sitebaropen');

    /*
		if(resizeWindow==null){
			// the next few lines resize the open sitebar window to fit in the screen and add a scrollbar if needed
			var sbSitebarContentHeight = $('div#sbSitebarContent').height();
			var sbSitebarContentMaxHeight = $(window).height()-70;

			if(sbSitebarContentHeight >= sbSitebarContentMaxHeight){
				$('div#sbSitebarContent').height(sbSitebarContentMaxHeight);
			}else{
				$('div#sbSitebarContent').attr('style',null);
			}
		}
*/
    }else if(windowstatus=='pullbody'){
        $('body').removeClass('sitebaropen');
    //$('#fsHelp').show();
    }

    return false;
}

function scrollTemplateThumbs(direction){
    var currentPos = $('div#templateThumbs').position().top;

    if(currentPos>=0 && direction=='up'){
        newPos = 0;
    }else{
        if(direction=='up'){
            var newPos = currentPos+188;
        }else if(direction=='down'){
            var newPos = currentPos-188;
        }
    }
    var newRoundedPos = Math.round(newPos/188)*188;
    $('div#templateThumbs').animate({
        top: newRoundedPos
    }, 400);

    return false;
}

function previewSite(action,section){
    if(action=='on'){
        //adjustTemplate('helpclose');
        sideBar.close();

        // siteBar.close
        $('div#fsSitebar').slideUp();
        adjustTemplate('pullbody');

        // siteBar.hide
        $('div#fsSitebarPos').css('height','16px');
        $('div#fsSitePreview').show();

        // set to var in editMode object
        $('div#fsSitePreview').attr('title',section);

        if(section != 'opensitebar'){
            // Turn edit mode off
            doEditMode('off');
        }

    }else if(action=='off'){
        $('div#fsSitePreview').hide();
        $('div#fsSitebar').slideDown();
        //		alert('Sec = '+section);
        if($('div#fsSitePreview').attr('title')=='opensitebar'){
            adjustTemplate('pushbody','noresize');
        }else{
            // Turn edit mode back on...
            doEditMode('on');
        }
        $('div#fsSitePreview').attr('title',null);
        $('div#fsSitebarPos').attr('style',null);
        if(wizard.running == true){
            toggleWizardInfo('on');
            //adjustTemplate('helpopen');
            sideBar.open();
        }
    }

    return false;
}

/*===============================================================


	HOMEPAGE AGGREGATE DISPLAY OPTIONS


==================================================================*/

function toggleAggregate(target){
    $(target).toggleClass('fsDisabled');
    return;
}

/*===============================================================


	SOCIAL NETWORK BOOKMARK FUNCTIONS


==================================================================*/

function fsSharer(type,siteUrl){

    var pageTitle = document.title;
    var pageDescription = pageTitle+' taken from '+siteUrl;

    if(type == 'facebook'){
        window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(siteUrl)+'&t='+encodeURIComponent(pageTitle),'fsWindow','toolbar=no,width=600,height=400');
    }else if(type == 'delicious'){
        window.open('http://del.icio.us/post?v=4&noui&jump=close&url='+encodeURIComponent(siteUrl)+'&title='+encodeURIComponent(pageTitle),'delWindow','toolbar=no,width=600,height=400');
    }else if(type == 'myspace'){
        var targetUrl = 'http://www.myspace.com/index.cfm?fuseaction=postto&t='+encodeURIComponent(pageTitle)+'&c='+encodeURIComponent(pageDescription)+'&u='+encodeURIComponent(siteUrl);
        window.open(targetUrl);
    }else if(type == 'digg'){
        var targetUrl = 'http://digg.com/submit?phase=2&url='+encodeURIComponent(siteUrl)+'&title='+encodeURIComponent(pageTitle)+'&bodytext='+encodeURIComponent(pageDescription);
        window.open(targetUrl);
    }else if(type == 'furl'){
        var targetUrl = 'http://www.furl.net/storeIt.jsp?t='+encodeURIComponent(pageTitle)+'&u='+encodeURIComponent(siteUrl);
        window.open(targetUrl);
    }else if(type == 'google'){
        var targetUrl = 'http://www.google.com/bookmarks/mark?op=edit&bkmk='+encodeURIComponent(siteUrl)+'&title='+encodeURIComponent(pageTitle);
        window.open(targetUrl);
    }else if(type == 'stumbleupon'){
        var targetUrl = 'http://www.stumbleupon.com/submit?url='+encodeURIComponent(siteUrl)+'&title='+encodeURIComponent(pageTitle);
        window.open(targetUrl);
    }else if(type == 'twitter'){
        var targetUrl = 'http://twitter.com/home?status='+encodeURIComponent(pageTitle)+' visit '+encodeURIComponent(siteUrl);
        window.open(targetUrl);
    }else if(type == 'favs'){
        if (window.sidebar) { // Mozilla Firefox Bookmark
            window.sidebar.addPanel(pageTitle, siteUrl,"");
        } else if( window.external ) { // IE Favorite
            window.external.AddFavorite(siteUrl,pageTitle);
        }
        else if(window.opera && window.print) { // Opera Hotlist
            return true;
        }
    }else if(type == 'email'){
        var href = "mailto:?"
        + "subject=" + siteUrl + "&"
        + "body=Hi, Thought you may be interested in this - " + pageDescription;
        var wndMail = window.open(href, "_blank", "scrollbars=yes,resizable=yes,width=10,height=10");
        if( wndMail ) {
            wndMail.close();
        }
    }

    $('.fsShare').fadeOut(300);
    $('body').unbind('click');

    return false;
}

function socialInteraction(section){
    if(section == 'close'){
        $('div#fsSocialNetworkUI').fadeOut(100);
        $('#fsSocialnetworkBubble').html(null);
    }else{
        ajaxRequest('/interactions/'+section,'#fsSocialnetworkBubble',false, 'fadeSocialNetworkBubble');
    /*var request = new AjaxRequest1('/dc/interactions/'+section);
		request.setSuccessCallback('window.fadeSocialNetworkBubble();');
		request.quickExecute('#fsSocialnetworkBubble',false);*/
    }
    return false;
}

function fadeSocialNetworkBubble(){
    $('div#fsSocialNetworkUI').fadeIn(100);
}

function socialInteractionText(){
    var url = window.navigation.getCurrentPageShortUrl();
    if(url == null){
        url	= document.location.href.replace('/#','');
    }
    var page_description = url+' - '+window.navigation.getCurrentPageDescription();
    $('.socialText').attr('value',page_description);

    var page_title = document.title.replace('[Edit Mode On]','');
    $('.socialTitle').attr('value',page_title);
    return false;
}

/*===============================================================


	LEGAL DOCUMENTS HELPER FUNCTIONS


==================================================================*/

function displayLegalDocument(documentId){
    window.open('http://'+window.location.hostname+'/dc/legal/'+documentId,'fsLegal','scrollbars=1,toolbar=0,status=0,location=0,menubar=0,width=600,height=400');
    return false;
}

/*===============================================================


	COMMENTS HELPER FUNCTIONS


==================================================================*/

function toggleCommentEditForm(model,id){
    $('#'+model+'CommentDisplay'+id).toggleClass('fsHidden');
    $('#'+model+'CommentEdit'+id).toggleClass('fsHidden');
    return false;
}

function deleteComment(model,foreignKey,id){
    if(confirm('Are you sure you want to delete this comment?')){
        //ajaxRequest('/comments/delete/'+model+'/'+foreignKey+'/'+id,'#'+model+'Comments',true);
        var delCommentRequest = new AjaxRequest1('/dc/comments/delete/'+model+'/'+foreignKey+'/'+id);
        delCommentRequest.quickExecute('#'+model+'Comments',true);
    }
    return false;
}

function reportComment(model,foreignKey,id){
    if(confirm('Are you sure you want to report this comment?')){
        //ajaxRequest('/comments/report/'+model+'/'+foreignKey+'/'+id,'#'+model+'Comments',true);
        var reportCommentRequest = new AjaxRequest1('/dc/comments/report/'+model+'/'+foreignKey+'/'+id);
        reportCommentRequest.quickExecute('#'+model+'Comments',true);
    }
    return false;
}

/*===============================================================


	MUSIC HELPER FUNCTIONS


==================================================================*/

function downloadTrack(trackId,reference){
    var url = 'http://'+document.domain+'/dc/tracks/download/'+trackId
    if(reference != null){
        if(reference){
            url+= '/'+reference;
        }
    }
    window.location.href = url;
    return false;
}

function downloadRelease(releaseId,reference){
    var url = 'http://'+document.domain+'/dc/releases/download/'+releaseId
    if(reference != null){
        if(reference){
            url+= '/'+reference;
        }
    }
    window.location.href = url;
    return false;
}

function trackDetails(DOM){
    $(DOM).parents('tr.item').next('tr.media-details').toggleClass('fsHidden');
    return;
}

function trackStreamingOptions(){
    $('div.music div.streaming').toggleClass('fsDisabled');
    if($('#TrackStreamMembersOnly').attr('disabled') == true){
        $('#TrackStreamMembersOnly').removeAttr('disabled');
    }else{
        $('#TrackStreamMembersOnly').attr('disabled',true);
    }
    //$('div.music div.streaming input[disabled!=]').attr('disabled','disabled');
    return;
}

function trackDownloadingOptions(){
	$('div.music div.downloading').toggleClass('fsDisabled');

    if($('#TrackDownloadMembersOnly').attr('disabled') == true){
		$('#TrackDownloadMembersOnly').removeAttr('disabled');
	}else{
		$('#TrackDownloadMembersOnly').attr('disabled',true);
	}

    if($('#TrackDownloadForEmail').attr('disabled') == true){
		$('#TrackDownloadForEmail').removeAttr('disabled');
	}else{
		$('#TrackDownloadForEmail').attr('disabled',true);
	}

	return;
}

function trackProducts(){
    $('div.music div.products').toggleClass('fsDisabled');

    $('div.music div.products input[type!=hidden]').each(function(i){
        if($(this).attr('disabled') == true){
            $(this).removeAttr('disabled');
        }else{
            $(this).attr('disabled',true);
        }
    });
    return;
}


//formats parameter depending if the browser is IE
function getFlashMovie(movieName) {

    var isIE = navigator.appName.indexOf("Microsoft") != -1;
    return (isIE) ? window[movieName] : document[movieName];
}


/*===============================================================


	UPLOAD HELPER FUNCTIONS


==================================================================*/

function cleanJSON(json){
    json = json.replace('\\x','\\');
    return json;
}

/*===============================================================


	MUSIC UPLOADER HELPER FUNCTIONS


==================================================================*/

function updateTrack(DOM){
    //alert($(DOM).val());
    //put the JSON data from the upload into an array
    var json = cleanJSON($(DOM).val());
    eval('var uploadedData = '+json);
    //put the inserted Track id into the hidden input
    //$('#TrackId').val(uploadedData['Track']['id']);
    //set the action of the form to update the new Track
    $('#TrackEdit').attr('action','/tracks/view/'+uploadedData['Track']['slug']);

    // remove the uploader
    $('#TrackFileUploaderWrapper').hide();

    //show the uploaded file name
    $('#TrackFileName').val(uploadedData['MediaFile']['file']['name']);
    $('#TrackFileNameWrapper').removeClass('fsHidden');


    //if the user has not entered a title yet, auto fill one
    if(($('#TrackTitle').val() == '') || ($('#TrackTitle').val() == $('#TrackTitle').attr('title'))){
        $('#TrackTitle').removeClass('fsFadedText');
        //var fileName = uploadedData['MediaFile']['file']['name'].split('.');
        $('#TrackTitle').val(uploadedData['Track']['title']);
    }
    return false;
}

/*===============================================================


	IMAGE BROWSER HELPER FUNCTIONS


==================================================================*/

function fileBrowserTabEvents(){

    $('div.fsFileselectTabs span.fsTabBrowse').live('click',function(){

        var browseTab = this;
        $(browseTab).siblings('span').removeClass('fsInputcolour');
        $(browseTab).addClass('fsInputcolour');
        var fileSelect = $(browseTab).parents('div.fsFileselect');
        fileSelect.children('div.fsFileselectUpload').hide();
        fileSelect.children('div.fsFileselectBrowse').show();
        $('body').bind('click',function(){
            if(imageBrowser.keepOpen != true){
                $(browseTab).siblings('span').addClass('fsInputcolour');
                $(browseTab).removeClass('fsInputcolour');
                fileSelect.children('div.fsFileselectBrowse').hide();
                fileSelect.children('div.fsFileselectUpload').show();
                $('body').unbind('click');
            }else{
                imageBrowser.keepOpen = false;
            }
        });
        return false;
    });

    $('div.fsFileselectTabs span.fsTabUpload').live('click',function(){
        $(this).siblings('span').removeClass('fsInputcolour');
        $(this).addClass('fsInputcolour');
        var fileSelect = $(this).parents('div.fsFileselect');
        fileSelect.children('div.fsFileselectBrowse').hide();
        fileSelect.children('div.fsFileselectUpload').show();
        return false;
    });
    return false;
}

function selectUploadedImage(DOM,inputId,size,updateBrowser){
    //retrieve the data from the upload
    var json = cleanJSON($(DOM).val());
    eval('var uploadedData = '+json+';');
    $(DOM).val('');

    //set the associated input to the image id
    $('#'+inputId).val(uploadedData['Image']['id']);
    $('#'+inputId).trigger('change');
    //alert('trigger change for: '+inputId);

    //create a url src value of the main image
    var src = '/thumb/'+uploadedData['Image']['id'];
    //check if the thumb requires sizes in the file name
    var sizeJson = cleanJSON(size);
    eval('size = '+sizeJson+';');
    var width = 0;
    var height = 0;
    var ignoreAspectRatio = false;
    if(size['width'] != null || size['height'] != null){
        src+= '_';

        if(size['width'] != null){
            src+= size['width'];
            width = size['width'];
        }
        src+= 'x';
        if(size['height'] != null){
            src+= size['height'];
            height = size['height'];
        }
        if(size['ignoreAspectRatio'] != null){
            src+= '-1';
            ignoreAspectRatio = true;
        }
    }

    if(updateBrowser){
        //update the selectable images in the file browser to include the new image
        refreshSelect(inputId,width,height,ignoreAspectRatio);
    }

    //get the file extension
    var fileNameParts = uploadedData['MediaFile']['file']['name'].split('.');
    src+= '.'+fileNameParts[1];

    // remove the height attribute of the img tag, as it will not match the newly selected image (it is only there to speed up the initial loading of the page, and will not be missed)
    $('#'+inputId).next('img').removeAttr('height');
    //set the src value
    $('#'+inputId).next('img').attr('src',src);

    //set the title and alt values for the img tag
    $('#'+inputId).next('img').attr('title',fileNameParts[0]);
    $('#'+inputId).next('img').attr('alt',fileNameParts[0]);
    return false;

}

function selectImage(DOM,id,thumbPath,inputId){
    // set the image browser to stay open once the image has been selected
    imageBrowser.keepOpen = true;
    //set the associated input to the image id
    $('#'+inputId).val(id);
    // trigger the onchange event in case there is any functionality set up for that listener
    $('#'+inputId).trigger('change');
    // remove the height attribute of the img tag, as it will not match the newly selected image (it is only there to speed up the initial loading of the page, and will not be missed)
    $('#'+inputId).next('img').removeAttr('height');
    //set the src of the img tag
    $('#'+inputId).next('img').attr('src',thumbPath);
    //set the title and alt values for the img tag
    $('#'+inputId).next('img').attr('title',$(DOM).children('img').attr('title'));
    $('#'+inputId).next('img').attr('alt',$(DOM).children('img').attr('alt'));

    // check if the thumb was created on the fly using the /thumb/ url path
    var pos = thumbPath.indexOf('/thumb/');
    if(pos == 0){
        //a thumbnail will now exist for the main image so update the onclick event for this image to point to the actual file
        //get the the thumb file name
        var parts = thumbPath.split('/');
        // create the path to newly created thumb
        var newThumbPath = '/sites/'+siteId+'/img/thumbs/'+parts[2];
        // update the click event, but not instantly, as this will cause problems in IE
        $(DOM).attr('onclick','');
        setTimeout("updateImageSelector('"+$(DOM).attr('id')+"','"+id+"','"+newThumbPath+"','"+inputId+"');",200);
    }
    return false;
}

function updateImageSelector(selectorId,id,newThumbPath,inputId){
    // update the onclick event for the specified element
    $('#'+selectorId).bind('click',
        function(){
            selectImage(this,id,newThumbPath,inputId);
        }
        );
    return false;
}

function refreshSelect(inputId,width,height,ignoreAspectRatio){
    var url = '/dc/images/browser/'+inputId+'/'+width+'/'+height;
    if(ignoreAspectRatio != null){
        url+= '/1';
    }
    var request = $.get(url,
        function(data){
            //alert(data);
            $('#FileSelectFor'+inputId).replaceWith(data);
        //close the connection to the server
        //request.setRequestHeader("Connection", "close");
        }
        );
    return false;
}

/*===============================================================


	GALLERY HELPER FUNCTIONS


==================================================================*/



/*===============================================================


	FORM HELPER FUNCTIONS


==================================================================*/

function inputDefaults(){

    $('input.fsInput[title]').each(function(){
        if($(this).val() == ''){
            $(this).addClass('fsFadedText');
            $(this).val($(this).attr('title'));
        }else if(($(this).val() == $(this).attr('title')) && !$(this).hasClass('fsFadedText')){
            $(this).addClass('fsFadedText');
        }
    });
    $('input.fsInput[title]').bind('focus',function(){
        if(($(this).val() == $(this).attr('title')) && $(this).hasClass('fsFadedText')){
            $(this).val('');
            $(this).removeClass('fsFadedText');
        }
    });
    $('input.fsInput[title]').bind('blur',function(){
        if($(this).val() == ''){
            $(this).addClass('fsFadedText');
            $(this).val($(this).attr('title'));
        }
    });
    $('input.fsInput').bind('focus',function(){
        $(this).addClass('fsFocus');
    });
    $('input.fsInput').bind('blur',function(){
        $(this).removeClass('fsFocus');
    });
    $('input.fsInput.fsInputPreview').bind('blur',function(){
        $(this).parents('div.row').children('span.fsColourPreview').css('background-color','#'+$(this).attr('value'));
    });
    return false;
}

//this function is called when a form is submitted using the JQuery form plugin, but before the data is sent to the server
//not used at the moment but useful for debugging
function showRequest(formData,jqForm,options){

    //DEBUG
    var formQueryString = $.param(formData);


    // jqForm is a jQuery object encapsulating the form element.  To access the
    // DOM element for the form do this:
    // var formElement = jqForm[0];

    // get the form id
    /*var formElement = jqForm[0];
	var formId = $(formElement).attr("id");
	// use the form id to see if the ajaxForms Object holds a destination element selector for the data returned by this form submission
	eval("var ajaxFormCheck = ajaxForms."+formId+";");
	if(ajaxFormCheck != undefined){
		if(ajaxFormCheck.returnTo != undefined){
			returnTo = ajaxFormCheck.returnTo;
			alert(returnTo);
		}
	}*/
    //alert("JQuery Form plugin will return data to: "+returnTo);

    //alert('ajaxForm is about to submit: \n\n' + formQueryString);

    //debug options
    /*for(key in options){
	alert(key+': '+options[key]);
}*/

    return true;

}


//handles tha data returned from the server after a form is submitted using the JQuery form plugin
function showResponse(data,statusText){
    //alert('response');
    //process returned data
    loadPageContent(data,false);
    //window.contentHandler.load(data);
    showFormLoader("finish");
    return false;
};

function saveAndPublish(formId,model){
    //set the published hidden field to 1
    $("#"+model+"Published").val(1);
    //submit the form
    submitForm(formId,true);
    return false;
}

function getParentFormId(selector){
    return $(selector).parents('form').attr('id');
}

function publish(formId,model){
    //add a hidden field to the form to signal the action
    $("#"+model+"Published").before('<input type="hidden" name="data['+model+'][publish]" value="1" />');
    //submit the form
    submitForm(formId,true);
    return false;
}

function retract(formId,model){
    //add a hidden field to the form to signal the action
    $("#"+model+"Published").before('<input type="hidden" name="data['+model+'][retract]" value="1" />');
    //submit the form
    submitForm(formId,true);
    return false;
}

function remove(formId){
    alert($(formId).parents('form').attr('action'));
    var urlParts = $(formId).parents('form').attr('action').split('/');
    alert('send to: /'+urlParts[1]+'/delete/'+urlParts[3]);
    window.location.href = '/'+urlParts[1]+'/delete/'+urlParts[3];
    return false;
}

function getNicEditorContents(){
    //any content in a nicEdit editor must be copied to it's relevant text area before submitting using javascript, or the data will not be sent to the server
    var editorInstanceCheck;
    var instances = 0;
    //loop thru textEditors array, telling nicEdit to copy the text editor contents to a textarea so it can be posted for each
    for(key in textEditors){
        //check the editor instance still exists in the window object before trying to access it, or this will cause an error!
        eval('if(window.'+textEditors[key]+'){ editorInstanceCheck = true;}else{ editorInstanceCheck = false;}');
        if(editorInstanceCheck){
            //debug
            //alert('get content for '+key+' = '+textEditors[key]);
            eval('instances = '+textEditors[key]+'.nicInstances.length;');
            //loop thru each editor held in this instance (this will only be 1, but best to check)
            for(var i=0;i<instances;i++){
                eval(textEditors[key]+'.nicInstances[i].saveContent();');
            }
        }
    }
    return false;
}


function returnKeySubmission(){

    $('input').live('keydown', function(e) {
        var characterCode; //literal character code will be stored in this variable

        if(e && e.which){ //if which property of event object is supported (NN4)
            e = e;
            characterCode = e.which; //character code is contained in NN4's which property
        }else{
            //alert('which property not supported');
            //e = event
            characterCode = e.keyCode; //character code is contained in IE's keyCode property
        }

        if(characterCode == 13){ //if generated character code is equal to ascii 13 (if enter key)
            // only proceed if the input does not have a class preventing auto submission
            if($(this).hasClass('doNotSubmitOnKeyPress') != true){
                //submit the form
                //alert($(this).attr('id'));
                submitForm($(this).parents('form').attr('id'),true);
            }
            return false;
        }else{
            return true;
        }
    });

    return false;
}


function addPoundSymbol(inputId){
    //alert(inputId);
    var data = $('#'+inputId).val();

    while(data.indexOf('&pound;') != -1){
        data = data.replace('&pound;','\u00A3');
    }
    //alert(data);
    $('#'+inputId).val(data);
    return false;
}

function showFormLoader(action){
    if(action == "start"){
        $("div#fsLoading").css("display","block");
        setTimeout(function() {
            $("div#fsLoading span").show()
        }, 5000);
    }else if(action == "finish"){
        $("div#fsLoading").css("display","none");
        $('html, body').animate({
            scrollTop: 0
        }, 1000);
        $("div#fsLoading span").hide();
    }
    return false;
}

function submitForm(id,getNicEditors){

    window.contentHandler.turnOnLoadingCursor();

    id = id.replace('#','');
    //check if any inputs contain the default title value
    //if they do, then clear them, or the default value will be posted!
    $('#'+id+' input.fsInput[title]').each(function(){
        if(($(this).val() == $(this).attr('title')) && $(this).hasClass('fsFadedText')){
            $(this).val('');
        }
    });

    //get contents of the nicEdit editors so they can be posted
    if(getNicEditors){
        getNicEditorContents();
    }

    $('#'+id+' input[type!=hidden], #'+id+' textarea').each(function(){
        //alert($(this).val());
        if($(this).attr('id') != 'MediaFileFile'){
            var value = $(this).val();
            // replace � (unicode = \u00A3) symbol with the HTML entity version before saving
            // use the unicode for the � symbol to find it, otherwise the javascript might not find it, and then it wont be replaced
            if(value.indexOf('\u00A3') != -1){
                // loop thru the value of the input to ensure multiple instances are replaced
                while(value.indexOf('\u00A3') != -1){
                    value = value.replace('\u00A3','&pound;');
                }
                $(this).val(value);
            }
        }
    });

    // decide how to submit the form by checking if the site is ajaxNavigation mode, and if the form has been setup to be submitted via ajax
    // check if this form exists in the ajaxForms Object
    eval('var ajaxFormCheck = ajaxForms.'+id+';');
    if(ajaxFormCheck != undefined){

        showFormLoader("start");

        // get the options Object for this form from the ajaxForms Object
        eval('var ajaxFormOptions = ajaxForms.'+id+'.options;');

        // add the current value of the form's action attribute to the retrieved options Object
        ajaxFormOptions.url = '\''+eval("'/dc'+$('#'+id).attr('action');")+'\'';

        //update the refereUrl variable in case it is being posted with form data
        if(id != 'UserLoginMainscreen'){
            setRefererUrl();
        }

        //generate  string containing the form plugin options
        var optionsString = '{type: "POST",';
        var delimeter = '';
        // loop thru the options Object retrieved from the ajaxForms Object for this form, adding each to the string
        for(key in ajaxFormOptions){
            eval('optionsString+= delimeter+key+\': \'+ajaxFormOptions.'+key+';');
            delimeter = ', ';
        }
        optionsString+= '}';

        // submit the form using the JQuery Form Plugin ajaxSubmit function, using the optionsString variable that has just been defined
        eval("$('#"+id+"').ajaxSubmit("+optionsString+");");

    }else{
        // submit the form normally
        $('form#'+id).submit();
    }

    return false;
}

/*===============================================================


	DEBUGGING FUNCTIONS


==================================================================*/


function debug(data){
    var debugData = '';
    var arraySize = 0;
    for(key in data){
        if(arraySize == 0){
            debugData+= '**referer url**\n'+refererUrl+'\n\n';
        }
        //alert('**'+key+'**\n'+data[key]);
        debugData+= '**'+key+'**\n'+data[key]+'\n\n';
        arraySize++;
    }
    if(arraySize > 0){
        alert(debugData);
    }else{
        alert('The returned JSON could not be decoded. Check the returned data in its raw state\n\n(Set debugRawAjaxResponse = true)');
    }
}

/*===============================================================


	NAVIGATION FUNCTIONS


==================================================================*/

function sendToHomePage(){

    if(historyPluginInitialised){
        redirectToHomePage();
    }else{
        onLoadSendToHomePage = true;
    }
    return false;
}

function redirectToHomePage(){
    var url = window.location.href;
    url = url.replace(window.location.protocol+'//'+window.location.hostname,'');
    url = url.replace('/#','');

    if(url == '/'){

        //loadPage('/home');
        window.navigation.requestHandler('/home');
    }
    return false;
}

function setNavigation(value){
    siteParams.ajaxNavigation = value;
    return;
}

function loadPage(url){
    // If the wizard is running, then load the correct wizard page
    //	if(wizard.running==true){
    //		alert('wizard running, load the correct page : '+url);
    //		help(url);
    //	}
    //set destination for returned content
    returnTo = defaultContentArea;

    if(url.indexOf('/') != 0){
        url = '/'+url;
    }

    //$('#fsBody').prepend(window.location.pathname);
    /*if(window.location.pathname == '/#'+url){
		ajaxRequest(url,returnTo);
	}else{*/

    $.historyLoad(url,returnTo);
    //}
    return;
}

function activateAjaxNavigation(){

    // Initialize JQuery Ajax History plugin.
    // set it to call the ajaxRequest() function
    $.historyInit(ajaxRequest);
    historyPluginInitialised = true;

    //set a tags to make ajax calls rather than redirect the browser
    setAjaxNavEvents();

    //prefix a tag href values with # to trigger ajax navigation
    modifyLinkUrls();

    if(onLoadSendToHomePage){
        redirectToHomePage();
        onLoadSendToHomePage = false;
    }
    return false;
}

function blockedNavigationAlert(){
    alert('Normal navigation is disabled until the site setup is complete');
}

//sets the onClick action of all the links on the page
function setAjaxNavEvents(){
    //alert('run events');
    if(wizard.running || wizard.load){
        //alert('restrict');
        $('a:not(div.component a, a#sbTemplate, form#TemplateAndThemeSelect a, form#SiteEdit a, div#fsHelp a, a.logout, a#sbEditmode, div.wLogin a, div.fsAlert a, div#ui-datepicker-div a, div.wizardIntro a)').die('click');
        $('a:not(div.component a, a#sbTemplate, form#TemplateAndThemeSelect a, form#SiteEdit a, div#fsHelp a, a.logout, a#sbEditmode, div.wLogin a, div.fsAlert a, div#ui-datepicker-div a, div.wizardIntro a)').unbind('click');

        $('a:not(div.component a, a#sbTemplate, form#TemplateAndThemeSelect a, form#SiteEdit a, div#fsHelp a, a.logout, a#sbEditmode, div.wLogin a, div.fsAlert a, div#ui-datepicker-div a, div.wizardIntro a)').live('click',function(){
            /*$('#fsBody a:not(a.wizardAction,a.tip,a.fsBtn,a.sbBtn,a.styledBtn,a.btn,a.logout,.wizardonly a,.paging a,div.component a,.success a)').unbind('click');
		$('#fsBody a:not(a.wizardAction,a.tip,a.fsBtn,a.sbBtn,a.styledBtn,a.btn,a.logout,.wizardonly a,.paging a,div.component a,.success a)').live('click',function(){*/
            blockedNavigationAlert();
            return false;
        });

    }else{

}

}

//prepends the href value of an a tag with /#
//this stops the page being redirected, and triggers the ajax navigation
function modifyLinkUrls(){

    //select all a tags (except for tooltips) [that have a href attribute] in the fsBody div
    $('#fsBody a:not(a.tip)[href]').each(function(){

        //get the href url and set to ajaxQueryString
        var ajaxQueryString = $(this).attr('href');

        //check the href is defined, as this will cause an error
        if(ajaxQueryString != undefined){

            if(ajaxQueryString.indexOf('://') == -1 && ajaxQueryString.indexOf('www.') == -1 && ajaxQueryString.indexOf(document.domain) == -1){
                //alert(ajaxQueryString);
                //don't modify the ajaxQueryString if it already begins with #
                //or the ajaxQueryString will start with /#/# which is wrong
                if(ajaxQueryString.charAt(1) != '#'){

                    //prepend the ajaxQueryString with # so that the jquery history plugin will record it
                    ajaxQueryString = '/#'+ajaxQueryString;

                    //set the href value
                    $(this).attr('href',ajaxQueryString);

                //DEBUG
                //alert('set href to "'+ajaxQueryString+'"');

                }

            }

        }

    });
    return;

}

var systemRequests = new Array();

//makes an ajax call using the href attribute of an a tag
function ajaxRequest(ajaxQueryString,destination,replaceDestination,callbackFunction){
    //check if a request needs to be made to the server
    if(makeAjaxRequest){

        //check the query string is set
        if(ajaxQueryString){

            window.contentHandler.turnOnLoadingCursor();

            /*alert('check for changes in ajax request');
			var requestContinue = false;
			if(formInputEditedFlag){

				formInputEditedFlag = false;
				if(confirm(formInputEditedPrompt)){
					alert('continue then');
					requestContinue = true;
				}

			}else{
				alert('no changes');
				requestContinue = true;
			}
			alert(requestContinue);
			if(requestContinue){*/

            if(ajaxQueryString.indexOf('/') != 0){
                ajaxQueryString = '/'+ajaxQueryString;
            }

            //set the full ajax request url
            var url = 'http://'+document.domain+'/dc'+ajaxQueryString;

            //DEBUG
            //alert('make ajax request to: '+url+', refererUrl = '+refererUrl);

            //show loading message
            //$(returnTo).html(loading);

            if(destination == undefined){
                destination = returnTo;
            }
            //alert('ajax request: '+ajaxQueryString+'. Returning to: '+destination)

            //alert(replaceSelector);
            if(replaceDestination == undefined){
                replaceDestination = false;
            }

            var ajaxOptions = {
                _refererUrl: refererUrl, 
                _returnTo: destination, 
                _loggedInStatus: loggedInStatus
            };
            //alert(ajaxOptions._loggedInStatus);

            //make ajax call to retreive the JSON data
            var request = $.post(url,ajaxOptions,function(data){

                //process returned data
                if(callbackFunction != undefined){
                    loadPageContent(data,replaceDestination,callbackFunction);
                }else{
                    loadPageContent(data,replaceDestination);
                }
            //close the connection to the server
            //request.setRequestHeader("Connection", "close");

            });

        //}

        }

    }else{

        //reset makeAjaxRequest var, so following requests will contact the server
        makeAjaxRequest = true;

    }
    return;
}

function setRefererUrl(){
    refererUrl = document.location.href.replace('#/','');
    refererUrl = refererUrl.replace('http://'+document.domain+'/','');
//alert('refererUrl = '+refererUrl);
}

/*===============================================================


	SITE BAR FUNCTIONS


==================================================================*/

function loadStats(url){
    $('#sbContent div.fsStatsGraph').html('Loading...');
    $('#sbContent div.fsStatsLegend').empty();
    //setRefererUrl();
    //returnTo = '#sbSitebarContent';
    //siteBarContent = true;
    //alert('nav a tag: show sb content: '+$(this).attr('href')+', in '+returnTo);
    //ajaxRequest(url,'#sbSitebarContent');

    window.siteBar.requestContent(url);
    return false;
}

function openShopSettings(){
    /*$('#sbNavigation a.sbMainbutton:not(#sbEditmode,#sbWizard)').removeClass('active');

	setRefererUrl();
	//returnTo = '#sbSitebarContent';
	siteBarContent = true;
//alert('nav a tag: show sb content: '+$(this).attr('href')+', in '+returnTo);
	ajaxRequest('/shops/settings','#sbSitebarContent');*/
    window.siteBar.loadSection('/sites/edit','/shops/settings');
    //$('#sbSettings').addClass('active');
    return false;
}

function deleteDomain(id){
    if(confirm('Are you sure you want to delete this domain?')){
        //ajaxRequest('/domains/delete/'+id,'#sbSitebarContent');
        window.siteBar.requestContent('/domains/delete/'+id);
    }
    return false;
}

//sitebar links
function activateSiteBarNavigation(){

}

function previewUserProfile(id,tab){

    var tabIdArray = new Array('UserProfile','UserActivity','UserOrders','UserDownloads');

    if($('#UserPreview div.sbTabs').attr('id') == 'UserPreviewTabs'+id){
        $('#UserPreview div.sbTabs span.sbTab').removeClass('active');
        $('#'+tab+'PreviewTab').addClass('active');

        for(key in tabIdArray){
            if(tabIdArray[key] == tab){
                $('#'+tabIdArray[key]+'Preview').toggleClass('fsHidden',false);
            }else{
                $('#'+tabIdArray[key]+'Preview').toggleClass('fsHidden',true);
            }
        }

    }else{
        ajaxRequest('/user_profiles/preview/'+id+'/'+tab,'#UserPreview');
    }
    return false;
}

function checkVatCountry(selectElement){
    var hideVat = true;
    for(key in europeanCountryCodes){
        if(europeanCountryCodes[key] == $(selectElement).val()){
            $('#CompanyVatNumberDiv').show();
            $('#CompanyIsVatRegistered').val(1);
            hideVat = false;
        }
    }
    if(hideVat){
        $('#CompanyVatNumberDiv').hide();
        $('#CompanyIsVatRegistered').val(0);
    }
    return false;
}

function toggleCompanyDataForm(){
    $('#SiteCompanySettings').toggle();
    if($('#CompanyVatNumber').length == 1){
        $('#CompanyVatNumber').attr('name','data[User][vat_number]');
        $('#CompanyVatNumber').attr('id','UserVatNumber');
    }else{
        $('#UserVatNumber').attr('name','data[Company][vat_number]');
        $('#UserVatNumber').attr('id','CompanyVatNumber');
    }
    return false;
}

/*===============================================================


	TEMPLATE & THEMES HELPER FUNCTIONS


==================================================================*/

//$('#sbSitebarContent #sbTemplateSelect a').live('click',function(){
function selectTemplate(){

    window.contentHandler.turnOnLoadingCursor();

    $('#sbTemplateSelect a.selected').removeClass('selected');
    $(this).addClass('selected')
    //get the requested template id
    var templateId = $(this).attr('id');
    //set the hidden input so the template change can be saved
    $('#SiteTemplateId').val(templateId);

    // modify the template image text, or hide it
    /*if($('#TemplateImageInfo-'+templateId).length > 0){
			$('#sbSitebarContent table tr td.sbTemplateImage p').html($('#TemplateImageInfo-'+templateId).html());
			$('#sbSitebarContent table tr td.sbTemplateImage').toggleClass('fsHidden',false);
		}else{
			$('#sbSitebarContent table tr td.sbTemplateImage p').empty();
			$('#sbSitebarContent table tr td.sbTemplateImage').toggleClass('fsHidden',true);
		}*/

    var templateThemeGroupId = $(this).attr('rel');
    // hide all theme groups, except the one related to the selected template
    if($('#'+templateThemeGroupId).hasClass('fsHidden')){

        $('#sbThemeSelect div:not(.scroll,#'+templateThemeGroupId+')').toggleClass('fsHidden',true);
        $('#'+templateThemeGroupId).removeClass('fsHidden');

        // remove the selected class from the previously selected Theme and apply it to the default Theme for the newly selected Template
        $('#sbThemeSelect div a.selected').removeClass('selected');
        var themeId = $('#'+templateThemeGroupId+' a.default').attr('id');
        $('#'+themeId).addClass('selected');
        //set the hidden input so the theme change can be saved
        $('#SiteThemeId').val(themeId);

    }else{

        var themeId = $('#SiteThemeId').val();

    }

    reloadTemplate(templateId,themeId);

    return false;

}




var themeDummy = {
    init: function(){
        // Appends "dummy-element" div to body:
        $('<div id="themeDummyElement" style="display:none;" />').appendTo('#fsBody');
    },
    check: function(callback) {

        // Checks if computed with equals that which is defined in the StyleSheets (2px):
        if ($('#themeDummyElement').width()==2){
            callback();
            $('#themeDummyElement').remove();
        }else{
            // If it has not loaded yet then simple re-initiate this
            // function every 200 milliseconds until it had loaded:
            setTimeout(function(){
                themeDummy.check(callback)
                }, 200);
        }
    }
}



//$('#sbSitebarContent #sbThemeSelect a').live('click',function(){
function selectTheme(){

    window.contentHandler.turnOnLoadingCursor();

    // deselect old, select new one
    $('#sbThemeSelect div a.selected').removeClass('selected');
    $(this).addClass('selected');

    //get the requested theme id
    var themeId = $(this).attr('id');
    //set the hidden input so the theme change can be saved
    $('#SiteThemeId').val(themeId);

    var templateId = $('#SiteTemplateId').val();

    reloadTemplate(templateId,themeId);

    /*//initialise the dummy test
		themeDummy.init();

		//IE6 bug fix
		//$('body').css({height:'100%'});

		//fade in the overlay
		$('#overlay').fadeIn(300,function(){

			//switch the theme stylesheet
			$('link#themeStyles').attr('href','/css/theme/'+themeId+'.css');

			// send request to server to update the preview session variable
			$.get('http://'+window.location.hostname+'/dc/themes/updatePreviewSession/'+themeId);

			//check the stylesheet has been loaded
			themeDummy.check(function(){

				$('div#sbThemeSave').show();

				$('#overlay').fadeOut(250,function(){window.contentHandler.turnOffLoadingCursor();});

			});
		});*/


    return false;

}

var templateDummy = {
    init: function(){
        // Appends "dummy-element" div to body:
        $('<div id="templateDummyElement" style="display:none;" />').appendTo('#fsBody');
    },
    check: function(callback) {

        // Checks if computed with equals that which is defined in the StyleSheets (2px):
        if ($('#templateDummyElement').width()==2){
            callback();
        }else{
            // If it has not loaded yet then simple re-initiate this
            // function every 200 milliseconds until it had loaded:
            setTimeout(function(){
                templateDummy.check(callback)
                }, 200);
        }
    }
}

function setTemplateBGImage(imagePath){
    if(imagePath == 'blank'){
        $('#fsBody').removeAttr('style');
    }else{
        $('#fsBody').css('background-image','url('+imagePath+')');
    }
    return false;
}

function updateTemplateBGImage(input){
    var imageId = $('#SiteImageId').val();
    var noImage = false;
    var reload = true;
    if($(input).attr('id') == 'SiteNoImage'){
        if($(input).attr('checked') == true){
            noImage = true;
        }else if(imageId == ''){
            reload = false;
        }
    }else{
        $('#SiteNoImage').attr('checked',false);
    }
    if(imageId == ''){
        noImage = true;
    }
    if(noImage){
        imageId = 'blank';
    }

    //alert(imageId);
    if(reload){
        window.contentHandler.turnOnLoadingCursor();
        reloadTemplate(null,imageId);
    }
    return false;
}

function reloadTemplate(templateId,themeId){

    //set the referer url
    setRefererUrl();

    if(refererUrl == ''){
        refererUrl = 'home';
    }
    //set url for ajax request
    var url = 'http://'+document.domain+'/'+refererUrl;

    //initialise the dummy test
    if(themeId != null){
        themeDummy.init();
    }else{
        templateDummy.init();
    }


    //IE6 bug fix
    //$('body').css({height:'100%'});

    //fade in the overlay div, when the animation is complete, get the new template
    $('#overlay').fadeIn(300,function(){

        var ajaxOptions = {
            //pass the current url
            _refererUrl: refererUrl,
            _returnTo: '#fsBody',
            _loggedInStatus: loggedInStatus
        }

        if(templateId != null){
            ajaxOptions.previewTemplateId = templateId;
        }else{
        //ajaxOptions.previewTemplateId = $('#SiteTemplateId').val();
        }

        if(themeId != null){
            ajaxOptions.previewThemeId = themeId;
        }else{
        //ajaxOptions.previewThemeId = $('#SiteThemeId').val();
        }

        //alert('template = '+ajaxOptions.previewTemplateId);
        var date = new Date();
        if(themeId != null){
            // switch the theme stylesheet
            // append url of stylesheet with the UTC date in milliseconds to stop the stylesheet being cached

            $('link#themeStyles').attr('href','/css/theme.css?id='+themeId+'&t='+date.getTime());
        }

        /*if(imageId != null){
		ajaxOptions.previewImageId = imageId;
	}else{
		if($('#SiteNoImage').attr('checked') == true){
			ajaxOptions.previewImageId = 'blank';
		}else{
			ajaxOptions.previewImageId = $('#SiteImageId').val();
		}
	}*/
        //alert('image = '+ajaxOptions.previewImageId);
        if(templateId != null){
            $('link#templateStyles').attr('href','/css/template.css?id='+templateId+'&t='+date.getTime());
        }
        //ajax request
        var request = $.post(url,ajaxOptions,function(data){

            //switch stylesheet
            //$('link#themeStyles').attr('href','/css/theme/'+themeId+'.css');


            if(themeId != null){
                //check the stylesheet has been loaded
                themeDummy.check(function(){
                    loadPageContent(data,false);
                    //fade out the overlay div
                    $('#overlay').fadeOut(250);
                });
            }else{

                //check the stylesheet has been loaded
                templateDummy.check(function(){

                    //set the destination of the returned HTML
                    //returnTo = '#fsBody';
                    //process returned data
                    loadPageContent(data,false);
                    //close the connection to the server
                    //request.setRequestHeader("Connection", "close");

                    //display the controls for saving the template change
                    //$('div#sbTemplateSave').show();

                    //fade out the overlay div
                    $('#overlay').fadeOut(250);

                });
            }
        });
    });
    return false;
}


/*===============================================================


	TOOL TIP FUNCTIONS


==================================================================*/

function showhideBubble(e) {

    var clicked = $(e.target); // get the element clicked

    if(clicked.is('.fsOpenBubble') || clicked.parents().is('.fsOpenBubble')) {
        e.stopPropagation();
    }else{
        $('.fsBubble').fadeOut(300);
        $(document).unbind('click',showhideBubble);
    }
}

$('.fsOpenBubble').live('click',function(){

    // Check where the bubble should be rendered - the left or the right

    var bodywidth = $('body').outerWidth();
    var tooltipx = $(this).offset();
    var tooltipwidth = 300;
    var tooltextwidth = $(this).outerWidth();
    var safezone = bodywidth - tooltipwidth;
    var actualtipx = tooltextwidth + tooltipx.left;

    // Flips the tooltip around if it is too close to the edge of the page
    //alert('act = '+actualtipx+' safe = '+safezone);
    if(actualtipx > safezone){
        //var arrowpos = 'pos-r';
        $('.fsBubble',this).addClass('fsArrowRight');
    }

    $('div.fsBubble',this).show();

    //$('div.fsBubble').fadeOut(300);

    $(document).bind('click',showhideBubble);
});


/*===============================================================


	CONTENT LOADING FUNCTIONS


==================================================================*/

//extract data from a JSON object then load it into the page
function loadPageContent(json,replaceContent,callbackFunction){

    //DEBUG
    if(debugRawAjaxResponse){
        //$(returnTo).html(json);
        alert('**Returned JSON object**\n\n'+json);
    }
    //alert('siteBarContent = '+siteBarContent+', returnTo = '+returnTo);
    //$('#fsca1').html(json);

    // remove any debugging data generated by cake from the ajax response
    // before the JSON string
    if(json.indexOf('{') != 0){
        json = json.slice(json.indexOf('{'));
    //alert('new data = '+json);
    }
    // time data after the JSON data
    if(json.indexOf('}<!--') != -1){
        json = json.split('}<!--',1);
        json = json[0]+'}';
    }



    //convert JSON object into an array
    json = cleanJSON(json);
    eval('var data = '+json);

    /*if(debugMode){
		alert(data['html']);
	}*/

    //alert(data['sessionExpired']);
    /*	if(data['sessionExpired'] != null){
		loggedInStatus = 0;
		$('#fsSitebarPos').remove();
		$('#fsSitebar').remove();
		data['reloadMediaPlayer'] = true;
		data['reloadUserProfileWidget'] = true;
	}*/

    // if the wizard is active then ensure the wizard object is started
    //	alert(data['userSessionActive']);
    if(data['userSessionActive'] == 1){
        //alert('logged in');
        if(data['siteBar'] != null){
            window.siteBar.load(data['siteBar']);
        }/*else{
			alert('logged in but bo sitebar html');
		}*/
    }else{
        //alert('logged out');
        window.sideBar.close();
        window.siteBar.remove();
    }

    //load the site bar if needed
    /*if(data['siteBar'] != null){
		if(siteBar.cancelLoad != true && $('#fsSitebarPos').length == 0){
			$('link[rel=stylesheet]:first').after('<link rel="stylesheet" type="text/css" href="/css/admin.css" />');
	//alert('load site bar with: '+data['siteBar']);
			$('body').prepend(data['siteBar']);
		}
		data['siteBar'] = null;
		//activateSiteBarNavigation();
	}*/

    //check to see if the address bar url should be changed
    if(data['set_url']){
        if(data['url'] != undefined){
            window.navigation.setAddressBarUrl(data['url']);
        }
    }

    if(data['replaceContent'] != null){
        if(data['replaceContent'] == 1){
            replaceContent = true;
        }else{
            replaceContent = false;
        }
    }

    //alert('load returned HTML into: '+data['returnTo']);
    // make the sure destination element (in the form of a JQuery selector) for returned HTML is set
    var destination = returnTo;
    if(data['returnTo'] != null){
        destination = data['returnTo'];
    }else{
        if(destination == undefined){
            destination = defaultContentArea;
        }
    }
    // load the HTML
    if(replaceContent){
        var target = $(destination).replaceWith(data['html']);
    }else{
        //alert('send data to: '+destination);
        var target = $(destination).html(data['html']);
    }

    $(document).trigger('ctrl:contentDidLoad', [$(target)]);

    // reset the flag for edited data that has not been saved if the HTML was loaded in the main content area
    if(destination == defaultContentArea){
        formInputEditedFlag = false;
    }

    //setAjaxNavEvents();

    //display the returned HTML
    //$(returnTo).html(data['html']);

    //set the page title
    if(data['pageTitle'] != false){
        document.title = data['pageTitle'];
    }

    //set the page description
    if(data['pageDescription'] != '' && data['returnTo'] == this.defaultDestinationSelector){
        $('meta[name=description]').attr("content",data['pageDescription']);
        window.navigation.setPageDescription(data['pageDescription']);
    }
    // set the page short url
    if(data['shortUrl'] != null && data['returnTo'] == this.defaultDestinationSelector){
        window.navigation.setPageShortUrl(data['shortUrl']);
    }

    if(siteParams.ajaxNavigation != 1 && historyPluginInitialised == true){
        $('#fsBody a:not(a.tip,a.fsBtn,a.sbBtn,a.styledBtn,a.btn,a.logout)').unbind('click');
    }

    //set any newly loaded links to use ajax
    if(siteParams.ajaxNavigation == 1 && historyPluginInitialised == false){
    //alert('initialise ajax nav');
    //activateAjaxNavigation();
    }else if(siteParams.ajaxNavigation){
        modifyLinkUrls();
    }
    //activate any newly loaded tool tips
    //	activateToolTips();

    inputDefaults();

    //if the content is for the site bar, then display the content area if needed
    //alert(siteBarContent+', '+returnTo);
    if(siteBarContent){
        //		$('#sbSitebarContent').slideDown(1000,function(){adjustTemplate('pushbody');});
        $('#sbSitebarContent').slideDown();
        adjustTemplate('pushbody');
    }

    //reset destination element and site bar flag
    returnTo = defaultContentArea;
    //alert('HTML loaded. set returnTo to: '+returnTo);
    siteBarContent = false;

    if(data['reloadPage'] != null){
        //alert('reload page (old)');
        //setRefererUrl();
        //ajaxRequest('/'+refererUrl,defaultContentArea);
        window.navigation.requestPage(window.navigation.getHashFromUrl(window.location.href));
    }

    if(data['reloadWidgets'] != null){
        window.widgets.reload();
    }

    if(data['reloadBasket'] != null){
        window.widget.reloadBasket();
    }

    if(data['reloadMediaPlayer'] != null){
        window.mediaPlayer.reloadPlayer(window.mediaPlayer.getCurrentlyPlaying(),1);
    }

    if(data['reloadUserProfileWidget'] != null){
        window.widgets.reloadUserProfile();
    }

    if(data['reloadEventsWidget'] != null){
        window.widgets.reloadEvents();
    }

    if(data['reloadNewsWidget'] != null){
        window.widgets.reloadNews();
    }

    if(data['closeOverlayWindow'] != null){
        window.overlayWindow.hide();
    }

    if(data['facebookConnected'] != null){
        window.facebook.hideAccountConnect();
    }

    if(data['updateEditMode'] != null){
        window.editMode.updateStatus(false);
    }

    if(data['refreshSiteImageOverview'] != null){
        window.siteBar.refreshSiteImageOverview();
    }

    // if the wizard is active then ensure the wizard object is started
    if(data['wizardActive'] != null){
        window.wizard.check();
    }else{
        window.wizard.close();
    }

    if(window.reloadTemplateAfterSave){
        window.reloadTemplateAfterSave = false;
        window.reloadTemplate($('#SiteTemplateId').val(),$('#SiteThemeId').val());
    }


    if(callbackFunction != undefined){
        //if(typeof(callbackFunction) == 'function'){
        eval(callbackFunction+'();');
    //}
    }

    window.contentHandler.turnOffLoadingCursor();

    return false;
}

function restrictedContent(){
    $('div.restricted a').attr('id','sbClose');
    $('div.restricted a').show();
    window.widgets.reloadUserProfile();
    return false;
}

// removable plugin
(function($){
    $.fn.ctrlRemovable = function(options) {
        var settings = {
            removableIconClass: 'ctrlIcon icoCross',
            afterRemove: null
        };
        $.extend(settings, options);

        var self = this;

        this.bindHandlers = function() {
            // select all the child elements within the set
            this.children().each(function(){
                // add the icon class to the element, then bind click handler to the "remove" element withn it
                $(this).find('.jsRemove').addClass(settings.removableIconClass).bind('click', self.remove);
            });
        }

        this.remove = function(event) {
            
            var itemToRemove = self.children().has(this);

            $(self).trigger('aboutToRemove.removable.ctrl', [itemToRemove, self]);
            
            // remove the child element of the parent (self) that contains the element that was clicked
            self.children().has(this).remove();
            // select all the child elements within the sortable and update each one
            self.children().each(function() {
                // update the position number
                $(this).find('.position').html(self.children().index(this) + 1);
                // store the child element in a variable so it can reference inside the next loop
                var child = this;
                // initialise a variable to store each name attribute that requires updating
                var name;
                // select all the inputs within the child element and update the indexes in the name attribute for each one
                $(this).find('input').each(function() {
                    // get the name attribute of the input
                    name = $(this).attr('name');
                    if (name != null) {
                        // replace the numeric index and then overwrite the name attribute
                        $(this).attr('name', name.replace(/\[[0-9]+\]/,'[' + self.children().index(child) + ']'));
                    }
                });
            });

            $(self).trigger('removed.removable.ctrl', [itemToRemove, self]);
        }
        
        if(editMode.isOn) {
            this.each(function() {
                self.bindHandlers();

                if (settings.afterRemove != null) {
                    $(self).bind('removed.removable.ctrl', settings.afterRemove);
                }
            });
        }
    }
})(jQuery);

// sortable plugin
(function($){
    $.fn.ctrlSortable = function(options) {
        var settings = {
            url: null,
            sortableIconClass: 'fsIcon icoMove'
        }
        $.extend(settings, options);

        var self = this;

        this.displayIcons = function() {
            this.children().each(function(){
                $(this).children().first().addClass(settings.sortableIconClass);
            });
        }

        this.bind('sortupdate', function(event, ui) {
            //console.log('parent id: ' + this.id);
            //console.log('item id: ' + ui.item[0].id);

            var index = $(this).children().index(ui.item) + 1;
            
            // if a url has been specified, the post the data to it
            if (settings.url != null) {
                $.ajax({
                    type: 'POST',
                    url: settings.url,
                    data: {
                        parentId: this.id,
                        childId: ui.item[0].id,
                        newPosition: index
                    }
                });
            }

            // select all the child elements within the sortable and update each one
            $(this).children().each(function() {
                // update the position number
                $(this).find('.position').html(self.children().index(this) + 1);
                // store the child element in a variable so it can reference inside the next loop
                var child = this;
                // initialise a variable to store each name attribute that requires updating
                var name;
                // select all the inputs within the child element and update the indexes in the name attribute for each one
                $(this).find('input').each(function() {
                    // get the name attribute of the input
                    name = $(this).attr('name');
                    if (name != null) {
                        // replace the numeric index and then overwrite the name attribute
                        $(this).attr('name', name.replace(/\[[0-9]+\]/,'[' + self.children().index(child) + ']'));
                    }
                });
            });
        });

        this.sortable({
            opacity: 1,
            axis: 'y',
            disabled: !editMode.isOn,
            placeholder: 'ctrlSortablePlaceholder'
        });

        if (this.length == 1) {
            $(document).bind('ctrl:editModeDidChange', function() {
                self.sortable('option', 'disabled', !editMode.isOn);
                self.displayIcons();
            });

            if(editMode.isOn) {
                this.displayIcons();
            }
        }
    }
})(jQuery);

// media list plugin
(function($){
    $.fn.ctrlMediaList = function(options) {
        var settings = {
            mediaType: 'Track',
            addButtonSelector: null,
            removeButtonSelector: null,
            placeHolderSelector: '.mediaItemPlaceholder',
            placeHolderClass: 'ctrl-mediaList-placeHolder',
            itemClass: 'ctrl-mediaList-item',
            itemsAdded: null,
            sortableOptions: {},
            removableOptions: {}
        };
        // merge defaults with any custome settings
        if (options) {
            $.extend(settings, options);
        }

        var self = this;

        this.openMediaBrowser = function() {
            // open the media browser
            window.mediaBrowser.load('Track');
            // add listeners for when the media browser is closed by
            // confirming a selection;
            $(document).bind('selectionConfirmed.mediaBrowser.ctrl', this.addSelectedMedia);
            // cancelling the selection.
            $(document).bind('selectionCancelled.mediaBrowser.ctrl', this.unbindMediaBrowserEvents);
        }

        this.unbindMediaBrowserEvents = function() {
            $(document).unbind('selectionConfirmed.mediaBrowser.ctrl', this.addSelectedMedia);
            $(document).unbind('selectionCancelled.mediaBrowser.ctrl', this.unbindMediaBrowserEvents);
        }

        this.addSelectedMedia = function(event, media) {

            // unbind the media browser events
            self.unbindMediaBrowserEvents();

            var newItem;
            var name;

            // loop thru media object, add each item to the media list
            for (i in media[settings.mediaType]) {
                // output media item to console
                //console.log(media[settings.mediaType][i]);
                // get the media list placeholder element and clone it. this will provide a template for the new item
                newItem = self.find('.' + settings.placeHolderClass).clone();
                // set the id attribute of the new item
                newItem.attr('id', media[settings.mediaType][i].id);
                // set the position within the new item
                newItem.find('.position').html(self.children(':not(.' + settings.placeHolderClass + ')').length + 1);
                // set the title within the new item
                newItem.find('.title').html(media[settings.mediaType][i].title);
                // set the values of the inputs within the new item element
                // id
                newItem.find('input[name$="id]"]').val(media[settings.mediaType][i].id);
                // has_file
                if (settings.mediaType == 'Track') {
                    newItem.find('input[name$="[has_file]"]').val(media[settings.mediaType][i].hasFile);
                    // remove the file icon that is not needed
                    if (media[settings.mediaType][i].hasFile == 1) {
                        // remove cross
                        newItem.find('span.icoCross').remove();
                    } else {
                        // remove tick
                        newItem.find('span.icoTick').remove();
                    }
                }
                
                // select all the inputs within the new item and update the indexes in the name attribute for each one
                newItem.find('input').each(function() {
                    // get the name attribute of the input
                    name = $(this).attr('name');
                    if (name != null) {
                        // replace the numeric index and then overwrite the name attribute
                        $(this).attr('name', name.replace(':index',self.children(':not(.' + settings.placeHolderClass + ')').length));
                    }
                });

                // add the new item element to the media list, and display it
                newItem.insertBefore(self.find('.' + settings.placeHolderClass)).removeClass(settings.placeHolderClass).show();
            }

            // re-apply the removable plugin so the functionality is added to the new items
            self.ctrlRemovable();

            $(self).trigger('itemsAdded.mediaList.ctrl', [media, self]);
        }

        // bind handler to add button
        this.each(function() {
            // add the item class to all child elements in the media list
            $(self).children().addClass(settings.itemClass);
            // add the place holder class to the place holder element
            $(self).find(settings.placeHolderSelector).addClass(settings.placeHolderClass);
            //
            if (settings.addButtonSelector != null) {
                $(settings.addButtonSelector).bind('click', function() {
                    self.openMediaBrowser();
                });
            }

            if (settings.itemsAdded != null) {
                $(self).bind('itemsAdded.mediaList.ctrl', settings.itemsAdded);
            }
        });

        // make the media list items sortable
        self.ctrlSortable(settings.sortableOptions);
        // make the media list items removable
        self.ctrlRemovable(settings.removableOptions);
    }
})(jQuery);

(function($) {
    $.fn.ctrlFileUpload = function(options) {

        var settings = {
            url: $(this).attr('action'),
            dataType: 'json',
            resetForm: true,
            submitButtonSelector: null,
            validation: [
                {
                    name: 'data[MediaFile][file]',
                    rule: ['notEmpty', 'fileType']
                }
            ],
            formValidationPassed: null,
            formValidationFailed: null,
            beforeSubmit: null,
            afterSubmit: null,
            onFinish: null,
            onError: null
        };

        $(this).each(function() {

            // check this is a form tag
            if (this.tagName.toLowerCase() == 'form') {

                var currentUploadId = null;

                var self = this;

                this.beforeSubmitHandler = function(arr, form, options) {
                    
                    // unbind the submit button of the form to prevent multiple submissions
                    $(self).find(settings.submitButtonSelector).unbind('click');

                    if (options.validation.length > 0) {
                        // bind handler for failing validation
                        if (settings.formValidationFailed != null) {
                            $(document).bind('failed.' + form.attr('id') + '.formValidation.ctrl', settings.formValidationFailed);
                        }
                        // bind handler for passing validation
                        if (settings.formValidationPassed != null) {
                            $(document).bind('passed.' + form.attr('id') + '.formValidation.ctrl', settings.formValidationPassed);
                        }

                        if (window.form.validate(arr, form, options)) {
                            // reset the upload identifier value in the upload form
                            var uploadId = '';
                            for (i=0; i<12; i++) {
                                uploadId+= Math.floor(Math.random()*11);
                            }
                            $('#' + form.attr('id')).find('input[name="UPLOAD_IDENTIFIER"]').val(uploadId);

                            self.setCurrentUploadId(uploadId);

                            // trigger the uploadAboutToStart event, passing the upload identifier and the jquery wrapped form
                            $(self).trigger('aboutToStart.fileUpload.ctrl', [uploadId, form]);

                            // bind the file input
                            self.bindSubmitButtonHandler();

                            setTimeout(self.triggerHasStarted, 1000);

                            return true;
                        } else {
                            self.bindSubmitButtonHandler();
                            
                            return false;
                        }
                    }

                    return true;
                }

                this.successHandler = function(response, statusText, xhr, form) {
                    // remove the validation listeners
                    $(document).unbind('failed.' + form.attr('id') + '.formValidation.ctrl');
                    $(document).unbind('passed.' + form.attr('id') + '.formValidation.ctrl');

                    // fire event to signal that the upload has finished
                    form.trigger('hasFinished.fileUpload.ctrl', [response, statusText, form]);
                }

                this.errorHandler = function(event, form, errors) {

                    $(document).unbind('failed.' + form.attr('id') + '.formValidation.ctrl');
                    $(document).unbind('passed.' + form.attr('id') + '.formValidation.ctrl');
                    
                    if (settings.onError != null) {
                        settings.onError(errors);
                    } else {
                        // initialise error message
                        var errorMsg = '';
                        // loop thru error objects, adding to the error message for each one
                        for (i in errors) {
                            errorMsg += errors[i].name + ' did not pass the ' +errors[i].rule + ' rule.\n';
                        }
                        // display an alert for the error message
                        alert(errorMsg);
                    }
                }

                this.triggerHasStarted = function() {
                    $(self).trigger('hasStarted.fileUpload.ctrl', [self.getCurrentUploadId(), self]);
                }

                this.bindSubmitButtonHandler = function() {
                    $(this).find(settings.submitButtonSelector).bind(
                        'click',
                        function() {
                            $(this).submit();
                        });
                }

                this.getCurrentUploadId = function() {
                    return currentUploadId;
                }

                this.setCurrentUploadId = function(uploadId) {
                    currentUploadId = uploadId;
                }

                settings.beforeSubmit = this.beforeSubmitHandler;
                settings.success = this.successHandler;
                settings.formValidationFailed = this.errorHandler;

                $.extend(settings, options);

                // submit the form
                $(this).ajaxForm(settings);

                if (settings.submitButtonSelector != null) {
                    // 
                    this.bindSubmitButtonHandler();
                }

                if (settings.beforeStart != null) {
                    $(this).bind('aboutToStart.fileUpload.ctrl', settings.beforeStart);
                }

                if (settings.afterStart != null) {
                    $(this).bind('hasStarted.fileUpload.ctrl', settings.afterStart);
                }

                if (settings.onFinish != null) {
                    $(this).bind('hasFinished.fileUpload.ctrl', settings.onFinish);
                }
            }
        });
    }
})(jQuery);

$(document).bind('ctrl:contentDidLoad', function(event, target) {
    target.find('.playlist table.sortable tbody').ctrlSortable({
        url:'/playlists/reOrder'
    });
    
    target.find('.track form.fileUpload').ctrlFileUpload({
        submitButtonSelector: '#TrackUploadBtn',
        beforeStart: function(event, uploadId, form) {
            // hide the form
            $(this).hide();
            // show progress
            $('.track').find('.jsUploadInfo').show();
        },
        afterStart: function(event, uploadId, form) {
            // set the name attribute to the upload id so it can be targeted by the upload manager
            $('.track').find('.jsUploadInfo').attr('name', uploadId);
            // check if the title has been edited
            if ($('#TrackTitle.fsFadedText').length > 0) {
                // get the file name so we can use it to autfill the track title field
                var fileName = $(form).find('input[type="file"]').val();
                // strip out any directories
                if (fileName.lastIndexOf('/') != -1) {
                    fileName = fileName.substr(fileName.lastIndexOf('/') + 1);
                }
                if (fileName.lastIndexOf('\\') != -1) {
                    fileName = fileName.substr(fileName.lastIndexOf('\\') + 1);
                }
                // strip the file extension
                fileName = fileName.slice(0, fileName.lastIndexOf('.'));
                // set the input value
                $('#TrackTitle.fsFadedText').val(fileName);
            }
        },
        onFinish: function(event, response) {
            if (response.Error == null) {
                // update the status element within the new item so that it displays that the upload is complete
                $('.track').find('.jsUploadInfo[name="' + response.upload_identifier + '"]').find(':not[.jsUploadComplete]').hide();
                $('.track').find('.jsUploadInfo[name="' + response.upload_identifier + '"]').find('.jsUploadComplete').show();
                // update the media file id input
                $('#MediaFile0Id').val(response.MediaFile.id);
                // update the file name field and display it
                $('#MediaFile0FileName').val(response.MediaFile.file.name).parent().show();
                // bind handler for remove file checkbox click event
                $('#MediaFile0RemoveFile').parent().show().bind('click', function(event) {
                    // show/hide delvery options
                    if ($(event.target).attr('checked')) {
                        // hide stream and download options
                        $('.streamOptions, .downloadOptions').hide();
                    } else {
                        // show stream and download options
                        $('.streamOptions, .downloadOptions').show();
                    }
                });
                // show stream and download options
                $('.streamOptions, .downloadOptions').show();
            } else {
                alert('errors!');
                $('.track').find('.jsUploadInfo').hide();
                $(this).show();
            }
                
        },
        onError: function(errors) {
            alert('The file you selected could not be uploaded');
            //console.log(errors);
        }
    });

    target.find('.mediaBrowser form.fileUpload').ctrlFileUpload({
        submitButtonSelector: '#MediaBrowserUploadFileBtn',
        beforeStart: mediaBrowser.newItemUploadAboutToStartHandler,
        afterStart: mediaBrowser.newItemUploadStartedHandler,
        onFinish: mediaBrowser.newItemWithFileResponseHandler,
        onError: function(errors) {
            alert('The file you selected could not be uploaded');
            //console.log(errors);
        }
    });
});

