var commentsValidationError = "Please enter a location or uncheck the box";
var GpOrganisationType = 'GP';
var HospitalOrganisationType = 'Hospital';
var DentistOrganisationType = 'Dentist';

$.fn.infiniteCarousel = function() {

    // Only create the carousel if the module is visible and it hasn't been created previously.
    if ($(this).is(":hidden")) {
        return false;
    }

    var currentPage = 0;

    return this.each(function() {

        var $commentsList = $('.commentsList', this),
            $commentsListItems = $commentsList.find('li'),
            $commentsLeftEdge = $commentsList.offset().left,
            $commentsListAnchors = $commentsList.find('a'),
            singleWidth = $commentsListItems.filter(':first').outerWidth(),
            left_value = singleWidth * (-1),
            initCarousel = false;

        // paging function
        function gotoPage(page, event) {

            if (initCarousel == false) {
                $commentsListItems.filter(':first').before($commentsListItems.filter(':last'));
                $commentsList.css({ 'left': left_value });
                initCarousel = true;
            }
            var dir = 0;
            if (event == 'next') {

                dir = 1;
                //get the right position
                var left_indent = parseInt($commentsList.css('left')) - singleWidth;

                //slide the item
                $commentsList.filter(':not(:animated)').animate({ 'left': left_indent }, 100, function() {

                    //move the first item and put it as last item
                    $('.commentsList li:last').after($('.commentsList li:first'));

                    //set the default item to correct position
                    $commentsList.css({ 'left': left_value });
                });

            } else {

                dir = -1;
                //get the right position
                var left_indent = parseInt($commentsList.css('left')) + singleWidth;

                //slide the item
                $commentsList.filter(':not(:animated)').animate({ 'left': left_indent }, 100, function() {

                    //move the first item and put it as last item
                    $('.commentsList li:first').before($('.commentsList li:last'));

                    //set the default item to correct position
                    $commentsList.css({ 'left': left_value });
                });
            }

            currentPage = page;
            afterClick(currentPage, $commentsListItems, dir);

            return false;
        }

        // Only add the back/forward buttons if they haven't already been added.
        if ($(this).find('a.arrow').length == 0) {
            $(".your-comments").after('<a href="#" class="arrow back" title="Previous comment">previous</a><a href="#" class="arrow forward" title="Next comment">next</a>');
        }
        else {
            // Remove the current events that are bound to the controls.
            $(this).unbind('goto');
            $('a.back').unbind('click');
            $('a.forward').unbind('click');
            $commentsListAnchors.unbind('focus');

        }

        // create a public interface to move to a specific page
        $(this).bind('goto', function(event, page) {
            gotoPage(page);
        });

        //bind to anchor focus
        $commentsListAnchors.focus(function() {

            // determine which anchor we are on
            var anchorCount = $commentsListAnchors.index(this);

            // determine which item we are in
            currentPage = Math.floor(anchorCount / 2);

            // grab the item from the list of items at the current page
            var commentItem = $commentsListItems.eq(currentPage);

            window.setTimeout(function() {

                // find the left edge of the current page
                var commentItemLeftEdge = commentItem.offset().left;

                // calculate the difference between the item and the ul left edge
                var distance = Math.floor($commentsLeftEdge - commentItemLeftEdge);

                // move the item to line up with the view port
                $commentsList.animate({ 'left': '+=' + distance }, 'fast');

            }, 100);
        });


        // 5. Bind to the forward and back buttons
        $('a.back', this).click(function(e) {
            e.preventDefault();
            dcsMultiTrack('DCSext.HomepageEvents', 'Comment Module Previous Button clicked', 'WT.dl', '121');
            return gotoPage(currentPage - 1, 'previous');
        });

        $('a.forward', this).click(function(e) {
            e.preventDefault();
            dcsMultiTrack('DCSext.HomepageEvents', 'Comment Module Next Button clicked', 'WT.dl', '121');
            return gotoPage(currentPage + 1, 'next');

        });

    });
};

