var gUserHistorySelectValues = [];  //data to store the dates for the history_selector _dropdown
gUserHistorySelectValues.INITIALIZED = false;
var gUserHistoryCache = new MfHashtable(); //cache to store history for days other than present


function createHistoryUI(){
	// Workaround for EM-752
	if (application.isInternetExplorer6) {
		$("user_history_form").onscroll = function() {
			$("user_history_selector").style.visibility = "hidden";
			$("user_history_selector").style.visibility = "visible";
		}
	}
	
    $("history_delete").onclick = clearUserHistory;
    var theTimestamp = document.createElement("p");
    theTimestamp.innerHTML = i18n.just_viewed;

    var insideWrapper = document.createElement("div");
    insideWrapper.id = "current_user_history";

    var wrapper = document.createElement("div");	// creating a separate wrapper to toggle current history display
    wrapper.id = "current_user_history_wrap";

    wrapper.appendChild(theTimestamp);
    wrapper.appendChild(insideWrapper);

    var pastWrapper = document.createElement("div");
    pastWrapper.id = "past_user_history_wrap";
    pastWrapper.style.display = "none";

    var theSelect = document.createElement("select");
    theSelect.id = "user_history_selector";
	
    theSelect.onchange = function() {
        //if (this.value == "today") {
        //    $("past_user_history_wrap").style.display = "none";
        //    $("current_user_history_wrap").style.display = "block";
        //} else {
            displayHistory(this.value);
        //}
    }
    var pWrap = document.createElement("p");
    pWrap.style.clear = "both";
    pWrap.style.margin = "1.0em 0";
	
    var label = document.createElement("label");
    label.setAttribute("for", "user_history_selector");
    label.innerHTML = i18n.view_history_for;

    pWrap.appendChild(label);
    pWrap.appendChild(theSelect);

    var infoHistory = $("info_history");
	infoHistory.appendChild(pWrap);	// the paragraph with the date select
    infoHistory.appendChild(wrapper);	// #current_user_history_wrap
    infoHistory.appendChild(pastWrapper);	// #past_user_history_wrap
}


//displays the history thumbs in history pane - e.g. when user chooses to see different history date
function displayHistory(dateStr,isInit) {
	debug("[UserHistory] Fetching history for " + dateStr);
	
	var params = {};
	params["from"] = dateStr + " 00:00:00";
	params["to"]  = dateStr + " 23:59:59";
	params["lastN"] = 80;
	params["parent"] = "past_user_history_wrap";
    params["actionName"] = "featureImageView";

    wait("Loading your image history...");

    var init = (isInit) ? true : false;
    selSetIndexByValue($("user_history_selector"),dateStr); //despite appearance this does not produce circular call safari/ff
    if(isDateToday(dateStr) &&  init == false){
        stopWait();
        addHistoryElements(params.parent,dateStr,application.userHistory);
    } else if (gUserHistoryCache.hasKey(dateStr)){
        stopWait();
        addHistoryElements(params.parent,dateStr,gUserHistoryCache.get(dateStr));
    } else {
        ViewUserHistory.execute(params, {callback:displayHistoryCallback.curryAlt(dateStr)});
    }
}

//creates the user history thumb image/element
function createHistoryThumb(attributes,createdAtInMillis){
    var img = document.createElement("a");

    img.className = "result_image";
    if ( createdAtInMillis ) {
        try {
            var localeDate = new Date(parseInt(createdAtInMillis));
        } catch(err){
            var localeDate = new Date(); // default to current date
        }
    } else {
        var localeDate = new Date();
    }

    img.setAttribute("title", i18nX(i18n.viewed_on, localeDate.toLocaleString()));
    img.style.backgroundImage = "url(" + application.imageServerURL + getPath('eh', attributes.image_code) + ")";
    img.href = "?image=" + attributes.image_code;
    img.href += "&width=" + attributes.wm_width;
    img.href += "&height=" + attributes.wm_height;
    img.href += "&wmark=" + attributes.wmark;
    img.href += "&thumb=" + attributes.thumb;
    img.href += "&keyword=" + Url.encode( attributes.keywords );
    img.id = "his_" + attributes.result_position;

    img.onclick = handleHistoryThumbClick;
    return img;
}


