function endsWith(str, s){
	var reg = new RegExp (s + "$");
	return reg.test(str);
}

function isFileExtensionImage(_filename) {
	var filename = _filename.toLowerCase();
	return endsWith(filename,'.jpg') || endsWith(filename,'.gif') || endsWith(filename,'.png');
} 

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\\\s)"+searchClass+"(\\\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

function getOriginalUrl(imageUrl) {
	var separatedPath = imageUrl.split("/");
	
	var imagename = separatedPath.pop();
	var imageDir = separatedPath[separatedPath.length-1];
	var filename = imagename;
	if(imageDir == '.thumbs') {
		separatedPath.pop(); //Remove .thumbs dir entry
		var filename = imagename.substr(1);	
		
	}
	else if(imageDir == '.resized') {
		separatedPath.pop(); //Remove .resized dir entry
		
		var filename = imagename.replace(/.resized_[0-9]+x[0-9]+_/gi,"");
		
	}
	
	var originalUrl = separatedPath.join("/")+"/"+filename;
	return originalUrl;
}

function addSubtitles() {
	var ingress = getElementsByClass('ingress',document.getElementById('content'));
	for(i = 0; i<ingress.length; i++) {
		addSubtitlesInElement(ingress[i]);
	}
	bread = getElementsByClass('body',document.getElementById('content'));
	for(i = 0; i<bread.length; i++) {
		addSubtitlesInElement(bread[i]);
	}
}
function addSubtitlesInElement(element) {
	slideshow = new Slideshow('');
	var separator = ';';
	if(element.tagName.toLowerCase() == "tr")
		return;
	var ingressimages = element.getElementsByTagName('img');
	for(j = 0; j<ingressimages.length; j++) {
			var image = ingressimages[j];
			image.onclick = function() {slideshow.showImageFromUrl(getOriginalUrl(this.src),this.alt)};
			var sibling = (image.nextSibling);
			var parent = image.parentNode;
			var alt = image.getAttribute('alt');
			var subtext = '';
			var photoInfo = '';
			if(alt) {
				var altsplit = alt.split(separator);
				if(altsplit.length == 2) {
					photoInfo = document.createTextNode('Foto: '+altsplit[0]);
					if(!isFileExtensionImage(altsplit[1]))
						subtext = altsplit[1]; 
				}
				else {
					if(!isFileExtensionImage(altsplit[0]))
						subtext = altsplit[0];
				}
			} 
			var align = image.getAttribute('align');
			var width = image.clientWidth+10;
			image.removeAttribute('align');
			var imgContainer = document.createElement('div');
			imgContainer.className = 'imgContainer';
			var styleAtt = document.createAttribute('style');
			styleAtt.value = 'float:'+align+';width:'+width+'px;';
			var cssText = 'width:'+width+'px;';
			if(align)
				cssText += 'float:'+align;
			imgContainer.style.cssText = cssText;
			//imgContainer.setAttribute('style','float:'+align+';width:'+width+'px;');
			
			imgContainer.appendChild(image);
			if(photoInfo) {
				var photContainer = document.createElement('div');
				photContainer.className = 'photContainer';
				photContainer.appendChild(photoInfo); 
				imgContainer.appendChild(photContainer);
			}
			if(subtext) {
				var subContainer = document.createElement('div');
				subContainer.className = 'subContainer';
				var subtitle = document.createTextNode(subtext);
				subContainer.appendChild(subtitle);
				imgContainer.appendChild(subContainer);
			}
			if(sibling == null)
				parent.appendChild(imgContainer);
			else
				parent.insertBefore(imgContainer,sibling);
	}
}
function clearMe(idToClear, defaultText) {
	var elem = document.getElementById(idToClear);
	if(elem.value == defaultText)
		elem.value = '';
}

function checkValid(button) {
	var form = button.parentNode;
	while(form != null && form.tagName.toLowerCase() != 'form')
		form = form.parentNode;
	var validators = Array();
	var elements = form.childNodes;
	for(i=0; i<elements.length; i++) {
		if(elements[i].id && elements[i].id.match('validator')) {
			validators.push(elements[i]);
		}
	}
	for(j=0; j<validators.length; j++) {
		if(validators[j].className != 'valid')
			return false;
	}
	return true;
}

/**
* Gets values from form components. Ids of the form components are passed in as parameter
* @param ids Comma-separated string containing the ids of the form components to get data from
* @return Returns a string containing the values of the components. String is on form key=value and separated by ampersands
*/
function getFormValues(stringIds) {
	if(stringIds == '') 
		return '';
	var ids = stringIds.split(",");
	var postDataStr = "";
	var formElem = null;
	var elemContent = "";
	for(i=0; i < ids.length; i++) {
		var idMap = ids[i].split("=");
		var elemId = idMap[0];
		var mappedId = (idMap.length == 2 ? idMap[1] : elemId);
		formElem = document.getElementById(elemId);
		if(!formElem) {
			alert('Kunde inte hämta data från '+elemId);
			return false;
		}
		//If element is drop down, value are fetched in a different way
		if(formElem.type == 'select-one') {
			elemContent = encodeURIComponent(formElem.options[formElem.selectedIndex].value);
		}
		else if(formElem.type == 'select-multiple') {
			elemContent = '';
			for (var j=0; j < formElem.options.length;j++) {
				if (formElem.options[j].selected) {
					elemContent+='&'+mappedId+'='+encodeURIComponent(formElem.options[j].value);
				}
			}
			elemContent = elemContent.substr(2+mappedId.length);
		}
		else if(formElem.type == 'radio' || formElem.type == 'file') {
			elemContent = '';
			var elements = document.getElementsByName(mappedId);
			for(var k=0; k < elements.length; k++) {
				if(elements[k].checked || elements[k].type == 'file')
					elemContent+= '&'+mappedId+'='+encodeURIComponent(elements[k].value);
			}
			elemContent = elemContent.substr(2+mappedId.length);
		}
		else {
			elemContent = xinha_editors[elemId] ? xinha_editors[elemId].getHTML() : formElem.value;
			elemContent = encodeURIComponent(elemContent);
		}
		postDataStr +='&'+mappedId+'='+elemContent;
	}
	return postDataStr.substr(1); //Remove first ampersand sign	
}

function setValid(elem,message,isValid) {
 	elem.innerHTML = message;
	elem.className = (isValid ? 'valid' : 'invalid');
}

var xmlHttp = null;

var boxMap = new Object();
boxMap['boxlogin'] = 'core.security.LogInBox';
function runService(serviceName, ids, reRenderIdsStr, propsStr) {
	runService(serviceName, ids, reRenderIdsStr, propsStr, 0);
}
/**
* Helper function that performs the ajax requests. Calls the specified service with 
* the specified properties. "ReRenders" the specified region with the response.
* @param serviceName The name of the service to runt
* @param ids Comma separated String of the ids of the form components to get data from
* @param reRenderId Id of component that should be rerendered with the ajax response
* @param propsStr String containing properties
*/
function runService(serviceName, ids, reRenderIdsStr, propsStr, showProgress) {
	var response;
	var postVariables = getFormValues(ids);
	if(postVariables === false)
		return false;
 	var props = toMap(propsStr);
 	var formatProps = propsStr.replace(/,/g,"&");
 	var reRenderPaths = '';
 	var reRenders = '';
 	if(props['navigateTo'] == null) {
	 	reRenders = reRenderIdsStr.split(',');
 		reRenderPaths = getBoxPaths(reRenders);
 		removeBoxes(reRenders,reRenderPaths); //Removes the box ids from the array. Now only contains ids for components
 	}
 	var callbackFunc = function requestIsDone() {
		//alert('request is done:'+xmlHttp.readyState);
		//If data has been retrieved
		if (xmlHttp.readyState == 4) {
			//alert('status:'+xmlHttp.status);
	   	// If the data was retrieved successfully
	   		if (xmlHttp.status == 200) {
	   			if(showProgress == 1)
		   			hideProgressIndicator();
	   			if(props['navigateTo'] == null) {
	   				var txtResponse = xmlHttp.responseText;
	   				if(txtResponse != "") //Empty response, nothing to update
		   				reRenderAreas(eval('(' + txtResponse + ')'));
	   			}
	   			else
	   				navigateTo(props['navigateTo']);
	   			
	   		}
	   		/* IE returns a status code of 0 on some occasions, so ignore this case */
	   		else if (xmlHttp.status != 0) {
	   		}
	 	}
 	}
 	performAJAX(callbackFunc, 'RunService.php',window.location.search.substring(1)+'&name='+serviceName+'&boxPaths='+reRenderPaths+'&currentView='+currentView+'&reRenderComponents='+reRenders+'&'+postVariables+'&'+formatProps,xmlHttp);
	if(showProgress == 1)
		showProgressIndicator();
 	return true;
} 	

/** Performs an AJAX request
* @param callback The callback method to handle the ajax response
* @param callUrl The url to call
* @param args The args to send with the AJX call
*/
function performAJAX(callback, callUrl, args) {
 	if (xmlHttp != null && xmlHttp.readyState != 0 && xmlHttp.readyState != 4) {
   		xmlHttp.abort();
 	}
 	xmlHttp = getXmlHttpObject();
 	//Register the callback
 	xmlHttp.onreadystatechange = callback;
 	//Open the connection
 	xmlHttp.open('POST', callUrl, true);
 	
 	xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
    xmlHttp.setRequestHeader("Content-length", 1);
    xmlHttp.setRequestHeader("Connection", "close");
 	xmlHttp.send(args);
 }

//Returns the xmlHttpObject. If IE then use ActiveX, else use standard
function getXmlHttpObject() {
	var requester = null;
	try {
   		requester = new XMLHttpRequest();
 	}
 	catch (error) {
   		try {
     	requester = new ActiveXObject("Microsoft.XMLHTTP");
   		}
   		catch (error) {
    		requester = null;
   		}
 	}
 	
 	return requester;
 }
 
 function contains(needle, haystack) {
 	for(i=0; i<haystack.length;i++) {
 		if(haystack[i] == needle)
 			return true;
 	}
 	return false;
 }
 
 /**
 *	Takes a comma-separated string on the form key1=value1,key2=value2... and transforms it into a map with key-value pairs
 */
 function toMap(str) {
 	var map = new Object();
 	var keyvalPairs = str.split(',');
 	//Iterate over the array containing strings on the form key=value as elements
 	for(i=0;i<keyvalPairs.length;i++) {
 		var separatorIndex = keyvalPairs[i].search('=');
 		var key = keyvalPairs[i].substring(0,separatorIndex);
 		var value = keyvalPairs[i].substring(separatorIndex+1);
 		map[key] = value;
	}
	
	return map;
}

function getBoxPaths(ids) {
	var localPaths = new Array();
	for(i=0; i<ids.length; i++) {
		if(boxMapping[ids[i]] != undefined)
			localPaths.push(boxMapping[ids[i]]);
	}
	return localPaths;
}
function reRenderAreas(areasMap) {
	for(var areaId in areasMap) {
		var elementToUpdate = document.getElementById(areaId);
		elementToUpdate.innerHTML = areasMap[areaId];
	}
	if(areasMap['messageBox'])
		showMessageBox(areasMap['messageBox']);
}

function showProgressIndicator() {
	var topPos = window.innerHeight/2-200;
	var leftPos = window.innerWidth/2-100;
	var progId = 'progressIndicator';
	var progressInd = document.getElementById('progressIndicator');
	progressInd.style.top = topPos+'px';
	progressInd.style.left = leftPos+'px';
	//Show
	changeElement(progId);
	changeElement("transparentLayer");
}
function hideProgressIndicator() {
	document.getElementById('transparentLayer').style.display='none';
	document.getElementById('progressIndicator').style.display='none';
}

function getDocumentSize() {
	var size = new Object();
		//Need to user right properties thanks to IE!
	if(window.innerHeight) {
		size.width = window.innerWidth;
		size.height = window.innerHeight;
	}
	else if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
   	size.width = document.documentElement.clientWidth;
    size.height = document.documentElement.clientHeight;
  }
  else if(document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    size.width = document.body.clientWidth;
    size.height = document.body.clientHeight;
  }
  
  return size;
 }