// Sets the footer link to a service specific url given the type of service that the current comment is displaying.
function afterClick(currentItem, list, dir) {

    while (currentItem < 0) {
        currentItem += list.length;
    }

    var index = currentItem % list.length;
    var currentListItem = list.get(index);

    if (currentListItem) {
        var feedbackId = $(currentListItem).attr("id");

        if (feedbackId) {
            var searchUrl = $(currentListItem).find("input." + feedbackId).val();

            if (searchUrl) {
                $(".module-comments .FooterTitle1Link").attr("href", searchUrl);
            }
        }
    }
}

// If the user has selected to use the location specified in the edit panel then check the 
// location entered and save it to a cookie.
function CommentsAfterSave(moduleId) {
    var containerClassSelector = getCommentsContainerSelector(moduleId);
    var locationTextSelector = getLocationTextSelector();
    var locationInputSelector = getLocationInputSelector(moduleId);
    var locationDetailsSelector = getLocationDetailsSelector(moduleId);
    var locationMessageSelector = locationDetailsSelector + ' .location-mesg';

    // Reset the error class.
    removeErrorClass(moduleId);

    if ($(locationMessageSelector).length > 0) {
        $(locationMessageSelector).remove();
    }

    // If the user has selected to use the current location for comments.
    if (IsUseLocationSelected(moduleId)) {
        var locationText = $(locationInputSelector).val();
        if (locationText && ((locationText == defaultLocationText) || (locationText.length == 0))) {
            // Display a message to the user informing them that they must enter a value for location.
            $(locationDetailsSelector).prepend('<p class="location-mesg"><label class="error">' + commentsValidationError + '</label></p>');
            $(getEditPanelContainerSelector(moduleId)).addClass(getCommentsErrorCssClass());
            return false;
        }
        else {
            // Disambiguate.
            var newProfileData = { location: $(locationInputSelector).val(), useLocation: true };
            var continueWithSave = true;

            var commentsData = GetCommentsData();
            if ((commentsData) && (locationText == commentsData.location)) {
                // Use the currently stored data as it has already been disambiguated.
                newProfileData = commentsData;
            }
            else {
                continueWithSave = getProfileLocation(newProfileData, containerClassSelector, locationTextSelector, true);
            }

            if (continueWithSave) {
                setNHSCookie(commentsProfileCookieName, JSON.stringify(newProfileData));
                PersonaliseComments(moduleManager.getProfileData(), containerClassSelector, moduleId);
            }

            return continueWithSave;
        }
    }
    else {
        // Checkbox is not enabled so remove the cookie and close the edit panel.
        var profileData = { location: null, useLocation: false };
        setNHSCookie(commentsProfileCookieName, JSON.stringify(profileData));
        CommentsInitialiser(null, moduleId);
        location.reload();
        return true;
    }
}

// Determines if the user has chosen to use the current location to personalise comments.
function IsUseLocationSelected(moduleId) {
    var useLocationCheckboxSelector = getUseLocationCheckboxSelector(moduleId);
    return $(useLocationCheckboxSelector).attr("checked") == true;
}

// Gets the value stored in the cookie and sets the checkbox.
function SetUseLocation(moduleId) {
    var useLocationCheckboxSelector = getUseLocationCheckboxSelector(moduleId);
    var checked = true; //Default to true.

    commentsData = GetCommentsProfileData();

    // if the value was stored in the cookie then set the checkbox accordingly.
    if (commentsData && (typeof (commentsData.useLocation) != 'undefined')) {
        checked = commentsData.useLocation;
    }

    $(useLocationCheckboxSelector).attr("checked", checked);
}

// When the comments module initialises
function CommentsInitialiser(profileData, moduleId) {
    var containerClassSelector = getCommentsContainerSelector(moduleId);
    var locationTextSelector = getLocationTextSelector();
    var locationInputSelector = getLocationInputSelector(moduleId);

    // Set the checkbox checked state if stored in the cookie.
    SetUseLocation(moduleId);

    // Call the handler for personalised comments if required.
    PersonaliseComments(profileData, containerClassSelector, moduleId);
}