function displayHistoryCallback(dateStr,response){
    //alert(JSON.stringify(response));
    //alert(JSON.stringify(response.result));
    //alert(response.result);
    stopWait();
    if (response.result.length == 0) {
		debug("[UserHistory] This user has no history.");
		return;
	}
    var actions = response.result;

    var createdAt = actions[0].action.createdAt.slice(0,19); //TODO add check for actions[0]
    var imageSet = new MfOrderedHash("desc");

	// This is a fix for IE, which misreads the eval() parsing above and adds an extra (empty) element to the end of the list.
	// See EM-588 for about the same amount of detail.
	var endOfList = actions.length - 1;
	while (endOfList >= 0 && !actions[endOfList]) {
		endOfList--;
	}

    for(var i = endOfList; i > -1; i--){
       var imageCode = actions[i].action.attributes.image_code;
        if (imageCode) {
            var img = createHistoryThumb(actions[i].action.attributes,actions[i].action.createdAtInMillis );    // createdAt is date string in yyyy-MM-dd HH:mm:ss.SSSZ format -- UserAction.java
            imageSet.set(imageCode, img);
        }
    }
    if(isDateToday(dateStr)){
        application.userHistory = imageSet;
    } else {
        //add to cache
        gUserHistoryCache.set(dateStr,imageSet);
    }
    addHistoryElements(response.parent,createdAt,imageSet);
}


function addHistoryElements(parent,createdAt,imageSet){
	if (parent == "past_user_history_wrap") {
		var pastWrap = $("past_user_history_wrap");
		
		while (pastWrap.firstChild){
			pastWrap.removeChild(pastWrap.firstChild);
        }

        $("current_user_history_wrap").style.display = "none";
		pastWrap.style.display = "block";
	}

	if(imageSet.length() == 0) return;
	
	var theTimestamp = document.createElement("p");
	//theTimestamp.innerHTML = actions[0].action.createdAt.slice(0,19);
	//theTimestamp.innerHTML = createdAt;    
    theTimestamp.innerHTML = formatDate( parseDate(createdAt.slice(0,10)), i18n.em_date_format );

    $(parent).appendChild(theTimestamp);

    for (i=0; i < imageSet.length(); i++) {
			$(parent).appendChild(imageSet.getIdx(i));
	}
    //debug("[UserHistory] addHistoryElements called for " + response.from + " to " + response.to);
}


// Wrapper function to avoid creating an indefinite number of anonymous functions.
function handleHistoryThumbClick() {
	noResultsOff(true);	// partial hiding of the "no-results" in case we're in a no-results state - EM-786
	fetchFeatureAndSims(this);
	return false;
}


function clearUserHistory() {
	if (!confirm( i18n.clearHistory ))
		return;
	
	var params = {};
	//params["userId"] = $("user_id").value;
	params["deleteAll"] = "yes";

	DeleteUserHistory.execute(params);

    var pastWrap;
    if (pastWrap = $("past_user_history_wrap")) {
        while (pastWrap.firstChild){
			pastWrap.removeChild(pastWrap.firstChild);
        }
    }

	resetUserHistory();
	
    gUserHistorySelectValues = [];
    fillUserHistorySelect();
	
}


function isDateToday(dateStr){
    var r = false;
    if (dateStr == null) return r;
    var today = new Date();
    var dAry = mfMap(function(a){return new Number(a);},dateStr.split("-"));
    if(dAry.length == 3){
        if (dAry[0] == today.getFullYear()){
            if((dAry[1]-1) == today.getMonth() && dAry[2]==today.getDate()){
                r = true;
            }
        }
    }
    return r;
}
//test isDateToday
/*alert(isDateToday("2008-10-01"));
alert(isDateToday("2008-1"));
alert(isDateToday("2008-09-25"));
alert(isDateToday("2008-9-25"));
alert(isDateToday("aaa"));
alert(isDateToday(null));*/


function fillUserHistorySelect(preserve){
    //uses global gUserHistorySelectValues to populate the select box
    var selObj = $("user_history_selector");
    var needToPreserve = false;
    var oldValue;
    if(preserve){
        needToPreserve = true;
        oldValue = selValue(selObj);
    }
    var dates = gUserHistorySelectValues;
    dwr.util.removeAllOptions("user_history_selector");
    if(dates.length > 0){
     
        var selectDates = mfMap(function(a){return {"text":(isDateToday(a) ? i18n.em_today :
                formatDate(parseDate(a),i18n.em_date_format) ), "value":a}},dates);
        dwr.util.addOptions("user_history_selector",selectDates,"value","text");
    }
    if(needToPreserve){
        selSetIndexByValue(selObj,oldValue);
    }
}


function isTodaySelectedInHistory(){
    if (isDateToday(selValue($("user_history_selector")))){
        return true;
    } else {
        return false;
    }
}

//this is called from feature.js to inform us of the fact that an image has been clicked
function addToTodaysHistory(attrs){
    //add to local history
    //add date to select - but preserve selected index
    //redraw if today was selected or if there is nothing selected at all

    if (areWeInRegularSearch()) {

        var weNeedToRedraw = isTodaySelectedInHistory() || (!(selValue($("user_history_selector"))));

        var img = createHistoryThumb(attrs);
        insertHistoryImage(img);
        resetHistoryButtons();
        //save history to drop down

        var d = new Date();

        var dateOnly1 = formatDate(d, "yyyy-MM-dd");
        //add the date to drop down if it does not exist but preserve the current selected index
        if (mfElemIndex(gUserHistorySelectValues, dateOnly1) == -1) {
            gUserHistorySelectValues.unshift(dateOnly1);
            fillUserHistorySelect(true);
        }

        if (weNeedToRedraw) {
            displayHistory(dateOnly1); //redraws the history thumbnails
        }
    }
}

