//start with "classes"


var Tooltip = { // verkar inte funka helt ju

	/* A simple class for showing tooltips. The tooltip-text
	 * should be placed in an attribute "tooltip" in the tag
	 * that is to be tooltipped. The tooltip is automatically
	 * showed for 800 milliseconds but by using changeDuration
	 * you can alter that time.
	 */

	show: function(e) {

		return;

		e = e || window.event;
		if(!this._check(e)) return;

		var targetElement = getTarget(e);

		if(!targetElement.tooltipFlag) { //tooltip is present

			targetElement.tooltipFlag = true;

			var tooltip = id("tooltip");

			if(!tooltip) { //append if first time
				tooltip = document.createElement("div");
				tooltip.id = "tooltip";
				document.body.appendChild(tooltip);
			}

			tooltip.innerHTML = targetElement.tooltipText;
			tooltip.style.width = ""; //otherwise a small tooltip will be 200px if a big one precedes

			var that = this;

			addEvent(targetElement, "mouseout", function() { that._hide(targetElement); });
			addEvent(targetElement, "mousedown", function() { that._hide(targetElement); });
			addEvent(targetElement, "mousemove", function() { that._getUpdatedPosition(e); });

			this._timer = setTimeout(function() { that._showAfterWait(targetElement); }, this._duration);
		}
	},

	changeDuration: function(duration) {
		if(!duration || isNaN(duration)) return;
		this._duration = duration;
	},


	//private functions and stuff. not to be touched or used.


	_duration: 800,
	_timer: null,

	_getUpdatedPosition: function(e) {

		e = e||window.event;

		var tooltip = id("tooltip");
		tooltip.style.left = e.clientX + 15 + "px";
		tooltip.style.top = e.clientY + 5 + "px";
	},

	_check: function(e) {

		e = e || window.event;
		var targetElement = e.target||e.srcElement;
		var text;

		if(text = targetElement.getAttribute("tooltip")) {
			targetElement.tooltipText = text;
			return true;
		} else return false;
	},

	_hide: function(targetElement) {

		targetElement.tooltipFlag = false;
		//targetElement.onmousemove = null;

		id("tooltip").style.display = 'none';
		clearTimeout(this._timer);
	},

	_showAfterWait: function(targetElement) {

		if(currentStyle(targetElement, "display") == "none") return;

		var tooltip = id("tooltip");
		var that = this;

		clearTimeout(this._timer);
		removeEvent(targetElement, function() { that._getUpdatedPosition(e); });

		tooltip.style.display = 'block';
		if(currentStyle(tooltip, "width") > 200) tooltip.style.width = "200px";
	}
}

