// Both jquery.js and FusionCharts.js are needed for the following to work.

/*global $, window, FusionCharts */

if (window.console === null) {
    window.console = {};
}
if (window.console.debug === null) {
    window.console.debug = function () {};
}
if (window.console.info === null) {
    window.console.info = function () {};
}
if (window.console.log === null) {
    window.console.log = function () {};
}
/**
 * IE get request limit
 */
window.GET_REQUEST_LIMIT = 2000;

/**
 * This constant matches property in displaytag.properties.
 * basic.msg.empty_list=Nothing found to display.
 */
var NOTHING_FOUND = "Nothing found to display.",
    APPLY_FILTERS_TIMEOUT = 1500,
    latestRequestTime = 0,
    timeoutPeriod = 120 * 60 * 1000; //timeout period, change to jsp & times by 1000

/*** response timer: used for session timeout ***/
window.pageLoadedTime = new Date().getTime();

$.ajaxSetup({
    url: "/chart/",
    type: "GET",
    dataType: "text",
    cache: false
});

$(function () {
    /***** Set up help links *****/
    $('a#helpLink').click(function () {
        // These lines make sure the user knows a new window has opened
        // by making sure the window is at least 20px smaller than the screen
        // in addition to the 10px top and left positioning in the window.opern call
        var height, width;

        height = (window.screen.height < 768) ? window.screen.height - 20 : 768 - 20;
        width = (window.screen.width < 1024) ? window.screen.width - 20 : 1024 - 20;

        window.open(this.href, '', 'fullscreen=no,height=' + height + ',width=' + width + ',left=10,top=10,scrollbars=yes,menubar=no,toolbar=no,location=no,status=no,resizable=yes');
        return false;
    });

    /***** Binding for show/hide links *****/
    $("a.hideFilterLink").click(function () {
        window.hideFilters($(this));
        return false;
    });

    $().liveTable(["Data_Table"]);

    // Bind date range inputs - both settlements and levels use the same settings
    $('input#effectiveDateFrom').datepicker({
        dateFormat: 'dd/mm/yy',
        changeMonth: true,
        changeYear: true,
        showAnim: 'fold',
        yearRange: '-20:+20'
    });

    $('input#effectiveDateTo').datepicker({
        dateFormat: 'dd/mm/yy',
        changeMonth: true,
        changeYear: true,
        showAnim: 'fold',
        yearRange: '-20:+20'
    });

    // For IE, remove the rounded corners from the calendar to stop DD_roundies
    // breaking the background positioning
    if ($.browser.msie) {
        $('div#ui-datepicker-div').removeClass('ui-corner-all');
    }

    // Bindings to keep the date range filters valid
    $('input#effectiveDateFrom').change(function () {
        window.checkDateValidity('from');
    });

    $('input#effectiveDateTo').change(function () {
        window.checkDateValidity('to');
    });
});

function hideFilters(link) {
    if ($(link).text() === "hide") {
        $(link).text("show");
        $(link).siblings(".toHide").hide("normal");
    } else {
        $(link).text("hide");
        $(link).siblings(".toHide").show("normal");
    }
}

function checkDateValidity(source) {
    var fromTime, toTime;

    fromTime = window.convertStringToTime($('input#effectiveDateFrom').attr('value'));
    toTime = window.convertStringToTime($('input#effectiveDateTo').attr('value'));

    if (fromTime > toTime) {
        switch (source) {
        case 'from':
            $('input#effectiveDateTo').attr('value', $('input#effectiveDateFrom').attr('value'));
            break;
        case 'to':
            $('input#effectiveDateFrom').attr('value', $('input#effectiveDateTo').attr('value'));
            break;
        default:
        // Do nothing
        }
    }
}

function convertStringToTime(dateString) {
    var tempDate = new Date();
    tempDate.setFullYear(parseInt(dateString.split('/')[2], 10));
    tempDate.setMonth(parseInt(dateString.split('/')[1] - 1, 10));
    tempDate.setDate(parseInt(dateString.split('/')[0], 10));
    return tempDate.getTime();
}

function checkSessionTimer() {
    var currentTime = new Date().getTime();
    window.console.debug("checkSessionTimer current position :" + (latestRequestTime + timeoutPeriod < currentTime));
    if (latestRequestTime !== 0) {
        if (latestRequestTime + timeoutPeriod < currentTime) {
            window.sessionTimedout();
        }
    }
}

function sessionTimedout() {
    window.location.reload();
}

