﻿// ComIT Generic functions

var comit = {
	isArray: function(obj) {
		if (!obj || !obj.constructor || obj.constructor.toString().indexOf("Array") == -1) {
			return false;
		}
		return true;
	},
	isElement: function(obj, tagName) {
		if (obj && (typeof (obj)).toLowerCase() == "object" && obj.nodeType && obj.nodeType == 1) {
			if (!tagName) {
				return true;
			}
			else if (tagName && obj.tagName && obj.tagName.toLowerCase() == tagName.toLowerCase()) {
				return true;
			}
		}
		return false;
	},
	getPos: function(node) {
		var x = node.offsetLeft;
		var y = node.offsetTop;
		var parent = node.offsetParent;
		do {
			if (parent.offsetLeft) { x = x + parent.offsetLeft; }
			if (parent.offsetTop) { y = y + parent.offsetTop; }
		}
		while (parent = parent.offsetParent);
		return [y, x];
	},
	attachClass: function(node, stringClassName) {
		var aCurrentClasses = node.className.split(" ");
		for (var i = 0; i < aCurrentClasses.length; i++) {
			var current = aCurrentClasses[i];
			if (current == stringClassName) {
				return;
			}
		}
		aCurrentClasses[aCurrentClasses.length] = stringClassName;
		node.className = aCurrentClasses.join(" ");
		return;
	},
	copyObject: function(obj) {
		var copy = {};
		for (var i in obj) {
			copy[i] = obj[i];
		}
		return copy;
	},
	removeClass: function(node, stringClassName) {
		var aCurrentClasses = node.className.split(" ");
		var aNewClasses = [];
		for (var i = 0; i < aCurrentClasses.length; i++) {
			var current = aCurrentClasses[i];
			if (current != stringClassName) {
				aNewClasses[aNewClasses.length] = current;
			}
		}
		node.className = aNewClasses.join(" ");
	},
	element: {
		getByClass: function(classNames, parentNode, tagNames) {
			// Function som returnerar en array med htmlnoder med rätt className/s
			// classNames kan vara en sträng eller en array med strängar
			// parentNode är en htmlnod, endast noder under denna nod kollas
			// tagNames kan vara en sträng eller en array med strängar
			var classElements = new Array();
			parentNode = (parentNode) ? parentNode : document;
			tagNames = (tagNames) ? tagNames : '*';

			var els = [];
			if (comit.isArray(tagNames)) {
				for (var i in els) {
					els[tagNames[i]] = parentNode.getElementsByTagName(tagNames[i]);
				}
			}
			else {
				els[tagNames] = parentNode.getElementsByTagName(tagNames);
			}
			for (var tagName in els) {
				for (var i = 0, j = 0, elsLen = els[tagName].length; i < elsLen; i++) {
					if (comit.isArray(classNames)) {
						for (var className in classNames) {
							var pattern = new RegExp('(^|\\\\s)' + classNames[className] + '(\\\\s|$)');
							if (pattern.test(els[tagName][i].className)) {
								classElements[j++] = els[tagName][i];
							}
						}
					}
					else {
						var pattern = new RegExp('(^|\\\\s)' + classNames + '(\\\\s|$)');
						if (pattern.test(els[tagName][i].className)) {
							classElements[j++] = els[tagName][i];
						}
					}
				}
			}
			return classElements;
		},
		getChildTags: function(parent, tagName) {
			var returnElements = [];
			if (parent == "" || tagName == "") {
				return returnElements;
			}
			var elements = parent.getElementsByTagName(tagName);
			for (var i in parent.childNodes) {
				var child = parent.childNodes[i];
				if (comit.isElement(child, tagName)) {
					returnElements[returnElements.length] = child;
				}
			}
			return returnElements;
		},
		getChildText: function(parent) {
			// Returnerar array med alla textnoder
			var texts = [];
			for (var i in parent.childNodes) {
				var child = parent.childNodes[i];
				if (child && child.nodeType && child.nodeType == 3) {
					texts[texts.length] = child.nodeValue;
				}
			}
			return texts;
		},
		getById: function(saIds) {
			var oaReturn = [];
			if (comit.isArray(saIds)) {
				for (var key in saIds) {
					var id = saIds[key];
					if ((typeof (id)).toLowerCase() == "string") {
						var element = document.getElementById(id);
						if (comit.isElement(element)) {
							oaReturn[oaReturn.length] = element;
						}
					}
				}
			}
			else if ((typeof (saIds)).toLowerCase() == "string") {
				var obj = document.getElementById(saIds);
				if (comit.isElement(obj)) {
					return obj;
				}
			}
			return oaReturn;
		},
		setOpacity: function(value, oaNodes) {
			if (comit.isArray(oaNodes)) {
				for (var key in oaNodes) {
					var node = oaNodes[key];
					node.style.opacity = value / 100;
					node.style.filter = 'alpha(opacity=' + value + ')';
				}
			}
			else if (comit.isElement(oaNodes)) {
				oaNodes.style.opacity = value / 100;
				oaNodes.style.filter = 'alpha(opacity=' + value + ')';
			}
			else return false;
			return true;
		},
		getStyle: function(node, rule) {
			var returnValue = "";
			if (document.defaultView && document.defaultView.getComputedStyle) {
				returnValue = document.defaultView.getComputedStyle(node, "").getPropertyValue(rule);
			}
			else if (node.currentStyle) {
				rule = rule.replace(/\-(\w)/g, function(strMatch, p1) {
					return p1.toUpperCase();
				});
				returnValue = oElm.currentStyle[strCssRule];
			}
			return returnValue;
		},
		add: function(parent, newTagName, className, idAndAlt, textOrSrc, title) {
			var newElement;
			if (newTagName.toLowerCase() == "tr") { newElement = parent.insertRow(parent.rows.length); }
			else if (newTagName.toLowerCase() == "td") { newElement = parent.insertCell(parent.cells.length); }
			else {
				newElement = parent.appendChild(document.createElement(newTagName));
				if (newTagName.toLowerCase() == "table") {
					newElement.cellPadding = 0;
					newElement.cellSpacing = 0;
				}
			}
			if (className && (typeof (className)).toLowerCase() == "string") comit.attachClass(newElement, className);
			else if (className && comit.isArray(className)) {
				for (var key in className) {
					var current = className[key];
					comit.attachClass(newElement, current);
				}
			}
			if (idAndAlt || newTagName.toLowerCase() == 'img') {
				if (!idAndAlt) { throw ("All images must have an alternate text"); }
				newElement.id = idAndAlt;
			}
			if (textOrSrc && newTagName.toLowerCase() == 'img') { newElement.src = textOrSrc; }
			else if (textOrSrc) { newElement.appendChild(document.createTextNode(textOrSrc)); }
			if (title) newElement.title = title;
			return newElement;
		},
		move: function(node, iaNewXY, iCorner) {
			iCorner = (iCorner) ? iCorner : 1;
			if (comit.isElement(node)) {
				if (node.style.position.toLowerCase() == "absolute") {
					// Corners: 1 = tlc = default, 2 = trc, 3 = blc, 4 = brc
					if (iCorner == 1 || iCorner == 2) node.style.top = iaNewXY[0] + "px";
					if (iCorner == 1 || iCorner == 3) node.style.left = iaNewXY[1] + "px";
					if (iCorner == 2 || iCorner == 4) node.style.right = iaNewXY[1] + "px";
					if (iCorner == 3 || iCorner == 4) node.style.bottom = iaNewXY[0] + "px";
				}
				else {
					throw ("Node has to be absolutely positioned: " + node.id);
				}
			}
			else {
				throw ("You have to provide a node to move.");
			}
		}
	},
	effects: {
		fadeIn: function(node, params) {
			if (!params.startTime) {
				comit.time.actions.add(new Date().getTime(), params, this.fadeIn, node);
				return;
			}
			var currentTime = new Date().getTime();
			var elapsed = currentTime - (params.startTime + params.delay);
			var value = (elapsed < params.duration) ? (elapsed / params.duration) * 100 : 100;
			comit.element.setOpacity(value, node);
			if (elapsed >= params.duration) {
				if (params.fadeInCallBack) {
					params.fadeInCallBack();
				}
				return true;
			}
		},
		fadeOut: function(node, params) {
			if (!params.startTime) {
				comit.time.actions.add(new Date().getTime(), params, this.fadeOut, node);
				return;
			}
			var currentTime = new Date().getTime();
			var elapsed = currentTime - (params.startTime + params.delay);
			var value = (elapsed < params.duration) ? 1 - ((elapsed / params.duration)) : 0;
			var softValue = ((Math.cos(Math.PI * (value - 1))) + 1) / 2;
			comit.element.setOpacity(softValue * 100, node);
			if (elapsed >= params.duration) {
				if (params.fadeOutCallBack) {
					params.fadeOutCallBack();
				}
				return true;
			}
		},
		animateMove: function(node, params) {
			if (!params.startTime) {
				comit.time.actions.add(new Date().getTime(), params, this.animate2, node);
				return;
			}

			var elapsed = params.currentTime - (params.startTime + params.delay);
			var value = (elapsed < params.duration) ? elapsed / params.duration : (elapsed >= 0) ? 1 : 0;
			var softValue = ((Math.cos(Math.PI * (value - 1))) + 1) / 2;
			if (elapsed >= 0 && !params.startY) {
				params.startY = comit.getPos(node)[0];
				params.startX = comit.getPos(node)[1];
			}
			var currentY = params.startY + ((params.targetY - params.startY) * softValue);
			var currentX = params.startX + ((params.targetX - params.startX) * softValue);
			if (elapsed >= 0) {
				comit.element.move(node, [currentY, currentX]);
			}
			if (value >= 1) {
				return true;
			}
		},
		imageShift: function(node, params) {
			if (!params.startTime) {
				params.imageElm = comit.element.add(document.body, "img", 0, "tempImg");
				params.imageElm.style.position = "absolute";
				params.imageElm.style.width = node.offsetWidth + "px";
				params.imageElm.style.height = node.offsetHeight + "px";
				params.imageElm.style.left = comit.getPos(node)[1] + "px";
				params.imageElm.style.top = comit.getPos(node)[0] + "px";
				params.image = new Image();
				params.imageElm.style.visibility = "hidden";
				params.imageElm.style.background = "url(" + node.src + ")";
				params.image.onload = function() {
					params.imageElm.style.visibility = "visible";
					comit.element.setOpacity(0, node);
					node.src = params.newSrc;
					var params2 = comit.copyObject(params)
					comit.effects.fadeIn(node, params2);
					comit.effects.fadeOut(params.imageElm, params);
				};
				params.image.src = params.newSrc;
				params.fadeOutCallBack = function() {
					params.imageElm.parentNode.removeChild(params.imageElm);
				}
			}
		},
		imageGallery: function(node, params) {
			if (!params.startTime) {
				comit.time.actions.add(new Date().getTime(), params, this.imageGallery, node);
				return;
			}
			var elapsed = params.currentTime - (params.startTime + params.delay);
			if (elapsed >= 0) {
				params.index += 1;
				if (params.index >= params.images.length) {
					params.index = 0;
				}
				delete params.startTime;
				fadeParams = { newSrc: params.images[params.index], duration: params.fadeTime, delay: 0 };
				comit.effects.imageShift(node, fadeParams);
				newParams = comit.copyObject(params);
				comit.effects.imageGallery(node, newParams);
				if (params.galleryCallBack) {
					params.galleryCallBack();
				}
				return true;
			}
		},
		changeValue: function(node, params) {
			if (!params.startTime) {
				comit.time.actions.add(new Date().getTime(), params, this.changeValue, node);
				return;
			}
			var elapsed = params.currentTime - (params.startTime + params.delay);
			if (elapsed >= 0) {
				if (params.index >= 0) {
					params.index++;
					if (params.index >= params.values.length) {
						params.index = 0;
					}
					node[params.targetValue] = params.values[params.index];
				}
				delete params.startTime;
				var newParams = comit.copyObject(params);
				comit.effects.changeValue(node, newParams);
				return true;
			}
		}
	},
	time: {
		action: function(startTime, params, func, target) {
			this.params = params;
			this.params["startTime"] = startTime;
			this.func = func;
			this.target = target;
		},
		actions: {
			add: function(startTime, params, func, target) {
				var list = comit.time.actions.list;
				list[list.length] = new comit.time.action(startTime, params, func, target);
				if (!comit.time.started) {
					comit.time.start();
				}
			},
			list: []
		},
		fps: function() {
			var currentTime = new Date().getTime();
			var elapsed = currentTime - comit.time.startTime;
			return comit.time.funcCounter / (elapsed / 1000);
		},
		func: function() {
			if (comit.time.actions.list.length < 1) {
				comit.time.stop();
				return;
			}
			comit.time.funcCounter++;
			var currentTime = new Date().getTime();
			var newList = [];
			for (var i = 0; i < comit.time.actions.list.length; i++) {
				var action = comit.time.actions.list[i];
				action.params.currentTime = currentTime;
				if (!action.func(action.target, action.params, action.startTime)) {
					newList[newList.length] = action;
				}
			}
			comit.time.actions.list = newList;
		},
		funcCounter: 0,
		start: function() {
			comit.time.timer = window.setInterval(function() { comit.time.func(); }, 1);
			comit.time.started = 1;
			comit.time.funcCounter = 0;
			comit.time.startTime = new Date().getTime();
		},
		started: 0,
		startTime: 0,
		stop: function() {
			window.clearInterval(comit.time.timer);
			comit.time.started = 0;
			//alert("functions per second: " + comit.time.fps());
		}
	}
};