var Slider = {

	/* A simple class to handle and create a slider.
	 * The slider needs some html-nodes to work, first
	 * it needs some container that is positioned in some
	 * way and has the class "slider", then it needs a bar 
	 * that has to have the class "slider_bar", it also needs
	 * a lever that has to have the class "slider_lever".
	 * a div that has the class "slider_center" is optional
	 */

	init: function(obj, onDrag, onMouseDown, onMouseUp) { //initiates events and stuff. needs to be passed a function that handles the position-info

		obj = id(obj);
		if(!obj || !onDrag) return false;

		if(!obj._initiatedslider) {

			obj._dragfunc = onDrag;

			var that = this;

			var lever = elementsByClassName("slider_lever", "div", obj, true);
			if(!lever || !hasChildNode(obj, ".slider_bar")) throw new Error("Seems the slider " + obj.id + " is missing some html-nodes.");

			//some events, unobtrusive is the shit, sometimes... sort of

			if(onMouseUp && typeof onMouseUp == "function") var mouseUp = function(e) { //put this in a variable so we easily can untie the event
			
				onMouseUp(e, that._computeposition(obj, lever.offsetLeft));
				removeEvent(document, "mouseup", mouseUp); //remove dragging-events tied to the document
			};
			
			if(onMouseDown && typeof onMouseDown == "function") var mouseDown = function(e) {
			
				onMouseDown(e, that._computeposition(obj, lever.offsetLeft));
			}

			addEvent(lever, "mousedown", function(e) {

				if(mouseUp) addEvent(document, "mouseup", mouseUp);
				if(mouseDown) mouseDown(e);
				
				that._drag(e, obj);
			});

			addEvent(obj, "mousedown", function(e) { // this handles if someone clicks on the bar

				e = e || window.event;

				if(getTarget(e) === lever) return;
				
				if(!obj._initinnerslider) that._initinner(obj); //must have everything initiated by now

				if(mouseUp) addEvent(document, "mouseup", mouseUp);
				if(mouseDown) mouseDown(e);

				that._mover(e, obj, lever, e.clientX - currentStyle(obj, "left") - obj._leverWidthS2);
			});

			obj._initiatedslider = true;
		}
	},

	show: function(obj) { //just does what you would expect

		obj = id(obj);
		if(!obj || !obj._initiatedslider) return;

		showLayer(obj);
		
		var dragger = getChildNodes(obj, ".slider_lever", "div", true);
		
		var position = dragger.offsetLeft;
	},

	hide: function(obj) { //likewise

		obj = id(obj);
		if(!obj || !obj._initiatedslider) return;

		hideLayer(obj);
	},

	toggle: function(obj) { //hides if visible and shows if not visible

		obj = id(obj);
		if(!obj || !obj._initiatedslider) return;

		if(currentStyle(obj, "display") != "block") {
			this.show(obj);
			return 1;
		} else {
			this.hide(obj);
			return 0;
		}
	},

	setPosition: function(obj, position) {

		obj = id(obj);
		if(!obj || position === undefined) return;

		if(!obj._initinnerslider) this._initinner(obj);

		var lever = getChildNodes(obj, ".slider_lever", "div", true);

		var realPosition = obj._hascenter ? obj._centerposition + position : position;

		this._mover(false, obj, lever, realPosition - Math.floor(currentStyle(lever, "width")/2));
	},

	getPosition: function(obj) {

		obj = id(obj);
		if(!obj) return;

		return this._computeposition(obj);
	},

	getX: function(obj) {

		obj = id(obj);
		if(!obj) return;

		return getChildNodes(obj, ".slider_lever", "div", true).offsetLeft;
	},

	// private functions, not to be used outside this class

	_initinner: function(obj) {

		if(obj._initinnerslider) return;

		var lever = getChildNodes(obj, ".slider_lever", "div", true);
		var bar = getChildNodes(obj, ".slider_bar", "div", true);
		var center = getChildNodes(obj, ".slider_center", "div", true);

		obj._leverWidthS2 = Math.floor(currentStyle(lever, "width")/2);
		obj._maxlength = currentStyle(bar, "width");

		if(center) {
			obj._hascenter = true;
			obj._centerposition = center.offsetLeft + Math.floor(currentStyle(center, "width")/2);
		}

		obj._initinnerslider = true;
	},

	_drag: function(e, obj) { // for effectiveness

		disableSelection();

		e = e || window.event;
		var target = getTarget(e);

		var that = this;

		addClass(target, 'slider_active');
		var deltaX = e.clientX - target.offsetLeft;

		addEvent(document, "mousemove", _moveHandler, false);
		addEvent(document, "mouseup", _upHandler, false, "test");

		stopEvent(e);

		function _moveHandler(e) { that._mover(e, obj, target, e.clientX - deltaX); }

		function _upHandler() {

			removeClass(target, 'slider_active');
			
			removeEvent(document, "mousemove", _moveHandler, false);
			removeEvent(document, "mouseup", _upHandler, false);

			enableSelection();
		}
	},

	_mover: function(e, obj, target, realPosition) { // takes care of the actual move and also passed the position on the bar to the provided function

		var position = this._computeposition(obj, realPosition);

		var checkPosition = realPosition - obj._leverWidthS2;

		if(checkPosition <= 0) realPosition = 0 - obj._leverWidthS2;
		else if(checkPosition >= obj._maxlength) realPosition = obj._maxlength - obj._leverWidthS2;

		target.style.left = realPosition + "px";
		obj._dragfunc(e, position);
	},
	
	_computeposition: function(obj, realPosition) { // computes the position to pass on, not necessarily the correct

		if(!obj._initinnerslider) this._initinner(obj);

		if(realPosition === undefined) realPosition = this.getX(obj);
		
		var position = realPosition + obj._leverWidthS2;
		
		if(position < 0) position = 0;
		else if(position > obj._maxlength) position = obj._maxlength;

		return (obj._hascenter) ? position - obj._centerposition : position;
	}
}

// standalone-functions