/**
*	Creates and displays a delete confirmation dialog box. If user clicks OK button
*	the specified service is run with the specified parameters
*	@param type the type of the item to delete
*	@param name the name of the item to delete
*	@param service The name of the service to run
*	@param props The properties to pass to the service
**/
function showDeleteConfirmation(type, name, service, reRenderIds, props) {
	var confDelContent = new ConfirmDelete(type,name,service, reRenderIds, props);
	var confirmDelete = document.getElementById("confirmDeleteDialog");
	//Set content in confirm delete dialog
	confirmDelete.innerHTML = confDelContent.toString();
	//Set style TODO: Move all but the top and left attribute to css.

	var size = getDocumentSize();
	var height = size.height;
	var width = size.width;


	var topPos = height/2-100;

	var leftPos = width/2-100;
	confirmDelete.style.top = topPos+'px';
	confirmDelete.style.left = leftPos+'px';
	//Show
	confirmDelete.style.display='block';
	document.getElementById("transparentLayer").style.display='block';
	var div = document.createElement('div');
	div.id = 'deleteconfirmation';
	var confirmationstring = 'Är du säker på att du vill ta bort '+type+' '+name+'?';
	/*var text = document.createTextNode(confirmationstring);
	var cancelButton = createButton('delCancelBtn','Avbryt');
	cancelButton.setAttribute('onClick','hideDeleteConfirmation()');
	var okButton = createButton('delOkBtn','Ta bort');
	var serviceCall = 'runService(\''+service+'\',\'\',\'\',\''+props+'\')';
	okButton.setAttribute('onClick',serviceCall);
	div.appendChild(text);
	div.appendChild(cancelButton);
	div.appendChild(okButton);
	document.body.insertBefore(div,document.body.firstChild);*/
	//return confirm(confirmationstring);
	
}
function hideDeleteConfirmation() {
	document.getElementById('transparentLayer').style.display='none';
	document.getElementById('confirmDeleteDialog').style.display='none';
}
function createButton(id, value) {
	var button = document.createElement('input');
	button.id = id;
	button.setAttribute('name',id);
	button.setAttribute('type','button');
	button.setAttribute('value',value);
	
	return button;
}
//Creates a string from the given array with the given separator
function toString(arr, separator) {
	var str = '';
	for(i=0; i<arr.length;i++)
		str += arr[i]+separator;
	return str;
}

