/* JSLint directives. See: http://www.jslint.com */

/*global document, location, window */
/*global YAHOO */


// ---  HI namespace and settings  ---------------------------------------------

var HI;
if (!HI) {
	HI = {};
}

var MIN_Y_IN_PANEL = 125;
var MIN_PANEL_WIDTH = 120;
var MAX_PANEL_WIDTH = 550;
var PANEL_SPACER = 30;
var SCROLL_OFFSET = 100;


// ---  DOM  -------------------------------------------------------------------

/**
 * Returns an HTMLElement reference.
 * @param {String | HTMLElement |Array} el Accepts a string to use as an ID for getting a DOM reference, an actual DOM reference, or an Array of IDs and/or HTMLElements.
 * @return {HTMLElement | Array} A DOM reference to an HTML element or an array of HTMLElements.
 */
HI.get = function (element) {
	return YAHOO.util.Dom.get(element);
};

HI.setElementDisplay = function (className, style) {
	var elements = YAHOO.util.Dom.getElementsByClassName(className, "span");
	for (var i = 0; i < elements.length; i++) {
		elements[i].style.display = style;
	}
};

HI.setXRelative = function (element, refElement, offset) {
	var x = YAHOO.util.Dom.getX(refElement);
	YAHOO.util.Dom.setX(element, x + offset);
};

HI.setYRelative = function (element, refElement, offset) {
	var y = YAHOO.util.Dom.getY(refElement);
	if (!y) {
		y = MIN_Y_IN_PANEL;
	}
	YAHOO.util.Dom.setY(element, y + offset);
};


// ---  Events  ----------------------------------------------------------------

HI.addInitializer = function (name) {
	YAHOO.util.Event.addListener(window, "load", name);
};


// -----------------------------------------------------------------------------

HI.callIfDefined = function (functionToCall) {
	if (functionToCall) {
		functionToCall();
	}
};

HI.booleanState = function (name) {
	var getCookie = function () {
		return YAHOO.util.Cookie.get(name);
	};
	var setCookie = function (value) {
		YAHOO.util.Cookie.set(name, value, { path: "/" });
	};
	return function (toggle) {
		var value = getCookie();
		if (!value) {
			value = "0";
			setCookie(value);
		}
		if (toggle) {
			value = (value === "1") ? "0" : "1";
			setCookie(value);
		}
		return (value === "1");
	};
};

HI.createState = function (items) {
	var allItems = items;
	var curItems = items;
	return {
		setAll : function () {
			curItems = allItems;
		},
		setNone : function () {
			curItems = "";
		},
		isMember : function (item) {
			return (item === curItems) || (curItems.search("\\b" + item + "\\b") !== -1);
		},
		addMember : function (item) {
			if (!this.isMember(item)) {
				curItems += " " + item;
			}
		},
		delMember : function (item) {
			curItems = curItems.replace(new RegExp("\\b" + item + "\\b\\s*", "g"), "");
		}
	};
};


// -----------------------------------------------------------------------------

// function used by Martianus project - must be present
function goAnchor(d) {
  window.location = d; 
  window.scrollBy(0, -SCROLL_OFFSET);
}

HI.printPage = function () {
	window.print();
};

HI.updatePagebreaks = function (visible) {
  var style = visible ? "inline" : "none";
  HI.setElementDisplay("page_nr_ctl", style);
};

function popUpAn(refElement, divId, atype) {
  if (typeof atype == 'undefined' ) atype = 'A';
	var div = '';
	if (atype == 'A') {
	 	div = document.getElementById('popupWindow');
		divBody = document.getElementById('popupBody');
		}
	else if (atype == 'PG') {
	 	div = document.getElementById('popupWindowPG');
		divBody = document.getElementById('popupBodyPG');
		}
	else if (atype == 'W') {
	 	div = document.getElementById('popupWindowW');
		divBody = document.getElementById('popupBodyW');
		}
	else if (atype == 'T') {
	 	div = document.getElementById('popupWindowT');
		divBody = document.getElementById('popupBodyT');
		}

	// if the style.display value is blank we try to check it out here 
	if (div.style.display == '' && div.offsetWidth != undefined && div.offsetHeight != undefined) {
		div.style.display = (div.offsetWidth != 0 && div.offsetHeight != 0) ? 'block' : 'none';
	}

	// If the PopUp is hidden ('none') then it will display it ('block').
	// If the PopUp is displayed ('block') then it will hide it ('none').
	divBody.innerHTML = document.getElementById(divId).innerHTML;
	div.style.display = (div.style.display == '' || div.style.display == 'block') ? 'none' : 'block';

	//HI.setXRelative(div, refElement, +20);
	//HI.setYRelative(div, refElement, -15);

	HI.setXRelative(div, refElement, +20);
	HI.setYRelative(div, refElement, -100);
}

 HI.showAnchoredVariation = function () {
	if (HI.vars) {
		var data = HI.panelDataExists("variation_panel");
		if (data) {
			var target = data["target"];
			if (target) {
				var element = HI.get(target);
				if (element) {
					HI.updateVariations(true);
					HI.vars.toggle(target.replace("vl-", "vd-"), element);
					window.scroll(0, YAHOO.util.Dom.getY(element) - SCROLL_OFFSET);
				}
			}
		}
	}
};