// If location data has been stored then the comments handler will be called to get
// comments personalised for this location.
function PersonaliseComments(profileData, containerClassSelector, moduleId) {
    if (IsUseLocationSelected(moduleId)) {
        profileData = GetCommentsData(profileData);

        if (IsLocationDataAvailable(profileData)) {
            // Call the handler and update the html with the response.
            var maxItems = (comments_maxItems) ? comments_maxItems : 3;
            var qs;
            (profileData.location) ? qs = 'location=' + escape(profileData.location) + '&' : qs = '';
            (profileData.easting) ? qs += 'easting=' + escape(profileData.easting) + '&' : qs += '';
            (profileData.northing) ? qs += 'northing=' + escape(profileData.northing) + '&' : qs += '';
            qs += 'maxItems=' + maxItems;
            var handlerUrl = '/HomePageModules/handlers/Comments.ashx?' + qs;

            //don't cache the results, and ensure that the call is actually completed asynchronously.
            $.ajaxSetup({
                async: true,
                cache: false
            });

            $.get(handlerUrl, function(data, textStatus, XMLHttpRequest) {
                if (textStatus == 'success') {

                    var listItems = GetRandomItems(data);
                    var commentsListSelector = containerClassSelector + ' .commentsList';
                    // Remove existing items.
                    $(commentsListSelector).find('li').remove();
                    // Add the new items.
                    $(listItems).each(function() {
                        $(commentsListSelector).append($(this));
                    });

                    initialiseCarousel();

                    // Update the explanatory text with the location that the user has selected.
                    $(containerClassSelector + ' h3 span.headerTextPersonalised').html(' near ' + profileData.location);
                }
            });
        }
    }
}

// Randomises the list of items that are returned so that 1 from GPs, 1 from Hospitals, 1 from Dentists
// and 2 from Other Services are displayed. If there aren't enough to fill the list of 5 then it
// randomly selects items from those remaining until there are 5 items returned.
function GetRandomItems(data) {
    var randomItems = new Array();
    var allItems = $("<ul>").append(data);

    // GP.
    GetRandomItem(allItems, GetSpecificOrganisationTypeSelector(GpOrganisationType), randomItems);

    // Hospital.
    GetRandomItem(allItems, GetSpecificOrganisationTypeSelector(HospitalOrganisationType), randomItems);

    // Dentist.
    GetRandomItem(allItems, GetSpecificOrganisationTypeSelector(DentistOrganisationType), randomItems);

    // Other Services.
    GetRandomItem(allItems, GetOtherServicesTypeSelector(), randomItems);
    GetRandomItem(allItems, GetOtherServicesTypeSelector(), randomItems);

    // Randomly select from those items left.
    while (($(allItems).children().length > 0) && (randomItems.length < 5)) {
        GetRandomItem(allItems, 'li', randomItems);
    }

    // Randomly sort.
    randomItems.sort(function() { return 0.5 - Math.random(); });

    return randomItems;
}

// Creates a class selector for a specific organisation type e.g. a GP.
function GetSpecificOrganisationTypeSelector(organisationType) {
    return 'li[id*=' + organisationType + ']';
}

// Creates a class selector for organisation types that are not GP, hospital or dentist.
function GetOtherServicesTypeSelector() {
    return 'li:not([id*=' + GpOrganisationType + '][id*=' + HospitalOrganisationType + '][id*=' + DentistOrganisationType + '])';
}

// Gets a item from the list of items retrieved (based on the selector passed in) after it 
// has been randomly sorted. Removes the item selected from the data passed in.
function GetRandomItem(data, listItemsSelector, randomItems) {
    var listItems = $(data).find(listItemsSelector);

    if (listItems && (listItems.length > 0)) {
        if (listItems.length > 1) {
            // Randomly sort.
            listItems.sort(function() { return 0.5 - Math.random(); });
        }

        // Add it to the new item array.
        randomItems.push(listItems[0]);

        // Remove the item from the list.
        var currentItemSelectorId = 'li[id=' + listItems[0].id + ']';
        $(data).find(currentItemSelectorId).remove();
    }
}