function ConfirmDelete(type, name, service, reRenderIds, props) {
	this.confirmStr = 'Är du säker på att du vill ta bort '+type+' '+name+'?<br />';
	this.cancelButton = '<input type="button" class="button" id="cancelDelete" value="Avbryt" onclick="hideDeleteConfirmation()" />';
	this.okButton = '<input type="button" class="button" id="confirmDelete" value="Ta bort" onclick="runService(\''+service+'\',\'\',\''+reRenderIds+'\',\''+props+'\');hideDeleteConfirmation()" />';
	this.toString = function() { return this.confirmStr+'<div style="text-align:right;margin-top:10px">'+this.cancelButton+this.okButton+'</div>'; };
}

function uploadFile(form) {
    if (!form) {
        return false;
    }
    var send = false;
    for (var n = 0; n < form.elements.length; n++) {
        if (form.elements[n].type == "file" && form.elements[n].value) {
            send = true;
            break;
        }
    }
    if (send) {
        var timestamp = (new Date).getTime();
        var frame_name = "imageupload" + timestamp;
        if (document.all && !window.opera) {
            var html = "<iframe name=\"" + frame_name + "\" src=\"gfx/blank.gif\" style=\"width:0;height:0;visibility:hidden;\"></iframe>";
            document.body.insertAdjacentHTML("BeforeEnd", html);
        } else {
            var frame = document.createElement("iframe");
            frame.name = frame_name;
            frame.width = 10;
            frame.height = 10;
            frame.style.visibility = "hidden";
            document.body.appendChild(frame);
        }
        
        form.target = frame_name;
        form.action = 'index.php?onlyUploadFiles=1';
        form.setAttribute("enctype", "multipart/form-data");
        form.setAttribute('encoding', 'multipart/form-data');
        form.submit();
    }
    return true;
}

