/* some useful javascripts, many thanks to pkk (www.quirksmode.org) */


/* @return number with leading zeros 
 * @param radix base
 * @param pad char to fill up with
 * @param size total width of returned number
 */
function Number_toPaddedString(size, pad, radix)
{
	if (!pad) var pad = '0';
	if (!radix) var radix = 10;
	var str = this.toString(radix);

	if (size > str.length)
	{
		for (var i = str.length; i < size; ++i)
			str = pad + str;
	}
	return str;
}
Number.prototype.toPaddedString = Number_toPaddedString;

/* @return true if string is only blank/space charachters 
 */
function String_isSpace()
{
	for (var i = 0; i < this.length; ++i)
	{
		switch (this.charAt(i)) {
		case ' ':
		case '\n':
		case '\r':
		case '\240': /* Opera 8.5 &nbsp; */
		case '\t':
			continue;
		default:
			return false;
		}
	}
	return true;
}
String.prototype.isSpace = String_isSpace;

/* remove leading and trailing spaces */
function String_trim()
{
    var b = 0;
    var e = this.length;

    while (this.charAt(b).isSpace() && b < e)
	    ++b;
    
    while (this.charAt(--e).isSpace() && b < e)
	    ;
    
    return this.substring(b, e + 1);
}
String.prototype.trim = String_trim;


/* format a date like YYYY-MM-DD */
function Date_toSimpleString()
{
	return this.getFullYear() 
		+ '-' + (this.getMonth() + 1).toPaddedString(10,2)
		+ '-' + this.getDate().toPaddedString(10,2);
}

/* create the date 'x' days in the future */
function Date_dayIncrement(x)
{
	this.setDate(this.getDate() + x);
	return this;
}

/* create the date 'x' months in the future */
function Date_monthIncrement(x)
{
	this.setMonth(this.getMonth() + x);
	return this;
}

/* create the date 'x' years in the future */
function Date_yearIncrement(x)
{
	this.setFullYear(this.getFullYear() + x);
	return this;
}

/* extend the builtin Date() class */
Date.prototype.toSimpleString = Date_toSimpleString;
Date.prototype.dayIncrement = Date_dayIncrement;
Date.prototype.monthIncrement = Date_monthIncrement;
Date.prototype.yearIncrement = Date_yearIncrement;


/* originally from pkk www.quirksmode.org
 */
function getElementsByTagNames(list,obj)
{
	if (!obj) var obj = document;
	var tagNames = list.split(',');
	var resultArray = new Array();
	for (var i=0;i<tagNames.length;i++)
	{
		var tags = obj.getElementsByTagName(tagNames[i]);
		for (var j=0;j<tags.length;j++)
		{
			resultArray.push(tags[j]);
		}
	}
	return sourceOrder(resultArray);
}

/* sort elements according to order the appear in source
 * originally from pkk www.quirksmode.org
 */
function sourceOrder(objs)
{
	var testNode = objs[0];
	if (testNode.sourceIndex)
	{
		objs.sort(function (a,b) {
				return a.sourceIndex - b.sourceIndex;
		});
	}
	else if (testNode.compareDocumentPosition)
	{
		objs.sort(function (a,b) {
				return 3 - (a.compareDocumentPosition(b) & 6);
		});
	}
	return objs;
}

/* my own, inspired by pkk
 */
function getElementsByTagAndClassName(tag,name,root)
{
	var obj = root ? root : document;
	if (typeof(root) == 'string') obj = document.getElementById(root);
	if (!obj) return;

	var resultArray = new Array();
	var tags = obj.getElementsByTagName(tag);
	for (var i = 0; i < tags.length; i++)
	{
		if (tags[i].className == name)
			resultArray.push(tags[i]);
	}
	return sourceOrder(resultArray);
}

/* get all elements of specified class 
 * @param name class of elements to find
 * @param root consider only children of this element or element with this id
 * @return array with elements of class 'name' ordered by source
 */
function getElementsByClassName(name,root)
{
	return getElementsByTagAndClassName('*', name, root);
}

function toArray(obj)
{
	if (obj)
	{
		var resultArray = new Array();

		if (obj.length !== undefined)
		{
			for (var i = 0; i < obj.length; ++i)
			{
				resultArray.push(obj[i]);
			}
		}
		else {
			resultArray.push(obj);
		}
		return resultArray;
	}
	return null;
}

