﻿// ComIT Generic functions

var comit = {
	screen: {
		getValues: function () {
			var width = 0, height = 0;
			if (window.innerHeight) { height = window.innerHeight; width = window.innerWidth; }
			else if (document.documentElement && document.documentElement.clientHeight) { height = document.documentElement.clientHeight; width = document.documentElement.clientWidth; }
			else if (document.body.clientWidth) { height = document.body.clientHeight; width = document.body.clientHeight; }
			else { alert("Browser does not support extScreen()"); }
			var scrollTop = (document.body.scrollTop > 0) ? document.body.scrollTop : (document.body.parentNode && document.body.parentNode.scrollTop > 0) ? document.body.parentNode.scrollTop : 0;
			var scrollLeft = (document.body.scrollLeft > 0) ? document.body.scrollLeft : (document.body.parentNode && document.body.parentNode.scrollLeft > 0) ? document.body.parentNode.scrollLeft : 0;
			return obj = {
				height: height,
				width: width,
				scrollTop: scrollTop,
				scrollLeft: scrollLeft
			};
		},
		makeFullyVisible: function (target, elementPositionObj) {
			if (!target || !target.nodeType || target.nodeType != 1) {
				return false;
			}
			debugger;
			if (target.offsetWidth === 0) {
				window.setTimeout(function () { debugger; comit.screen.makeFullyVisible(target); }, 1);
				return false;
			}
			var targetPos = comit.getPos(target);
			var screen = comit.screen.getValues();
			if (target.offsetWidth > screen.width) {
				target.style.width = screen.width + "px";
			}
			targetPos.endX = targetPos.x + target.offsetWidth;
			targetPos.endY = targetPos.y + target.offsetHeight;
			var mod = {};
			if (targetPos.x < 0) mod.x = 0;
			if (targetPos.y < 0) mod.y = 0;
			if (targetPos.endX > screen.width + screen.scrollLeft) mod.x = screen.width + screen.scrollLeft - target.offsetWidth;
			if (targetPos.endY > screen.width + screen.scrollTop) mod.y = screen.height + screen.scrollTop - target.offsetHeight;
			if (!mod.y) {
				if (!mod.x) return true;
				mod.y = targetPos.y;
			}
			if (!mod.x) mod.x = targetPos.x;
			comit.element.move(target, [mod.y, mod.x]);
		}
	},
	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: y, x: 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;
	},
	ensureEvent: function (e) {
		if (!e) {
			e = window.event;
		}
		return e;
	},
	getEventTargetNode: function (e) {
		e = comit.ensureEvent(e);
		var targetNode;
		if (e.target) {
			targetNode = e.target;
		}
		else if (e.srcElement) {
			targetNode = e.srcElement;
		}
		if (targetNode.nodeType == 3) {
			// defeat Safari bug
			targetNode = targetNode.parentNode;
		}
		return targetNode;
	},
	stopPropagation: function (e) {
		comit.ensureEvent(e);
		if (e.stopPropagation) {
			e.stopPropagation();
		}
		e.cancelBubble = true;
	},
	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(" ");
	},
	event: {
		GetTargetElement: function (e) {
			var targetElement;
			if (e.target) targetElement = e.target;
			else if (e.srcElement) targetElement = e.srcElement;
			if (targetElement.nodeType == 3) { // defeat Safari bug
				targetElement = targetElement.parentNode;
			}
			return targetElement;
		}
	},
	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;
			}
		}
	},
	cookie: {
		create: function (name, value, days) {
			if (days) {
				var date = new Date();
				date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
				var expires = "; expires=" + date.toGMTString();
			}
			else var expires = "";
			document.cookie = name + "=" + value + expires + "; path=/";
		},

		read: function (name) {
			var nameEQ = name + "=";
			var ca = document.cookie.split(';');
			for (var i = 0; i < ca.length; i++) {
				var c = ca[i];
				while (c.charAt(0) == ' ') c = c.substring(1, c.length);
				if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
			}
			return null;
		},

		erase: function (name) {
			comit.cookie.create(name, "", -1);
		}
	},
	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());
		}
	}
};