HI.showAnchoredNote = function () {
	if (HI.notes) {
		var data = HI.panelDataExists(NOTE_PANEL);
		if (data) {
			var target = data["target"];
			if (target) {
				var element = HI.get(target);
				if (element) {
					HI.showAllNotes();
					HI.notes.toggle(target.replace("nl-", "nd-"), element);
					window.scroll(0, YAHOO.util.Dom.getY(element) - SCROLL_OFFSET);
				}
			}
		}
	}
};


// ---  Panels  ----------------------------------------------------------------

var NAVIGATION_PANEL = "navigation_panel";
var NOTE_PANEL = "note_panel";
var PICTURE_PANEL = "picture_panel";
var READING_PANEL = "reading_panel";
var SEARCH_PANEL = "search_panel";

// DOM element to get panels from
HI.panelSource = null;
// DOM element to add panels to
HI.panelTarget = null;

// TODO add more functionality
HI.panels = {
	dom: YAHOO.util.Dom,
	getElements: function (className, tag) {
		return this.dom.getElementsByClassName(className, tag, HI.panelTarget);
	}
};


// -----------------------------------------------------------------------------

HI.showFacsimile = function (name, facsLink) {
	if (HI.isActivePanel(PICTURE_PANEL)) {
		HI.picts.load(name, facsLink);
	} else {
		HI.picts.active = name;
		// insert picture panel before reading panel
		var index = HI.findActivePanel(READING_PANEL);
		activePanels.splice(index, 0, PICTURE_PANEL);
		HI.panelPrefs.show(PICTURE_PANEL);
		HI.createPanels();
		window.scroll(0, YAHOO.util.Dom.getY("facs-" + name) - SCROLL_OFFSET);
	}
};

// FacsLink element: <img src="..." class="facsLink" pict="M001" onClick="..."/>
HI.showFirstFacsimile = function () {
	if (HI.isActivePanel(PICTURE_PANEL) && HI.isActivePanel(READING_PANEL)) {
		var facsLink = HI.findFacsLink(HI.picts.active);
		if (facsLink) {
			HI.showFacsimile(facsLink.getAttribute("pict"), facsLink);
		}
	}
};


// ---  BUILD the gui  ---------------------------------------------------------

// id's of visible panels
var activePanels = [];

HI.findActivePanel = function (name) {
	for (var i = 0; i < activePanels.length; i++) {
		if (activePanels[i] === name) return i;
	}
	return -1;
};

HI.isActivePanel = function (name) {
	return (HI.findActivePanel(name) >= 0);
};

// panel data - initialized in HI.loadNewGUI
var panelData = [];

HI.panelDataExists = function (name) {
	for (var i = 0; i < panelData.length; i++) {
		if (panelData[i].id === name) return panelData[i];
	}
	return null;
};

var panelWeight = {
	annotation_panel: 3,
	compare_panel: 6,
	facsimile_panel: 3,
	inline_variant_panel: 3,
	letter_panel: 3,
	navigation_panel: 3,
	note_panel: 2,
	picture_panel: 3,
	reading_panel: 3,
	search_panel: 3,
	text_panel: 3,
	transcription_panel: 3,
	variation_panel: 2
};

var getPanelWeight = function (id) {
	return panelWeight[id];
};

// set variables
var DDhandlers = ["col1", "col2", "col3", "col4"];