/** This is called every time a new search is performed.  It saves all search details to user history
 *  for later recall (via the back button, or bookmark, or a different method).  It also updates
 *  the user hash.
 *
 */
function saveCurrentSearchState() {
	if (areWeInRegularSearch()) {
		var search_form = $("search_form");
	    var params = {};
	    params["actionName"] = "searchDetails";
	
	    params["attrName_1"] = "query";
	    params["attrVal_1"]  = $("rawQuery").value;

	    params["attrName_2"] = "licType";
	    params["attrVal_2"]  = getRadioValue(search_form.licType);
	
	    params["attrName_3"] = "sort";
	    params["attrVal_3"]  = getRadioValue(search_form.sort);
	
	    params["attrName_4"] = "so_horizontal";
	    if ($("so_horizontal").checked) {
	    	params["attrVal_4"] = true;
	    } else {
	    	params["attrVal_4"] = false;
		}
	
	    params["attrName_5"] = "so_vertical";
	    if ($("so_vertical").checked) {
	    	params["attrVal_5"] = true;
	    } else {
	    	params["attrVal_5"] = false;
		}

	    params["attrName_6"] = "so_square";
	    if ($("so_square").checked) {
	    	params["attrVal_6"] = true;
	    } else {
	    	params["attrVal_6"] = false;
		}

	    params["attrName_7"] = "so_panoramic";
	    if ($("so_panoramic").checked) {
	    	params["attrVal_7"] = true;
	    } else {
	    	params["attrVal_7"] = false;
		}
/* EM-1019: disabled on TRUNK
	    params["attrName_8"] = "so_qspace";
	    if ($("so_qspace").checked) {
	    	params["attrName_8"] = true;
	    } else {
	    	params["attrName_8"] = false;
		}

        params["totalAttributes"] = "8";
*/
        params["totalAttributes"] = "7";

        SaveAction.execute(params, {
			callback:function(response) {
			    if (! response.error) {
    				var res = eval('(' + response.result + ')');
			
	    			$("hash_history_user_id").value = res.action.userId;

			    	var ts = res.action.createdAt;

				    application.searchDetailHistory.set(ts, res.action.attributes);
			
    				updateHistoryHash(ts);
    	        }
			}
		});
	} else if (areWeInLightbox()) {
		// No server-side saving when in lightbox.  We only update the left index position,
		// since there are no other variables.
		updateHistoryHash("");
	}
}

function updateHistoryHash(timestampString) {
	// Turn off hash polling while we update it.
	var chh = $("check_hash_history");
	chh.value = "false";
	
	var currentHash = getHash();
	
	// Add or update the hash string with the left index position.
	var str = currentHash;
	if (str.indexOf("sp=") > 0) {
		str = str.replace(new RegExp("sp\=[^&]*"), "sp=" + getLeftIndex());
	} else {
		str += "&sp=" + getLeftIndex();
	}
	
	// Add or update the hash string with the timestamp string.
	if (str.indexOf("ts=") > 0) {
		str = str.replace(new RegExp("ts\=[^&]*"), "ts=" + timestampString);
	} else {
		str += "&ts=" + timestampString;
	}	

	if (str != currentHash) {
		debug("[HASHSTORY] UHH: Compared " + str + " with " + currentHash + " and they are different")
	 	setHash(str);
		$("last_hash_history").value = str;
		debug("[HASHSTORY] UHH: Just stored hash, it is " + $("last_hash_history").value + " and should be " + currentHash);
	} else {
		debug("[HASHSTORY] UHH: Compared " + str + " with " + currentHash + " and they are the same, so no publish")
	}
	
	application.searchReloadInProgress = false;

	debug("Hash is now " + str);
	
	// Turn hash polling back on.
	chh.value = "true";	
}

function hashEncode(str) {
	return encodeURIComponent(str);
}

function hashDecode(str) {
	return decodeURIComponent(str);	
}

function setHash(str) {
    if (application.isInternetExplorer6) {
        return;
    }
    window.location.hash = str;
	if (application.isInternetExplorer) {
		$("ie_hash_workaround").src = "/em/search/blank.html?" + str.slice(1);	// removing the hash
	}
}

