//
// MoinMoin commonly used JavaScript functions
//

// use this instead of assigning to window.onload directly:
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

function can_use_gui_editor() {
    var sAgent = navigator.userAgent.toLowerCase();
 
    if (sAgent.indexOf("msie") != -1 && sAgent.indexOf("mac") == -1 &&
        sAgent.indexOf("opera") == -1 ) {
        // Internet Explorer
        var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1];
        return ( sBrowserVersion >= 5.5 );
    } else if (navigator.product == "Gecko" && 
               navigator.productSub >= 20030210) {
        // Gecko
        return true;
    }
    // else if (sAgent.indexOf("safari") != -1 ) {
    //    // Safari - build must be at least 312 (1.3)
    //    return (sAgent.match( /safari\/(\d+)/ )[1] >= 312 );
    // } 
    else {
        // Unknown browser, assume gui editor is not compatible
        return false;
    }
}


function update_edit_links() {
    // Update editlink according if if the browser is compatible
    if (can_use_gui_editor() == false) return;

    var editlinks = document.getElementsByName("editlink");
    for (i = 0; i < editlinks.length; i++) {
        var link = editlinks[i];
        href = link.href.replace('editor=textonly','editor=guipossible');
        link.href = href;
    }
}


function add_gui_editor_links() {
    // Add gui editor link after the text editor link
    
    // If the variable is not set or browser is not compatible, exit
    try {gui_editor_link_href} catch (e) {return}
    if (can_use_gui_editor() == false) return;
    
    var all = document.getElementsByName('texteditlink');
    for (i = 0; i < all.length; i++) {
        var textEditorLink = all[i];
        // Create a list item with a link
        var guiEditorLink = document.createElement('a');
        guiEditorLink.href = gui_editor_link_href;
        var text = document.createTextNode(gui_editor_link_text);
        guiEditorLink.appendChild(text);
        var listItem = document.createElement('li')
        listItem.appendChild(guiEditorLink);
        // Insert in the editbar
        var editbar = textEditorLink.parentNode.parentNode
        var nextListItem = textEditorLink.parentNode.nextSibling;
        editbar.insertBefore(listItem, nextListItem);
    }
}
  

function show_switch2gui() {
    // Show switch to gui editor link if the browser is compatible
    if (can_use_gui_editor() == false) return;
    
    var switch2gui = document.getElementById('switch2gui')
    if (switch2gui) {
        switch2gui.style.display = 'inline';
    }
}


function load() {
    // Do not name this "onload", it does not work with IE :-)
    // TODO: create separate onload for each type of view and set the
    // correct function name in the html. 
    // e.g <body onlod='editor_onload()'>
    
    // Page view stuff
    update_edit_links();
    add_gui_editor_links();
    
    // Editor stuff
    show_switch2gui();
}


function before_unload(evt) {
    // TODO: Better to set this in the editor html, as it does not make
    // sense elsehwere.
    // confirmleaving is available when editing
    try {return confirmleaving();}
    catch (e) {}
}

// Initialize after loading the page
addLoadEvent(load)

// Catch before unloading the page
window.onbeforeunload = before_unload











/*  Prototype JavaScript framework
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://prototype.conio.net/
/*--------------------------------------------------------------------------*/

//note: modified & stripped down version of prototype, to be used with moo.fx by mad4milk (http://moofx.mad4milk.net).

var Class = {
	create: function() {
		return function() {
			this.initialize.apply(this, arguments);
		}
	}
}

Object.extend = function(destination, source) {
	for (property in source) destination[property] = source[property];
	return destination;
}

Function.prototype.bind = function(object) {
	var __method = this;
	return function() {
		return __method.apply(object, arguments);
	}
}

Function.prototype.bindAsEventListener = function(object) {
var __method = this;
	return function(event) {
		__method.call(object, event || window.event);
	}
}

function $() {
	if (arguments.length == 1) return get$(arguments[0]);
	var elements = [];
	$c(arguments).each(function(el){
		elements.push(get$(el));
	});
	return elements;

	function get$(el){
		if (typeof el == 'string') el = document.getElementById(el);
		return el;
	}
}

if (!window.Element) var Element = new Object();

Object.extend(Element, {
	remove: function(element) {
		element = $(element);
		element.parentNode.removeChild(element);
	},

	hasClassName: function(element, className) {
		element = $(element);
		if (!element) return;
		var hasClass = false;
		element.className.split(' ').each(function(cn){
			if (cn == className) hasClass = true;
		});
		return hasClass;
	},

	addClassName: function(element, className) {
		element = $(element);
		Element.removeClassName(element, className);
		element.className += ' ' + className;
	},
  
	removeClassName: function(element, className) {
		element = $(element);
		if (!element) return;
		var newClassName = '';
		element.className.split(' ').each(function(cn, i){
			if (cn != className){
				if (i > 0) newClassName += ' ';
				newClassName += cn;
			}
		});
		element.className = newClassName;
	},

	cleanWhitespace: function(element) {
		element = $(element);
		$c(element.childNodes).each(function(node){
			if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) Element.remove(node);
		});
	},

	find: function(element, what) {
		element = $(element)[what];
		while (element.nodeType != 1) element = element[what];
		return element;
	}
});

var Position = {
	cumulativeOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
		} while (element);
		return [valueL, valueT];
	}
};