function Filters(filterProperties, tabsets, targets) {
    var p, i, temp;
    this.properties = filterProperties;
    for (p in filterProperties) {
        this[p] = filterProperties[p];
    }
    if (typeof(targets) === 'undefined') {
        targets = [];
    } else {
        if (!$.isArray(targets)) {
            temp = targets;
            targets = [];
            targets.push(temp);
        }
    }
    this.targets = targets;
    for (i = 0; i < tabsets.length; i = i + 1) {
        $(tabsets[i]).smgtabs();
        $(tabsets[i] + ">ul>li>a").each(function () {
            var target = window.getTarget(this);
            // a Target object consists of the target div to load,
            // plus the anchor link contained the href
            // We are storing a reference to the anchor link here, not the href
            // because the href behind a tab may be changed elsewhere in the code
            // If we stored just the href, we'd have an old copy stored as a String
            // By storing the anchor object, we can always reference the most up-to-date href
            // Coding using this needs to refer to target.link.href, not just target.href
            targets.push({target: target, link: this});
        });
    }
    this.getFilters = function () {
        var filters, p;

        filters = [];

        for (p in this.properties) {
            if ($.isArray(this[p])) {
                filters = filters.concat(this[p]);
            } else {
                filters.push(this[p]);
            }
        }
        return filters;
    };
    // call HA133104 & HA133070
    this.getParameterMap = function(){
    //	debugger;
    	var filters = this.getFilters();
    	var paramMap = {};
    	
    	for(var i = 0; i < filters.length; i++){
    		var filter = filters[i].indexOf("&") > -1 ? filters[i].split("&") :  filters[i];
    		
    		// filter might be null or undefined
    		// test first to make sure we have data
    		if(filter){
    			if($.isArray(filter)){
    				for(var j = 0; j < filter.length; j++){
    					this.addToParamMap(paramMap, filter[j]);
    				}
    			}else{
    				this.addToParamMap(paramMap, filter);
    			}
    		}


    	}
        return paramMap;
    };
    this.addToParamMap = function(paramMap, filter){

		var breakPoint = filter.indexOf("=");
		var key = filter.substring(0, breakPoint);
		var value = filter.substring(++breakPoint);
		if (paramMap[key]) {
			paramMap[key].push(value);
		} else if (key !== "") {
			paramMap[key] = [ value ];
		}    	
    };
    this.toQueryString = function () {
        var queryString;
        
        queryString = "?" + window.getTsQs();
        
        // get request params from filter
 
        queryString += this.getRequestQuery(); 

        if (window.isIE) {
            // Show animation for IE
           queryString += "&"+ window.getAnimateQs();
        }
        return queryString;
    };
    this.getRequestQuery = function(){
    	 var filters, i, filter;
    	 var queryString = "";
    	
    	 filters = this.getFilters();
    	
        for (i = 0; i < filters.length; i = i + 1) {
            filter = $.trim(filters[i]).replace('+', '%2B');
            if (filter.length > 0) {
                queryString += filter + "&";
            }
        }
        if(window.isIE && queryString.length > GET_REQUEST_LIMIT){
        	return "";
        }else{
        	return queryString;
        }
    };
    this.apply = function (except) {
        var i;
        window.setTs();
        window.console.info("Applying filters");
        for (i = 0; i < this.targets.length; i = i + 1) {
            if (typeof(except) === 'undefined' ||
                except !== this.targets[i].target[0].id) {
                $(this.targets[i].target).removeClass("loaded");
                window.loadTarget(this.targets[i].target, window.calcNewAjaxUrl(this.targets[i].link.href), window.getParameterMap());
            }
        }
        return false;
    };
    return this;
}

function calcNewAjaxUrl(oldUrl) {
    var queryString, newUrl;

    queryString = window.filters.toQueryString();
    newUrl = oldUrl.split("?")[0] + queryString;
    window.console.debug("Old Href: " + oldUrl);
    window.console.debug("New Href: " + newUrl);
    return newUrl;
}
//call HA133104 & HA133070 -An error message is displayed  when selecting ‘managerial & supervisory’,  
//'operational' and ‘professional & technical’ in the list of job families on IE
//reason - url parameter string is too long to send using get request you get a resource
//not available error
//solution - send request using post method
function getParameterMap(){
	if(window.filters.getRequestQuery){
		if(window.filters.getRequestQuery() === ""){
			return window.filters.getParameterMap();
		}
	}else{
		// request length is ok don't need to use post
		return undefined;	
	}
}

function getTsQs() {
    return "ts=" + window.latestRequestTime + "&";
}

function setTs() {
    window.latestRequestTime = new Date().getTime();
}

function getAnimateQs() {
    return "animate=0&";
}

$.fn.smgtabs = function () {

    $("ul.tabContainer", this).addClass("ui-corner-all");
    $("li.tab", this).addClass('ui-corner-top');
    // Hide all content panels
    $("div.tabContent", this).hide();
    // Add selected class to default tab
    $("li.tabDefault", this).addClass("tabSelected");
    if(window.isIE) {
        $("li.tabDefault", this).css({backgroundColor: '#FFF', color: 'blue'});
    }
    // Show panel for default tab
    $('#' + $("li.tabDefault", this).attr('id').replace('tab_', '')).css('display', 'block');

    $("li.tab a", this).click(function () {
        var targetDiv = $('#' + $(this).parent('li').attr('id').replace('tab_', ''));
        // Hide all tabs
        $(this).parents('div.tabs').children('div.tabContent').hide();
        $(this).parent("li.tab").siblings("li").removeClass("tabSelected");
        // IE isn't very good at managing styles dynamically with multiple classes
        if(window.isIE) {
            $(this).parent("li.tab").siblings("li").css({backgroundColor: '#EEE', color: '#555'});
        }
        $(this).parent("li.tab").addClass("tabSelected");
        // IE isn't very good at managing styles dynamically with multiple classes
        if(window.isIE) {
            $(this).parent("li.tab").css({backgroundColor: '#FFF', color: '#212121'});
        }
        $(this).blur();
        // Show this tab
        targetDiv.show();

        if(!$(this).hasClass('dont-load-content')) {
            window.loadTarget(targetDiv, window.calcNewAjaxUrl(this.href), window.getParameterMap());
        }

        return false;
    });
};