HI.panelPrefs = function () {
	var counts = {};
	var prefs = YAHOO.util.Cookie.get("panelprefs");
	prefs = (prefs) ? YAHOO.lang.JSON.parse(prefs) : { visible: {}, width: {} };
	function writePrefs() {
		var data = YAHOO.lang.JSON.stringify(prefs);
		YAHOO.util.Cookie.set("panelprefs", data, { path: "/" });
		// alert(data);
	}
	return {
		init : function (id) {
			counts[id] = 1;
		},
		show : function (id) {
			counts[id] = counts[id] ? counts[id] + 1 : 1;
			if (counts[id] === 1) {
				prefs.visible[id] = "show";
				writePrefs();
			}
		},
		hide : function (id) {
			counts[id] = counts[id] ? counts[id] - 1 : 0;
			if (counts[id] === 0) {
				prefs.visible[id] = "hide";
				writePrefs();
			}
		},
		visible: function (id) {
			return prefs.visible[id];
		},
		setWidth: function (id, value) {
			prefs.width[id] = value;
			writePrefs();
		},
		getWidth: function (id) {
			return prefs.width[id];
		}
	};
}();

HI.buildPanelDivs = function (nPanels) {
	var html = '';
	for (var i = 0; i < nPanels; i++) {
		html += '<div id="col' + (i + 1) + '" class="panel"></div>';
		html += '<div id="handel' + (i + 1) + '" class="slider"></div>';
	}
	// put de HTML in the placeholder
	HI.panelTarget.innerHTML = html;
};

HI.setPanelProperties = function () {
	var i, left, unitWidth, weight, weightSum, width, widths;
	var totalWidth = YAHOO.util.Dom.getViewportWidth();
	var n = activePanels.length;

	widths = [];
	weightSum = 0;
	for (i = 0; i < n; i++) {
		width = HI.panelPrefs.getWidth(activePanels[i]);
		if (width) {
			widths[i] = width;
			totalWidth -= width;
		} else {
			weightSum += getPanelWeight(activePanels[i]);
		}
	}

	if (weightSum !== 0) {
		// Divide remaining width over panels without a preferred width
		unitWidth = Math.floor( (totalWidth - n * PANEL_SPACER - 25) / weightSum );
		for (i = 0; i < n; i++) {
			if (!widths[i]) {
				weight = getPanelWeight(activePanels[i]);
				widths[i] = HI.normalizeWidth(weight * unitWidth);
			}
		}
	}

	left = 0;
	for (i = 0; i < n; i++) {
		width = widths[i];
		YAHOO.util.Dom.setStyle('col'+(i+1), 'width', width + 'px');
		YAHOO.util.Dom.setStyle('col'+(i+1), 'left', left + 'px');
		YAHOO.util.Dom.setStyle('handel'+(i+1), 'left', (left + width) + 'px');
		left += width + PANEL_SPACER;
	}
};

HI.normalizeWidth = function (width) {
	if (width < MIN_PANEL_WIDTH)
    return MIN_PANEL_WIDTH;
  else if (width > MAX_PANEL_WIDTH) return MAX_PANEL_WIDTH;
  else
    return width;
};

HI.setSliderBehaviour = function () {
	var zIndx = 101;
	for (var i = 0; i < activePanels.length; i++) {
		DDhandlers[i] = new YAHOO.util.DD('handel' + (i+1));
		DDhandlers[i].setYConstraint(0, 0); // no vertical movement

		// while drag
		DDhandlers[i].on('dragEvent', function (ev) {
			zIndx = zIndx + 1;
			var dom = YAHOO.util.Dom;
			var curr = this.id.replace('handel', '');
			var width = dom.getX('handel' + curr) - dom.getX('col' + curr) - 10;
			dom.setStyle('col' + curr, 'width', width + 'px');
			dom.setStyle('col' + curr, 'z-index', zIndx);	
		
		}, DDhandlers[i], true);

		// on release
		DDhandlers[i].on('mouseUpEvent', function (ev) {
			var dom = YAHOO.util.Dom;
			var curr = this.id.replace('handel', '');
			for (var j = parseFloat(curr); j < activePanels.length; j++) {
				var prevPos = parseFloat(dom.getStyle('handel' + (j), 'left'));
				var prevWidth = parseFloat(dom.getStyle('col' + (j+1), 'width'));
				dom.setStyle('col' + (j+1), 'left', (prevPos + PANEL_SPACER) + 'px');
				dom.setStyle('handel' + (j+1), 'left', (prevPos + prevWidth + PANEL_SPACER) + 'px');
				dom.setStyle('col' + (j+1), 'z-index', 100);
				zIndx = 101;
			}
			// Make panel width the preferred value
			j = parseInt(curr, 10);
			var value = parseFloat(dom.getStyle('col' + j, 'width'));
			HI.panelPrefs.setWidth(activePanels[j - 1], value);
		}, DDhandlers[i], true);
	}
};