document.getElementsByClassName = function(className) {
	var children = document.getElementsByTagName('*') || document.all;
	var elements = [];
	$c(children).each(function(child){
		if (Element.hasClassName(child, className)) elements.push(child);
	});  
	return elements;
}

//useful array functions
Array.prototype.iterate = function(func){
	for(var i=0;i<this.length;i++) func(this[i], i);
}
if (!Array.prototype.each) Array.prototype.each = Array.prototype.iterate;

function $c(array){
	var nArray = [];
	for (var i=0;i<array.length;i++) nArray.push(array[i]);
	return nArray;
}


/*  Starry Set Form Widget
 *  (c) 2006 Chris Iufer <chris@duarte.com>
 *  Starry is freely distributable under the terms of an MIT-style license.
 *  See the Duarte Design web site: http://www.duarte.com/portfolio/
/*--------------------------------------------------------------------------*/
var debug = false;

var StarryDefaults = {
		sprite: "stars.gif",
		width: 13,
		height: 11,
		startAt: 0,
		maxLength: 5,
		multiplier: 1,
		showNull: false,
		align: 'left',
		feedback: true,
                labels: ['unrated (click starts to rate)',
                         '1: I hate it',
                         '2: I don\'t like it',
                         '3: It\'s OK',
                         '4: I like it',
                         '5: I love it'
                        ],
		sprite:'/wiki/common/stars.gif'
};

// The Starry Class
// new Starry('id_of_element'[, {options}]);
// This is the main starry widget. Create new widgets after window load
var Starry = Class.create();
Starry.prototype = {
	initialize: function(element) {
		this.element = $(element);
		this.form = $(element + "-form");
		this.element.className = "starry";
		this.options = {};
		// get our defaults
		Object.extend(this.options, StarryDefaults);
		Object.extend(this.options, arguments[1] || {});
		this.name = element;//this.options.name || "starry" + id.next();
		if(debug) console.log(this.options.showNull);
		// lets build our array with an extra one for null
		this.children = new Array(this.options.maxLength + 1);
		if(debug) console.log('children length '+ this.children.length);
		// lets make the hidden form value
		this.hidden = document.createElement("input");
		this.hidden.type = "hidden";
		this.hidden.name = "vote"; //this.name;
		this.element.appendChild(this.hidden);
		// build out each child
		for(i=0; i < this.children.length; i++) {
			this.children[i] = new SingleStar(this, i);
			this.element.appendChild(this.children[i].element);
		}
		if( this.options.feedback ) {
			this.feedback = document.createElement('div');
			this.feedback.className = "feedback";
			this.feedback.style.cssFloat = this.options.align;
			// this.feedback.style.display = 'block';
			this.element.appendChild(this.feedback);
		}
		// startup
		this.selected = this.options.startAt;
		this.reset(this.selected);
	},
	set: function(index) {
		if(debug) console.log('set index '+ index);
		// set the child
		for(var i=1; i < this.children.length; i++)
			this.children[i].element.style.backgroundPosition = (i <= index) ? "0 -" + this.options.height * 2 + "px" : "0 0";
		if(this.options.feedback)
			this.feedback.innerHTML =
                            this.options.labels[this.children[index].value];
		this.selected = index;
		// set the form value
		this.hidden.value = this.children[index].value;
		if(debug) console.log('set value ' + this.hidden.value);
	},
	show: function(index) {
		if(debug) console.log('show index '+ index);
		// show the child
		for(var i=1; i < this.children.length; i++)
			this.children[i].element.style.backgroundPosition = (i <= index) ? "0 -" + this.options.height + "px" : "0 0";
		if(this.options.feedback)
			this.feedback.innerHTML =
                            this.options.labels[this.children[index].value];
	},
	reset: function() { this.set(this.selected); },
	clear: function() {
		for(var i=1; i < this.children.length; i++)
			this.children[i].element.style.backgroundPosition = "0 0";
	}
};

// Class: SingleStar(parent_object, index of that parent's children)
// Not to be called directly, inherits its options from a Starry object
var SingleStar = Class.create();
SingleStar.prototype = {
	initialize: function(parent, index) {
		this.parent = parent;
		this.index = index;
		if(debug) console.log('Creating star at index '+ this.index);
		this.value = this.index * this.parent.options.multiplier;
		if(debug) console.log('value '+ this.value);
		this.element = document.createElement("div");
		this.element.style.width = this.parent.options.width + "px";
		this.element.style.height = this.parent.options.height + "px";
		this.element.style.backgroundImage = "url(" + this.parent.options.sprite + ")";
		this.element.style.backgroundPosition = (this.index == 0) ? "0 -" + this.parent.options.height * 3  +"px" : "0 0";
		this.element.className = "standard_star";
		this.element.style.cssFloat = this.parent.options.align;
		// this.element.style.display = 'block';
		if(!this.parent.options.showNull && this.index == 0) this.element.style.display = "none";
		this.element.onclick = function() { this.parent.set(this.index); this.parent.form.submit(); }.bind(this);
		this.element.onmouseover = function() { this.parent.show(this.index); }.bind(this);
		this.element.onmouseout = this.parent.reset.bind(this.parent);
		if(debug) console.log('set onclick handler');
	}
};

// this function manages an auto_increment for id's
var id = { start: 0, prev: 0, next: function() { return this.start + this.prev++; } };