// Gets any comments data if it is stored in the cookie, otherwise, uses
// homepage preferences cookie values for the profile data.
function GetCommentsData(profileData) {
    // Check if there is any comments data.
    var commentsData = GetCommentsProfileData();

    // Use data stored for the comments module if found.
    if (IsLocationDataAvailable(commentsData)) {
        profileData = commentsData;
    }

    // Otherwise, use the values stored in homepage preferences.
    if (!profileData) {
        profileData = moduleManager.getProfileData();
    }

    return profileData;
}

// Determines if there is location data available that can be used to personalise the comments.
function IsLocationDataAvailable(profileData) {
    return (profileData) && (profileData.location) && (profileData.location.length > 0) &&
            (profileData.easting) && (profileData.easting.length > 0) &&
            (profileData.northing) && (profileData.northing.length > 0);
}

// Remove the error class if it exists for styling purposes.
function removeErrorClass(moduleId) {
    $(getEditPanelContainerSelector(moduleId)).removeClass(getCommentsErrorCssClass());
}

// Creates an location input box when the user clicks the edit link in the module.
function CommentsAfterEditClick(moduleId) {
    var containerClassSelector = getCommentsContainerSelector(moduleId);
    var locationTextSelector = getLocationTextSelector();
    var locationDetailsSelector = getLocationDetailsSelector(moduleId);
    var locationValue = '';
    var locationInputSelector = getLocationInputSelector(moduleId);

    removeErrorClass(moduleId);

    var profileData = GetCommentsData(null);
    if ((profileData) && (profileData.location)) {
        locationValue = profileData.location;
    }

    createLocationInputBox(containerClassSelector, locationDetailsSelector, locationTextSelector, locationValue);

    // Set up the save button as the default when enter is pressed in the location input field.
    $(locationInputSelector + ',' + getUseLocationCheckboxSelector(moduleId)).keypress(function(e) {
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
            $(this).closest('.module').find('.module-save a').click();
            return false;
        } else {
            return true;
        }
    });
}

// Gets the comments profile data from the cookie value stored.
function GetCommentsProfileData() {
    return getJSONObjectFromCookie(commentsProfileCookieName);
}

// Gets the container class selector for comments.
function getCommentsContainerSelector(moduleId) {
    return '#' + moduleId;
}

// Gets the class selector for the location input field.
function getLocationTextSelector() {
    return '.commentsLocationText';
}

// Gets the class selector for the div containing the location details elements.
function getLocationDetailsSelector(moduleId) {
    return getCommentsContainerSelector(moduleId) + ' #location-details';
}

// Get the selector for the location input field.
function getLocationInputSelector(moduleId) {
    return getCommentsContainerSelector(moduleId) + ' input' + getLocationTextSelector();
}

function getUseLocationCheckboxSelector(moduleId) {
    return getCommentsContainerSelector(moduleId) + ' input.useLocation';
}

function getEditPanelContainerSelector(moduleId) {
    return getCommentsContainerSelector(moduleId) + ' .module-edit-content';
}

// Gets the error css class to allow styling of the checkbox and location input field in error.
function getCommentsErrorCssClass() {
    return 'module-edit-error';
}

// Sets up the carousel for displaying comments.
function initialiseCarousel() {
    $('.comment-holder').infiniteCarousel();
}

// After the open button is clicked need to set up the carousel for rotating comments.
function CommentsAfterOpenClickScript(moduleId) {
    initialiseCarousel();
}

// Resets the checkbox after the cancel button has been clicked.
function CommentsEditPanelCancelClick(moduleId) {
    // Set the checkbox checked state if stored in the cookie.
    SetUseLocation(moduleId);
}

jQuery(document).ready(function() {
    var element = $('.share-link');
    $(element).click(function(e) {
        e.preventDefault();
        renderstep2();
    });
});