HI.loadPanelContent = function () {
	for (var i = 0; i < activePanels.length; i++) {
		panelContent('col' + (i + 1), activePanels[i]);
	}
};

//set the height of the panels
HI.setPanelHeight = function () {
	var m, panelheightCur;
	var panelheightTop = 0;
	for (m = 0; m < activePanels.length; m++) {
		panelheightCur = YAHOO.util.Dom.getStyle('innerPanel'+(m+1), 'height');
		
		//alert("offsetHeight: " + document.getElementById( 'innerPanel'+(m+1) ).offsetHeight);
		//alert("clientHeight: " + document.getElementById( 'innerPanel'+(m+1) ).clientHeight);
		
		
		if (panelheightCur == false) {
			panelheightCur = 4000;
		} else if (panelheightCur == 'auto') {
			panelheightCur = document.getElementById( 'innerPanel'+(m+1) ).offsetHeight;
		} else {
			panelheightCur = parseFloat(panelheightCur.replace('px',''));
		}
		if (panelheightCur > panelheightTop) {
			panelheightTop = panelheightCur;
		}
	}

	var viewportHeight = YAHOO.util.Dom.getViewportHeight();
	if (panelheightTop < viewportHeight) {
		panelheightTop = viewportHeight - 110;
	}

	panelheightTop = panelheightTop + 'px';
	for (m = 0; m < activePanels.length; m++) {
		YAHOO.util.Dom.setStyle('col' + (m + 1), 'height', panelheightTop);
	}
};

HI.createPanels = function () {
	HI.buildPanelDivs(activePanels.length); 
	HI.setPanelProperties(); 
	HI.setSliderBehaviour(); 
	HI.loadPanelContent();
	// TODO: generalize to all actions when panels have been initailized
	HI.showFirstFacsimile();
	HI.showAnchoredVariation();
	HI.showAnchoredNote();
};

HI.loadNewGUI = function () {
	HI.panelSource = HI.get("panelSource");
	if (!HI.panelSource) throw new Error("Missing element 'panelSource' in HTML");
	HI.panelTarget = HI.get("panelTarget");
	if (!HI.panelTarget) throw new Error("Missing element 'panelTarget' in HTML");

	panelData = YAHOO.lang.JSON.parse(HI.panelDef);
	for (var i = 0; i < panelData.length; i++) {
		var id = panelData[i].id;
		if (panelData[i].init === "show" && HI.panelPrefs.visible(id) !== "hide") {
			activePanels.push(id);
			HI.panelPrefs.init(id);
		}
		if (panelData[i].init === "hide" && HI.panelPrefs.visible(id) === "show") {
			activePanels.push(id);
			HI.panelPrefs.init(id);
		}
	}
	HI.createPanels();
};

// create listbox to select panelcontent
function panelSelector(tllr){
var browser=navigator.appName;
if (browser=='Microsoft Internet Explorer') {
	
	var html = '<select class="selectpopIE" onchange="newPanelContent(\'col' + tllr + '\', this.value);"';
	html += '<option>Change panel</option>';

	for (var i = 0; i < panelData.length; i++) {
		html += '<option value="' + panelData[i].id + '">' + panelData[i].name + '</option>';
	}
	html += '</select>';
	return html;
	}

	else {
	var html = '<span id="headerSelect'+ tllr +'" class="panelSelectLink" onmouseover="showPanelPopup('+ tllr + ', \'v\')" onmouseout="showPanelPopup('+ tllr + ', \'h\')">Change panel</span>';
	html += '<div id="selectpop' + tllr + '" style="display:none;" class="panelSelectPopup" onmouseover="showPanelPopup('+ tllr + ', \'v\')" onmouseout="showPanelPopup('+ tllr + ', \'h\')">';
	for (var i = 0; i < panelData.length; i++) {
		html += '<a href="#" onClick="newPanelContent(\'col' + tllr + '\',\'' + panelData[i].id + '\')">' + panelData[i].name + '</a><br/>';
	}
	html += '</div>';
	return html;
		
		}



}



function showPanelPopup(id, action) {

if (action == 'v') {
		YAHOO.util.Dom.setStyle('selectpop' + id , 'display', 'block');
		var pos = YAHOO.util.Dom.getX('headerSelect'+id); 
		YAHOO.util.Dom.setX('selectpop' + id, pos);


	}
	if (action == 'h') {
		YAHOO.util.Dom.setStyle('selectpop' + id , 'display', 'none');
	}
}