function uploadImages(form,albumid) {
    if (!form) {
        return false;
    }
    var send = false;
    for (var n = 0; n < form.elements.length; n++) {
        if (form.elements[n].type == "file" && form.elements[n].value) {
            send = true;
            break;
        }
    }
    if (send) {
        var timestamp = (new Date).getTime();
        var frame_name = "imageupload" + timestamp;
        if (document.all && !window.opera) {
            var html = "<iframe name=\"" + frame_name + "\" src=\"gfx/blank.gif\" style=\"width:0;height:0;visibility:hidden;\"></iframe>";
            document.body.insertAdjacentHTML("BeforeEnd", html);
        } else {
            var frame = document.createElement("iframe");
            frame.name = frame_name;
            frame.width = 10;
            frame.height = 10;
            frame.style.visibility = "hidden";
            document.body.appendChild(frame);
        }
        var queryString = window.location.search;
        var imids = queryString.split('imageIds');
        var imidsQuery = '';
        if(imids.length == 2) {
        	var pos = imids[1].search("&");
				var ids = "";
					if(pos == -1)
						query = imids[1];
					else
						query = imids[1].substring(0,pos);
					imidsQuery = 'imageIds'+query;
				}
        form.target = frame_name;
        
        form.action = 'imagemanager.php?__plugin=ImageManager&albumid='+albumid+'&'+imidsQuery;
        form.setAttribute("enctype", "multipart/form-data");
        form.setAttribute('encoding', 'multipart/form-data');
        form.submit();
    }
    return true;
}