function findservices() {

    var location = jQuery('#comment-location').val();
    var orgKey = jQuery('#comment-ddl-services').find('option:selected').val();

    // Since the variables are passed from velocity template, have a quick check whether they exist.
    if ((typeof (step3title) == 'undefined') || (step3title == null)) {
        var step3titlecopy = '';
    }
    else {
        var step3titlecopy = step3title;
    }

    if ((typeof (webtrendstag) == 'undefined') || (webtrendstag == null)) {
        var webtrendstagcopy = '';
    }
    else {
        var webtrendstagcopy = webtrendstag;
    }

    if ((typeof (webpartheader) == 'undefined') || (webpartheader == null)) {
        var webpartheadercopy = '';
    }
    else {
        var webpartheadercopy = "<h2>" + webpartheader + "</h2>";
    }

    if (orgKey == "") {
        renderstep2("serviceError");
    }
    else if (location == "" || location == "Postcode, town or practice name") {
        renderstep2("orgError", orgKey);
    }
    else {

        var orgKeyText = ' ' + orgKey;
        if (orgKey == "walkincentre") {
            orgKeyText = " walk-in centre";
        }
        if (orgKey == "aande") {
            orgKeyText = "n A&E";
        }
        if (orgKey == "maternity") {
            orgKeyText = " maternity service";
        }

        jQuery.get("/homepagemodules/Handlers/CommentOnOrganisation.ashx?step=3&location=" + location + "&orgtype=" + orgKey + "&webtrendstag=" + webtrendstagcopy, function(data) {
        jQuery(".share-container").html(data).prepend('<p class="share-text">' + step3titlecopy + orgKeyText + ' near:' + '</p>');
            jQuery(".share-container").prepend(webpartheadercopy);
            jQuery(".share-back, .share-commentanother, .share-cancel").wrap('<li class="share-foot-links" />');
            jQuery("li.share-foot-links").wrapAll('<ul class="share-foot" />');
            if (data == "") {
                renderstep2("orgError", orgKey);
            }

        });
    }
}

function commentgoback() {
   renderstep2(); 
}

function renderstep1() {

    // Since the variables are passed from velocity template, have a quick check whether they exist.
    if ((typeof (action1text) == 'undefined') || (action1text == null)) {
        var action1textcopy = '';
    }
    else {
        var action1textcopy = action1text;
    }

    // Since the variables are passed from velocity template, have a quick check whether they exist.
    if ((typeof (action1textdesc) == 'undefined') || (action1textdesc == null)) {
        var action1textdesccopy = '';
    }
    else {
        var action1textdesccopy = action1textdesc;
    }

    if ((typeof (step1title) == 'undefined') || (step1title == null)) {
        var step1titlecopy = '';
    }
    else {
        var step1titlecopy = step1title;
    }

    if ((typeof (webtrendstag) == 'undefined') || (webtrendstag == null)) {
        var webtrendstagcopy = '';
    }
    else {
        var webtrendstagcopy = webtrendstag;
    }

    if ((typeof (webpartheader) == 'undefined') || (webpartheader == null)) {
        var webpartheadercopy = '';
    }
    else {
        var webpartheadercopy = webpartheader;
    }

    if ((typeof (imageurl) == 'undefined') || (imageurl == null)) {
        var imageurlcopy = '';
    }
    else {
        var imageurlcopy = imageurl;
    }

    jQuery.get("/homepagemodules/Handlers/CommentOnOrganisation.ashx?step=1&action1text=" + action1textcopy + "&action1textdesc=" + action1textdesccopy + "&webtrendstag=" + webtrendstagcopy + "&webpartheader=" + webpartheadercopy + "&imageurl=" + imageurlcopy, function(data) {
        jQuery(".share-wp").replaceWith(data);
        jQuery(".share-wp").addClass("step1");
        jQuery(".share-text").html(step1titlecopy);
        jQuery(".your-comments-wrap, .comment-holder h3").removeClass("hidden");
        jQuery(".share-container").removeClass("steps");

    });
}