function newPanelContent(id, from) {
	var idx = parseFloat(id.replace('col', '')) - 1;
	HI.panelPrefs.hide(activePanels[idx]);
	HI.panelPrefs.show(from);
	panelContent(id, from);
}

function panelContent(id, from) {	

	var contentHtml = document.getElementById(from).innerHTML;
	if (contentHtml == '' || contentHtml == '<wicket:panel>\n</wicket:panel>') {
		// if panel is empty, get content from last content panel
		var last = activePanels.length - 1;
		contentHtml = document.getElementById(activePanels[last]).innerHTML;
	}

	id = id.replace('col', '');
	var contentHeader = '<div class="headerSelector">' + panelSelector(id)+ '<img src="/web/skins/images/b_close_panel.png" class="closepanel" onclick="panelManager(\'del\', ' + id + ');"></div>';
	var contentVar = '<div id="innerPanel'+ id + '" class="innerPanel">' + contentHeader + contentHtml + '</div>';
	
	document.getElementById('col'+id).innerHTML = contentVar;
	activePanels[(parseFloat(id)-1)] = from;
	HI.setPanelHeight();

	// TODO find a better solution, works only for one facsimile panel
	if (HI.floatDiv && from === "facsimile_panel") {
		HI.floatDiv("floatFacs", 0, 60).floatIt();
	}

	var initializer = HI["init_" + from];
	if (typeof initializer === "function") {
		initializer();
	}
}

// Manage the adding and deleting of the panels
function panelManager(action, col) {
	var id, index, last = activePanels.length - 1;
	if (action === "add") {
		id = activePanels[last];
		activePanels.push(id);
		HI.panelPrefs.show(id);
	} else if (action === "del" && last > 0) {
		index = (typeof col === "number") ? (col - 1) : last;
		id = activePanels[index];
		if (id) {
			activePanels.splice(index, 1);
			HI.panelPrefs.hide(id);
		}
	}
	HI.createPanels();
}

HI.swapPanels = function (panelToShow, panelToHide) {
	if (HI.panelDataExists(panelToShow) && HI.findActivePanel(panelToShow) < 0) {
		// panel exists and is not yet visible
		var index = HI.findActivePanel(panelToHide);
		if (index >= 0) {
			// replace panel
			activePanels[index] = panelToShow;
			HI.panelPrefs.hide(panelToHide);
		} else {
			// add panel on the left
			activePanels.splice(0, 0, panelToShow);
		}
		HI.panelPrefs.show(panelToShow);
		HI.createPanels();
	}
};

HI.showNavigationPanel = function () {
	HI.swapPanels(NAVIGATION_PANEL, SEARCH_PANEL);
};

HI.showSearchPanel = function () {
	HI.swapPanels(SEARCH_PANEL, NAVIGATION_PANEL);
};

HI.initOptionsPanel = function () {
	HI.optionsPanel = new YAHOO.widget.Panel("elaborate_options", { 
		width: "600px",
		height: "440px",
		fixedcenter: true,
		visible: false,
		constraintoviewport: true
	});
	HI.optionsPanel.render();

	var tabView = new YAHOO.widget.TabView('elaborate_options_body');
	var tabs = YAHOO.lang.JSON.parse(HI.optionTabs);
	if (tabs) {
		for (var i = 0; i < tabs.length; i++) {
			var tab = new YAHOO.widget.Tab({
				labelEl: HI.get(tabs[i] + "_label"),
				contentEl: HI.get(tabs[i] + "_content")
			});
			tabView.addTab(tab);
		}
	}
};

HI.alignedItems = function () {
	var visible = "";
	return {
		show: function (id, refElement) {
			var obj = HI.get(id);
			if (obj) {
				obj.style.display = "block";
				HI.setYRelative(obj, refElement, 0);
			}
			visible = id;
		},
		hide: function (id) {
			if (visible) {
				id = id || visible;
				var obj = HI.get(id);
				if (obj) {
					obj.style.display = "none";
				}
				visible = "";
			}
		},
		toggle: function (id, refElement) {
			if (id === visible) {
				this.hide(id);
			} else {
				this.hide(visible);
				this.show(id, refElement);
			}
		}
	};
};

// ---  event handlers  --------------------------------------------------------

HI.onLoad = function () {
	if (HI.panelDef) {
		HI.loadNewGUI();
	}
	HI.initOptionsPanel();
};

HI.onResize = function () {
	if (HI.panelDef) {
		HI.createPanels();
	}
};