function getHash() {
	if (application.isInternetExplorer6) {
        return "";
    }
	if (application.isInternetExplorer) {
        /* AW Jan 30, 09: This code is not working it is returning '?p=' in IE7
        var historyFrame = document.getElementById("ie_hash_workaround");
		var doc = historyFrame.contentWindow.document;
		var hash = new String(doc.location.search);
		return hash.slice(hash.indexOf("?"));
		*/
        var loc = ""+window.location;
        var idx_hash = loc.indexOf("#");
        var hash = "";
        if ( idx_hash > 0 ) {
            hash = "#" + Url.decode(loc.substr(idx_hash+1));
        }
        return hash;


    }
	return window.location.hash;
}

function updateHashSearchPosition() {
	// Turn off hash polling while we update it.
	var chh = $("check_hash_history");
	chh.value = "false";

	// We have to wait for updateHistoryHash to establish this search's history hash string before we
	// can begin incrementing it.  Otherwise we end up with extraneous records in the browser history.
	if (application.searchReloadInProgress) {
		return;
	}
	
	var currentHash = getHash();
	
	// Add or update the hash string with the left index position.
	var str = currentHash;
	if (str.indexOf("sp=") > 0) {
		str = str.replace(new RegExp("sp\=[^&]*"), "sp=" + getLeftIndex());
	} else {
		str += "sp=" + getLeftIndex();
	}

	if (str != currentHash) {
		debug("[HASHSTORY] UHSP: Compared " + str + " with " + currentHash + " and they are different")
		setHash(str);
		$("last_hash_history").value = str;
		debug("[HASHSTORY] UHSP: Just stored hash, it is " + $("last_hash_history").value);
	} else {
		debug("[HASHSTORY] UHSP: Compared " + str + " with " + currentHash + " and they are the same, so no publish")
	}
	
	debug("Hash is now " + str);
	
	// Turn hash polling back on.
	chh.value = "true";
}

function pollHistoryHash() {
    if (application.isInternetExplorer6) {
        return;
    }
    //EM-1499 I do not want any of this executed if the modal infomercial is open
    if(ELOCKS.get("MODAL_INFO_LOCK")){
        return;    
    }
    // If the back button was clicked.
	if ($("pageLeftToggle").value == "false" 
		&& $("pageRightToggle").value == "false"
		&& $("traffic_light").value != "go"
		&& $("check_hash_history").value == "true") {

		var currentHash = getHash();
		var storedHash = $("last_hash_history").value;
		
		if (currentHash != storedHash) {
			$("last_hash_history").value = currentHash;
			
			debug("[HASHSTORY] A change was detected!");
			debug("[HASHSTORY] currentHash: " + currentHash);
			debug("[HASHSTORY]     storedHash: " + storedHash);
			
			var storedPos = getLeftIndex();
			var currentPos = currentHash.getQueryValue("sp");

			var oldTimestamp = hashDecode(storedHash.getQueryValue("ts"));
			var newTimestamp = hashDecode(currentHash.getQueryValue("ts"));
			
			if (areWeInRegularSearch() && oldTimestamp != newTimestamp) {
				// Revert to the search specified by newTimestamp.
				
				closeFeatureImage();	// EM-738
				
				var nts = newTimestamp;
				var attributes = application.searchDetailHistory.get(nts);
				if (attributes) {
					attributes.sp = currentPos;
					createNewSearch(attributes);
				} else {
					fetchSearchState(newTimestamp);
				}
			} else if (storedPos != currentPos) {
				closeFeatureImage();	// EM-738
				slideTo(currentPos);
			}
		}
	}
	window.setTimeout("pollHistoryHash()", 600);
}

function fetchSearchState(ts) {
	var year   = ts.slice(0,4);
	var month  = ts.slice(5, 7) - 1;
	var day    = ts.slice(8, 10);
	var hour   = ts.slice(11,13);
	var minute = ts.slice(14, 16);
	var second = ts.slice(17, 19);
	
	var tsDate = new Date(
		year,
		month,
		day,
		hour,
		minute,
		second
	);
    //stops the execution if we were given invalid timestamp
    var stopThis = true;
    if(tsDate){
        if(!isNaN(tsDate.getTime())){
            stopThis = false;
        }
    }

    if(stopThis) return;
    var otherDate = new Date(tsDate.getTime() + 1000);
	
	var params = {};
	params["userId"] = $("hash_history_user_id").value;
	params["actionName"] = "searchDetails";
	params["from"] = tsDate.format();
	params["to"]  = otherDate.format();
	params["lastN"] = 1;

	UserHistoryFindAction.execute( params, function(response) { 
		var res = eval('(' + response.result + ')');
		
		createNewSearch(res.action.attributes);
	});
	
}

function initHashHistory() {
	if (application.isInternetExplorer  && application.isInternetExplorer6 == false) {
		var blank = document.createElement("iframe");
		blank.id = "ie_hash_workaround";
		blank.src = "/em/search/blank.html";
		blank.style.position = "absolute";
		blank.style.right = "0px";
		blank.style.border = "0px";
		blank.style.width = "0px";
		
		document.body.appendChild(blank);
	}
}