/**
* Removes elements containing box ids from the specified array
* @param large The array to remove elements containing box ids from
*/
function removeBoxes(arr) {
	for(var boxid in boxMapping) {
		var pos = array_exists(boxid, arr);
		if(pos != -1)
			arr.splice(pos,1);
	}
}

function array_exists(needle, haystack) {
	for(i=0; i<haystack.length; i++) {
		if(haystack[i] == needle)
			return i;
	}
	return -1;
}
function showMessageBox(message) {
	var messageBox = document.getElementById('messageBox');

	if(message != "" && message != undefined) {
		messageBox.style.display = 'block';
		messageBox.innerHTML = message;
		
		//setTimeout('changeElement(\''+messageBox.id+'\')',4000);
		changeElement('\''+messageBox.id+'\'');
	}
	else
		messageBox.style.display = 'none';
}

function changeElement(id) {
	var element = document.getElementById(id);
	var cssClass = element.className;
	var exists = cssClass.match('hidden');
	if(exists == null) {
		if(element.style.display == 'block')
			element.style.display = 'none';
		else
			element.className = cssClass+' '+'hidden';
		
	} else {
		element.className = element.className.replace('hidden','');
	}
}

function navigateTo(url) {
	window.location = url;
}

function toggleContextMenu(id, isChild) {
	var cMenu = document.getElementById(id);
	cMenu.style.position = 'absolute';
	var parent = cMenu.parentNode;
	var parentTop = findElemY(parent);
	cMenu.style.top = (isChild ? 0: parentTop+parent.clientHeight+3) +'px';
	var xpos = findElemX(parent);
	cMenu.style.left = (isChild ? parent.clientWidth + 5 : xpos) +'px';
	changeElement(id);
}

function getMouseCoords(e) {
	var posx = 0;
	var posy = 0;
	if (!e) var e = window.event;
	if (e.pageX || e.pageY) 	{
		posx = e.pageX;
		posy = e.pageY;
	}
	else if (e.clientX || e.clientY) 	{
		posx = e.clientX + document.body.scrollLeft
			+ document.documentElement.scrollLeft;
		posy = e.clientY + document.body.scrollTop
			+ document.documentElement.scrollTop;
	}
	
	return new Array(posx,posy);
}


function findElemX(obj)
  {
    var curleft = 0;
    if(obj.offsetParent)
        while(1) 
        {
          curleft += obj.offsetLeft;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.x)
        curleft += obj.x;
    return curleft;
  }

  function findElemY(obj)
  {
    var curtop = 0;
    if(obj.offsetParent)
        while(1)
        {
          curtop += obj.offsetTop;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.y)
        curtop += obj.y;
    return curtop;
  }