function getTarget(tab) {
    var re = /([_\-\w]+$)/i;
    return $("#" + re.exec(tab.title)[1]);
}

function getSelectedTarget(tabId) {
    return getTarget($(tabId + " li.tabSelected a")[0]);
}

function loadTarget(target, href, paramMap, xml) {
	//debugger;
    if ($(target).hasClass("loaded")) {
        window.console.debug("Target already loaded: NOT updating " + target);
        return;
    }

    var chartType = target.attr("chart");

    window.console.info("Target href: " + href);
    window.console.info("Chart Type: " + chartType);

    if (typeof(chartType) === 'undefined') {
        window.loadTable(target, href, paramMap);
    } else {
        window.loadChart(target, href, chartType, xml);
    }
}

function loadChart(target, href, chartType, xml) {

    if ($(target).is(":hidden")) {
        window.console.debug("Chart target is hidden: NOT updating " + target);
        return;
    }

    var debugMode, jsEnabled, targetId, chartId, chart;

    debugMode = "0";
    jsEnabled = "1";
    targetId = target.attr("id");
    chartId = targetId + "_Id";

    window.console.info("Target Id: " + targetId);
    window.console.info("Chart Id: " + chartId);

    try {
        chart = (window.isIE) ? window.getChartFromId(chartId) : null;
        if (chart === null) {
            // Firefox breaks if we keep re-using the same chart object - re-create a new one
            chart = new FusionCharts(chartType, chartId, "100%", "100%", debugMode, jsEnabled);
            chart.addParam('wmode', 'transparent');
            window.setData(chart, href, xml);
            chart.render(targetId);
        } else if (window.rendered[chartId]) {
            // IE breaks if we keep creating new objects so re-use the same one
            window.setData(chart, href, xml);
        }
        $(target).addClass("loaded");
    } catch (e) {
        window.console.info("ERROR:" + e.message);
    }
}

function setData(chart, href, xml) {
    var e;
    if (typeof(href) !== 'undefined' && href !== null) {
        chart.setDataURL(window.escape(href));
    } else if (typeof(xml) !== 'undefined' && xml !== null) {
        chart.setDataXML(xml);
    } else {
        e = {message: "Cannot set data: both href and xml are null!"};
        throw e;
    }
}

function hideAjaxSpinner() {
    $("img#loading").fadeOut(600);
}

function showAjaxSpinner() {
    $("img#loading").fadeIn(100);
}

function loadTable(target, href, paramMap) {
    var oldStuff = target.html();
    // Start the loading graphic
    
    showAjaxSpinner();
    window.console.info("Target href: " + href);
    target.load(href,paramMap, function (responseText, status, xhr) {
        var ETag, loginRegExp, errorRegExp;

        ETag = xhr.getResponseHeader("ETag");
        loginRegExp = new RegExp('meta name="page-type" content="login"');
        errorRegExp = new RegExp('meta name="page-type" content="error"');

        // Stop the loading graphic
    	hideAjaxSpinner();

        // W3C spec for ETag HTTP Response Header
        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19
        window.console.debug("ETag: " + ETag);
        window.console.debug("Current request time is " + window.latestRequestTime);
        // Check response is the one we want, ie, the latest
           //As per call HA130971 & HA133337  
           /* if (window.latestRequestTime !== parseInt(ETag, 10)) {
            window.console.debug("Received request time of " + ETag + " rejected.\n Current request time is " + window.latestRequestTime);
            // Restore previous content
            target.html(oldStuff);
               return;
        }*/

        if (errorRegExp.test(responseText)) {
            // TODO: Find out what to do when there is a server error in an ajax request
            window.console.debug("Error page returned");
        } else if (loginRegExp.test(responseText)) {
            sessionTimedout();
        }

        // Is the response empty?
        if (!responseText.match(/\w/) || responseText.indexOf(NOTHING_FOUND) > -1) {
            // TODO: Find out what to do when there is no response from an ajax request
            window.console.debug("Empty response returned");
        }

        // Label this target as "loaded" for later tab-switching
        $(target).addClass("loaded");

        window.loadTableCallback(target);
    });
}

function loadTableCallback(target) {
    // Different behaviour needed for each of settlements & levels.
}

var filterDelay;
function applyFilters(except) {
    window.clearTimeout(filterDelay);
    filterDelay = window.setTimeout(function () {
        return window.filters.apply(except);
    }, APPLY_FILTERS_TIMEOUT);
    return false;
}