function createFakeWindow(obj, hide, doOnClose, doOnHide, noDrag) { // needs some fixing probably

	obj = id(obj);
	if(obj.fakeWindow) return; // this is already run

	var objID = obj.id;

	var nav = elementsByClassName("float_lager_nav", "div", obj, true);
	if(!nav) {

		// create the window if it's not already done

		nav = document.createElement("div");
		nav.className = "float_lager_nav float_lager_nav_inactive";
		nav.id = objID + "_nav";

		var navInner = "";
		if(hide) navInner += '<span class="float_lager_nav_hide v_mus_top" tooltip="minimera">_</span>';
		navInner += '<span class="float_lager_nav_close v_mus_top" tooltip="stäng">X</span>';

		nav.innerHTML = navInner;

		var inner = document.createElement("div");
		inner.className = "fake_window_inner";
		insertChildNodes(inner, obj.childNodes);

		obj.style.padding = "0px"; // will look like hell otherwise
		obj.appendChild(nav);
		obj.appendChild(inner);
	}

	// some special-code due to mozillas stupid bug, men borde nog inte ligga här
	var editors = elementsByClassName("wys_editor", "div", obj);
	var len = editors.length;
	if(len != 0) {
		for(var i = 0; i < len; i++) editor.fix(editors[i]);
	}

	// initialize events and stuff

	addEvent(obj, "click", function() {

		// disabled is just a little failsafe that might be removed someday

		if(!obj.disabled) fakeWindowToTop(obj);
		obj.disabled = false;
	});

	setButtonEvents('close');
	if(hide) setButtonEvents("hide");

	addEvent(nav, "mouseup", f_all, false);
	addEvent(nav, "mousedown", function(e) {

		if(!e) e = window.event;
		var t = e.target||e.srcElement;

		if(isMember(t,'float_lager_nav_close')) {
			changeClass(t,'v_mus_top','i_mus_top');
		} else if(isMember(t,'float_lager_nav_hide')) {
			changeClass(t,'v_mus_top','i_mus_top');
		} else {

			this.moving = true;
			fakeWindowToTop(obj);
			
			if(!noDrag) drag(e, obj);
		}
	});

	obj.fakeWindow = true; // this function doesn't need to be run again on this obj

	// first some code-saving...
	function setButtonEvents(flag) {

		var b = elementsByClassName("float_lager_nav_" + flag, "span", obj, true);
		if(!b) return;

		addEvent(b, "mouseup", function() { // reset active press and/or close

			if(b.hover) {

				b.hover = false;

				f_all();

				if(flag == "hide") {
					obj.hide = true;
					if(doOnHide && (typeof doOnHide == "function")) doOnHide(obj);
				} else {
					obj.close = true;
					if(doOnClose && (typeof doOnClose == "function")) doOnClose(obj);
				}

				hideLayer(obj);
			}

			changeClass(b, 'i_mus_top', 'v_mus_top');
			enableSelection();
		});

		addEvent(b, "mouseout", function() { // reset active hover-color

			changeClass(b, 'i_mus_top', 'v_mus_top');
			if(!b.hover) enableSelection();
		});

		addEvent(b, "mouseover", function() {
			if(b.hover) changeClass(b, 'v_mus_top', 'i_mus_top');
		});

		addEvent(b, "mousedown", function(e) {

			addEvent(document, "mouseup", function() {
				b.hover = false;
				removeEvent(document, "mouseup", arguments.callee);
			});

			changeClass(b, 'v_mus_top', 'i_mus_top');

			disableSelection();
			b.hover = true;

			stopEvent(e || window.event);
		});
	}

	function f_all() {

		var el = elementsByClassName("float_lager_nav", "div"); //referens till alla nav för senare bruk

		for(var i=0;i<el.length;i++) el[i].moving = false;

		var he = elementsByClassName("float_lager_nav_hide","span");
		for(i=0;i<he.length;i++) he[i].hover = false;

		var ke = elementsByClassName("float_lager_nav_close","span");
		for(i=0;i<ke.length;i++) ke[i].hover = false;
	}
}

function fakeWindowToTop(obj) { //window-handler

	obj = id(obj);
	if(!obj) return;

	var fakeLayers = elementsByClassName("float_lager_nav","div");
	var parentLayer;
	
	for(var i = 0, len = fakeLayers.length; i < len; i++) {

		changeClass(fakeLayers[i], 'float_lager_nav_active', 'float_lager_nav_inactive');

		parentLayer = fakeLayers[i].parentNode;
		
		if(currentStyle(parentLayer, "z-index") == 12) parentLayer.style.zIndex = 11;
		else parentLayer.style.zIndex = 10;
	}

	obj.style.zIndex = "12";
	changeClass(getChildNodes(obj, ".float_lager_nav", "div", true), 'float_lager_nav_inactive', 'float_lager_nav_active');
}

function fixPositionProblem(obj) { // fixes so when two layers have the same position offset is added to the topmost

	obj = id(obj);
	if(!obj) return;

	var offset = 8;

	var top = currentStyle(obj, "top");
	var left = currentStyle(obj, "left");

	var layers = elementsByClassName("float_lager");
	for(var i = 0, len = layers.length; i < len; i++) {

		if(layers[i] == obj) continue;

		if(currentStyle(layers[i], "display") == "block") {

			var cLeft = currentStyle(layers[i], "left");
			if(cLeft > left - 2 && cLeft < left + 2) obj.style.left = (left - offset) + "px";

			var cTop = currentStyle(layers[i], "top");
			if(cTop > top - 2 && cTop < top + 2) obj.style.top = (top + offset) + "px";
		}

	}
}

// handlers for the boolean selector-node

function boolean_isSelected(obj) {

	obj = id(obj);
	if(!obj) return;

	return isMember(obj, "booleanchooses_inactive");
}

function boolean_select(obj) {
	
	obj = id(obj);
	if(!obj) return;

	removeClass(obj, "booleanchooser_disabled");
	addClass(obj, "booleanchooser_inactive");
}

function boolean_unselect(obj) {

	obj = id(obj);
	if(!obj) return;

	removeClass(obj, "booleanchooser_disabled");
	removeClass(obj, "booleanchooser_inactive");
}

function boolean_disable(obj) {

	obj = id(obj);
	if(!obj) return;

	removeClass(obj, "booleanchooser_inactive");
	addClass(obj, "booleanchooser_disabled");
}