function renderstep2(error, orgKey) {

    // Since the variables are passed from velocity template, have a quick check whether they exist.
    if ((typeof (step2title) == 'undefined') || (step2title == null)) {
        var step2titlecopy = '';
    } else {
        var step2titlecopy = step2title;
    }

    if ((typeof (webpartheader) == 'undefined') || (webpartheader == null)) {
        var webpartheadercopy = '';
    }
    else {
        var webpartheadercopy = "<h2>" + webpartheader + "</h2>";
    }

    jQuery.get("/homepagemodules/Handlers/CommentOnOrganisation.ashx?step=2", function(data) {
        jQuery(".share-container").html(data).addClass("steps");
        jQuery(".your-comments-wrap, .comment-holder h3").addClass("hidden");
        jQuery(".share-wp").removeClass("step1").addClass("nobg");
        jQuery(".share-find, .share-cancel").prepend('<span class="crnr tl"></span><span class="crnr tr"></span><span class="crnr bl"></span><span class="crnr br"></span>');
        jQuery(".share-find").wrap('<li class="find-link" />');
        jQuery(".share-cancel").wrap('<li class="cancel-link" />');
        jQuery(".share-step-2").prepend('<p class="share-text">' + step2titlecopy + '</p>');
        jQuery(".share-step-2").prepend(webpartheadercopy);
        jQuery(".share-step-2 li").wrapAll('<ul class="clear" />');
        jQuery(".share-step-2 ul").wrap('<div class="share-buttons" />');


        if (error == "orgError") {
            jQuery("#comment-location").before('<p class="error">Please enter a valid postcode, town or practice name</p>');
            jQuery("#comment-ddl-services option[value='" + orgKey + "']").attr("selected", "selected");
        } else if (error == "serviceError") {
            jQuery("#comment-location").before('<p class="error">Please select a service</p>');
        }
        
        // set focus to Service drop down list
        jQuery("#comment-ddl-services").focus();

        // When Enter button is pressed and focus is on location box then call findServices() if location is provided otherwsie through validation error.
        jQuery("#comment-location").live("keypress", function(e) {
            if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
                if (location == "" || location == "Postcode, town or practice name") {
                    renderstep2("orgError", orgKey);
                }
                else {
                    findservices();
                }
                return false;
            } else {
                return true;
            }

        });

        // When Enter button is pressed and focus is on Serviced drop down list then call findServices() if location is provided otherwsie through validation error.
        jQuery("#comment-ddl-services").live("keypress", function(e) {
            if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
                if (location == "" || location == "Postcode, town or practice name") {
                    renderstep2("orgError", orgKey);
                }
                else {
                    findservices();
                }
                return false;
            } else {
                return true;
            }
            
        });
        
        jQuery('.location').focus(function() {
            if (jQuery(this).val() == jQuery(this).attr('defaultValue'))
                jQuery(this).val('');
        });
        jQuery('.location').blur(function() {
            if (jQuery(this).val() == '')
                jQuery(this).val(jQuery(this).attr('defaultValue'));
        });    
            
    });
}

function commentgetorgs(location, orgtype, northing, easting, ispostcode, isplacename, webtrendstag) {

    var element = jQuery('.share-step-3-links');

    // Since the variables are passed from velocity template, have a quick check whether they exist.
    if ((typeof (step4title) == 'undefined') || (step4title == null)) {
        var step4titlecopy = '';
    }
    else {
        var step4titlecopy = step4title;
    }

    if ((typeof (webtrendstag) == 'undefined') || (webtrendstag == null)) {
        var webtrendstagcopy = '';
    }
    else {
        var webtrendstagcopy = webtrendstag;
    }

    if ((typeof (webpartheader) == 'undefined') || (webpartheader == null)) {
        var webpartheadercopy = '';
    }
    else {
        var webpartheadercopy = "<h2>" + webpartheader + "</h2>";
    }

    var url = "/homepagemodules/Handlers/CommentOnOrganisation.ashx?step=4&location=" + location
                + "&orgtype=" + orgtype
                + "&northing=" + northing
                + "&easting=" + easting
                + "&ispostcode" + ispostcode
                + "&isplacename" + isplacename
                + "&webtrendstag" + webtrendstagcopy

    jQuery.get(url, function(data) {
        jQuery(".share-container").html(data).prepend('<p class="share-text">' + step4titlecopy + '</p>');
        jQuery(".share-container").prepend(webpartheadercopy);
        jQuery(".share-commentanother, .share-cancel").wrap('<li class="share-foot-links" />');
        jQuery(".share-step-4 li.share-foot-links").wrapAll('<ul class="share-foot" />');
    });
 }