/*
Console for trace, errors etc
Array with better nodeList suppport
getElementsByClassNames()
*/

function menuSelect(e)
{
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();

	var href = this.getAttribute('href');

	var hrefParts = href.split('#');
	var id = hrefParts[1];

	for (var i = 0; i < window.chapters.length; ++i)
	{
		var t = window.chapters[i];
		var m = window.menuItems[i];

		if (t.id == id)
		{
			if (e.ctrlKey && t.style.display != 'none')
			{
				t.style.display = 'none';
				m.className = 'menu-item';
			}
			else {
				t.style.display = 'block';
				m.className = 'menu-item selected';
			}
		}
		else if (!e.ctrlKey) {
			t.style.display = 'none';
			m.className = 'menu-item';
		}
	}
	this.blur();
	return false; /* disable default action */
}

function menuShowAll()
{
	for (var i = 0; i < window.chapters.length; ++i)
	{
		var t = window.chapters[i];
		var m = window.menuItems[i];

		t.style.display = 'block';
		m.className = 'menu-item selected';
	}
	this.onclick = menuHideAll;
}

function menuHideAll()
{
	for (var i = 0; i < window.chapters.length; ++i)
	{
		var t = window.chapters[i];
		var m = window.menuItems[i];

		t.style.display = 'none';
		m.className = 'menu-item';
	}
	this.onclick = menuShowAll;
}

/* @return a html-linked email adress (<a>-tag)
 * @param str is a string consisting of name ';' email
 *  where 'name' is any string not including ';'
 *  and 'email' an email adress with all dots replaced by spaces
 *  and the 'at' char replaced by any string surrounded by parenteses and spaces
 *  like so: "Klas Arvidsson ; kma ( tomte nisse) home se"
 */
function createLinkedAdress(str) {
	if (str) {
		/* note: in Opera 8.5 &nbsp; is already replaced with char '\240' */
		var content = str.replace(/&nbsp;/gi, '\240').split(';');
		
		if (content.length > 1)
		{
			var name = content[0].trim();
			var email = content[1].trim();
		}
		else {
			var email = content[0].trim();
			var name = null;
		}

		email = email.replace(/\s/gi, '.');
		email = email.replace(/\.\(.*\)\./, '&#x40;');

		if (!name) name = email;

		return '<' + "a hr" + "ef=\"&#x6d;&#x61;&#10" 
			+ "5;&#108;&#x74;&#x6f;&#58;" 
			+ email + "\">" + name + "</a>";
	}
	return '';
}

window.onload = function js()
{
	var menu = document.getElementById('menu');
	window.menuItems = getElementsByClassName('menu-item',menu);
	window.chapters = getElementsByClassName('chapter');

	if (menuItems.length && chapters.length && menuItems.length === chapters.length)
	{
		for (var i = 0; i < menuItems.length; ++i)
		{
			menuItems[i].onclick = menuSelect;
/*			menuItems[i].onmouseup = menuSelect;*/
			chapters[i].style.display = 'none';
		}
		menuItems[0].className = 'menu-item selected';
		chapters[0].style.display = 'block';
		menu.title = "Prova klicka i menun med CTRL nedtryckt";
	}
	var t = document.getElementById('color');
	t.onclick = menuShowAll;
	t.title = "Klicka för att visa/dölja allt";

	var nospam = getElementsByTagAndClassName('span', 'nospam');
	for (var i = 0; i < nospam.length; ++i)
		nospam[i].innerHTML = createLinkedAdress(nospam[i].innerHTML);

    var anchors = document.getElementsByTagName("a");
    for (var i = 0; i < anchors.length; i++) {
        var anchor = anchors[i];
        if (anchor.getAttribute("href") &&
            anchor.getAttribute("rel") == "external")
            anchor.target = "_blank";
    }
    
	var info = document.getElementById('meta-info');
	var tech = document.getElementById('meta-tech');
	var desc = document.getElementById('meta-description');
	info.innerHTML = createLinkedAdress(info.innerHTML);
	tech.innerHTML = createLinkedAdress(tech.innerHTML);
	desc.innerHTML = createLinkedAdress(desc.innerHTML);
}

