/*****************************************************************/
/* CMFLAT Version 1.4 - Javascript Frontend Functions            */
/* Copyright 2011 by Matthias Kleiser, CPKI GmbH <info@cpki.de>  */
/*                                                               */
/* NO UNAUTHORIZED USE! DO NOT REMOVE THIS COPYRIGHT NOTICE!     */
/*****************************************************************/

//++++++++++++++++++++++++++
//	collect get vars
//++++++++++++++++++++++++++
var urlapp = window.location.search;
var get = new Array();
if (urlapp != "")  {
	liste = urlapp.split("&");
	for (i=0;i<liste.length;i++) {
		temp = liste[i].split("=");
		temp[1]=temp[1].replace(/\+/g," ");
		temp[1]=unescape(temp[1]);
		get[temp[0]] = temp[1];
	}
}
     
//++++++++++++++++++++++++++
//	http request object
//++++++++++++++++++++++++++
var http;
var browser = navigator.appName;
if(browser == "Microsoft Internet Explorer") {
    http = new ActiveXObject("Microsoft.XMLHTTP");
}
else{
    http = new XMLHttpRequest();
}

//++++++++++++++++++++++++++
//	mouse tracker
//++++++++++++++++++++++++++
var mouseX = -1;
var mouseY = -1;

jQuery(document).ready(function(){
   $(document).mousemove(function(e){
	if (e.pageX || e.pageY)  {
		mouseX = e.pageX;
		mouseY = e.pageY;
	}
	else if (e.clientX || e.clientY)  {
		mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}
   }); 
});

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// custom cursor
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function showMyCursor() {
	$('#mycursor').css('left', (mouseX+5)+"px");
	$('#mycursor').css('top', (mouseY+5)+"px");
	$('#mycursor').css('display', 'block');
}

function hideMyCursor() {
	$('#mycursor').css('display', 'none');
}

//************************************************************************
// CALENDAR
//************************************************************************

function transformDate(d, mode) {
	if (mode=='db') {
		var tmp=d.split('.');
		return tmp[2]+'-'+(1*tmp[1]<10 ? "0" : "")+1*tmp[1]+'-'+(1*tmp[0]<10 ? "0" : "")+1*tmp[0];
	}
	else {
		var tmp=d.split('-');
		return (1*tmp[2]<10 ? "0" : "")+1*tmp[2]+'.'+(1*tmp[1]<10 ? "0" : "")+1*tmp[1]+'.'+tmp[0];
	}	
}

// date selector ++++++++++++++++++++++++++++++++++++++++++++++++
function selectDate(url, formid, target, date) { 
	url += '&calendar=show&id=' + formid + '&tgt=' + target;
	if (date=='') date = document.getElementById(formid+'_'+target).value;
	if (date!='') url += '&date=' + date;
	cm_ajaxSimpleLoader(url, formid + '_' + target + '_dateSelector');
}
function setDate(url, formid, target, date) {
	document.getElementById(formid+'_'+target).value = date;
	url += '&calendar=hide&id=' + formid + '&tgt=' + target + '&date=' + date;
	cm_ajaxSimpleLoader(url, formid+'_'+target+'_dateSelector');
	document.getElementById(formid+'_'+target).focus();
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++
//	cookie and reload
//++++++++++++++++++++++++++++++++++++++++++++++++++++
function setCookie(name, value) {
	$.cookie(name, value);

function getCookie(name) {
	return $.cookie(name);
}}

function setCookieAndLoad(name, value, url) {
	setCookie(name, value);
	window.location = url; 
}

function setCookieAndReload(name, value) {
	setCookie(name, value);
	window.location.reload(); 
}

function cm_confirmAction(msg, url) {
	if (confirm(msg)) window.location = url;
}

function cm_setSelectionAndLoad(type, name, elem, url) {
	var k = elem.selectedIndex;
	var value = elem.options[k].value;
	if (type=='cookie') {
		setCookie(name, value);
	}
	if (type=='get') {
		url = url + '&' + name + '=' + value;
	}
	window.location = url; 
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	content filters
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function cm_setHeadFilter(elem, name, url, cookie) {
	var value = $(elem).val();
	if (cookie)
		setCookie(cookie, value);		
	window.location = url + (url.indexOf("?") ? "&" : "?") + name + "=" + value;
}

function cm_setContentFilter(cid) {
	var mask = 'contentFilter_' + cid + '_rs_';
	var filter = '';
	$('.contentFilter_' + cid).each(function() {
		if ($(this).val()!='') {
			var fld = $(this).attr('id').substr(mask.length);
			var txt = $(this).val();
			filter += "[" + fld + "]" + "=[" + txt + "]";
		}
	});
	setCookie('contentFilter_' + cid, filter);
}

function cm_resetContentFilter(cid, fld) {
	document.getElementById('contentFilter_' + cid + '_rs_' + fld).value = '';
	cm_setContentFilter(cid);
}

function cm_setContentFilterURL(cid, url) {
	var mask = 'contentFilter_' + cid + '_rs_';
	var filter = '';
	$('.contentFilter_' + cid).each(function() {
		if ($(this).val()!='') {
			var fld = $(this).attr('id').substr(mask.length);
			var txt = $(this).val();
			filter += escape("[" + fld + "]" + "=[" + txt + "]");
		}
	});
	window.location = url + ((filter!='') ? '&filter_' + cid + '=' + filter : '');
}

function cm_resetContentFilterURL(cid, fld, url) {
	document.getElementById('contentFilter_' + cid + '_rs_' + fld).value = '';
	cm_setContentFilterURL(cid, url);
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	positioning
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function getBody(w) {
	if (!w) w = document;
	else w = w.document;
    return (w.compatMode && w.compatMode == "CSS1Compat") ? w.documentElement : w.body || null;
}

function getDocSize() {
    var obj = new Object();
	var doc = getBody();
   	obj.x = Math.max( doc.scrollWidth, doc.offsetWidth, doc.clientWidth );
   	obj.y = Math.max( doc.scrollHeight, doc.offsetHeight, doc.clientHeight );
   	return obj;
}

function getWindowSize() {
    var obj = new Object();
	if (document.all) {
		var win = getBody(window);
		obj.x = win.clientWidth;
		obj.y = win.clientHeight;
	}
	else {
		obj.x = window.innerWidth;
		obj.y = window.innerHeight;	
	}
	return obj;
}

function getScrollPos() {
    var obj = new Object();
	if (document.all) {
		var win = getBody(window);
		obj.x = win.scrollLeft;
		obj.y = win.scrollTop;
	}
	else {
		obj.x = window.pageXOffset;
		obj.y = window.pageYOffset;	
	}
	return obj;
}

function getPosition(e) {
	x = e.offsetLeft;
	y = e.offsetTop;
    var obj = new Object();
	parentObj = e.offsetParent;
	while(parentObj != null) {
		x += parentObj.offsetLeft;
		y += parentObj.offsetTop;
		parentObj = parentObj.offsetParent;
	}
	obj.x = x;
	obj.y = y;
	return obj;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	scrolling
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
scrollStep=10;

timerLeft="";
timerRight="";

function cm_scrollRight(id){
  clearTimeout(timerRight) ;
  document.getElementById(id).scrollLeft+=scrollStep;
  timerRight=setTimeout("cm_scrollRight('"+id+"')",10);
}

function cm_scrollLeft(id){
  clearTimeout(timerLeft);
  document.getElementById(id).scrollLeft-=scrollStep;
  timerLeft=setTimeout("cm_scrollLeft('"+id+"')",10);
}

function cm_stopScroll(){
  clearTimeout(timerRight);
  clearTimeout(timerLeft);
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	tip
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function showTip(e, text) {
    var pos = $(e).offset();
    var tip = document.getElementById('tip');
    tip.innerHTML = Base64.decode(text);
	tip.style.top = pos.top + 'px';
	tip.style.left = pos.left + 'px';
	tip.style.display = 'block';
}

function showAjaxTip(e, url) {
    var pos = $(e).offset();
    cm_ajaxSimpleLoader(url+"&ajax=on", 'tip');
	tip.style.top = (pos.top+$(e).height()) + 'px';
	tip.style.left = pos.left + 'px';
	tip.style.display = 'block';
}

function hideTip(e) {
    var tip = document.getElementById('tip');
	if (!e) var e = window.event;
	var tg = (window.event) ? e.srcElement : e.target;
	if (tg.nodeName!='DIV') return;
	var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
	while (reltg != tg && reltg.nodeName != 'BODY')
		reltg = reltg.parentNode;
	if (reltg==tg) return;
    tip.innerHTML = '';
	tip.style.display = 'none';	
}

function hideTip2() {
    var tip = document.getElementById('tip');
    tip.innerHTML = '';
	tip.style.display = 'none';	
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	css classes
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function has_class (elem, classname) {
	el = document.getElementById(elem);
  	return(
	 	(" " + (el.className || '') + " ").indexOf(classname) >= 0
  	);
}

function add_class (elem, newclass) {
	el = document.getElementById(elem);
  	var classes = (el.className || '').split(" ");
 	classes.push(newclass);
  	el.className = classes.join(" ");
}

function remove_class (elem, endclass) {
	el = document.getElementById(elem);
  	if(!el.className) return el;
  	var classes = el.className.split(" ");
  	for(var i = 0; i < classes.length; i++) {
    	if(classes[i] == endclass) classes[i] = '';
  	}
  	el.className = classes.join(" ");
}


function cm_hilite(e, hiliteClass) {
 	$(e).addClass(hiliteClass);
}

function cm_lowlite(e, hiliteClass) {
 	$(e).removeClass(hiliteClass);
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	toggle functions
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function cm_showLayer(elem, duration) {
	$(elem).show(duration);
}
function cm_hideLayer(elem, duration) {
	$(elem).hide(duration);
}

function cm_toggleLayer(elem, duration) {
	var status = ($('#'+elem).css('display')=='none');
	$('#'+elem).toggle(duration);
	return status;
}
function cm_exclusiveToggleLayer(elem, cl, duration) {
	$('.'+cl).hide(duration);
	$('#'+elem).show(duration);
}

function cm_toggleLayerWithCookie(elem, duration) {
	var status = cm_toggleLayer(elem, duration) ? 'opened' : 'closed';
	setCookie(elem, status);
}
function cm_toggleLayerWithIcon(img, elem, imgopen, imgclosed, duration) {
	var status = cm_toggleLayer(elem, duration) ? 'opened' : 'closed';
	setCookie(elem, status);
	if (status=='opened') {
		img.src = imgopen;
	}
	else {
		img.src = imgclosed;
	}
}

function cm_toggleDisplay(elem) {
	var status = ($('#'+elem).css('display')=='none');
	$('#'+elem).toggle();
	return status;
}
function cm_exclusiveToggleDisplay(elem, cl) {
	$('.'+cl).hide();
	$('#'+elem).show();
}
function cm_toggleDisplayByCheckbox(cbox, elem) {
	$('#'+elem).toggle($('#'+cbox).attr('checked'));
}
function cm_exclusiveToggleDisplayWithCookie(elem, cl) {
	$('.'+cl).hide();
	$('#'+elem).show();
	setCookie('layerOpen_'+cl, elem);
}

function cm_multiToggleDisplay(elem, cl) {
	$('.'+cl).each(function() {
		if (this.id==elem)
			$(this).toggle();
		else
			$(this).hide();
	});
}

function cm_toggleWidth(el, min, max) {
	if ($('#'+el).width()>(max+min)*0.5) { 
		$('#'+el).width(min);
	}
	else {
		$('#'+el).width(max);
	}
}
function cm_toggleHeight(el, min, max) {
	if ($('#'+el).height()>(max+min)*0.5) { 
		$('#'+el).height(min);
	}
	else {
		$('#'+el).height(max);
	}
}
function cm_exclusiveToggleWidth(el, cl, min, max) {
	if ($('#'+el).width()>(max+min)*0.5) {
		$('#'+el).width(min);
	}
	else {
		$('#'+el).width(max);
		$('.'+cl).width(min);
	}
}
function cm_exclusiveToggleHeight(el, cl, min, max) {
	if ($('#'+el).height()>(max+min)*0.5) {
		$('#'+el).height(min);
	}
	else {
		$('#'+el).height(max);
		$('.'+cl).height(min);
	}
}


//++++++++++++++++++++++++++
//	zoom images
//++++++++++++++++++++++++++
function zoomImg(url, e) {
	var tgt = url+'&zoom=img&src='+escape(e);
	cm_ajaxOverlayBoxLoader(tgt, '50% 50%');
}


//++++++++++++++++++++++++++
//	gallery functions
//++++++++++++++++++++++++++
var gallery = new Array();
function cm_initGallery(n, source, alt, title, desc, thumb) {
	gallery[n] = new Object();
	gallery[n]['source']=Base64.decode(source).replace("'", "`");
	gallery[n]['alt']=Base64.decode(alt).replace("'", "`");
	gallery[n]['title']=Base64.decode(title).replace("'", "`");
	gallery[n]['desc']=Base64.decode(desc).replace("'", "`");
	gallery[n]['thumb']=Base64.decode(thumb).replace("'", "`");
}
function cm_toggleGallery(mode, id, n) {

	if (mode=='foto') {
		document.getElementById(id + '_foto').innerHTML = '<img src=\"'+gallery[n]['source']+'\" alt=\"'+gallery[n]['alt']+'\" title=\"'+gallery[n]['title']+'\" />';
	}
	if (mode=='video') {
		document.getElementById(id + '_video').innerHTML = ((gallery[n]['source']!='') ? gallery[n]['source'] : gallery[n]['alt']);
	}
	document.getElementById(id + '_title').innerHTML = gallery[n]['title'];
	document.getElementById(id + '_desc').innerHTML = gallery[n]['desc'];
	
	// set thumb active class
	var n_alt = parseInt(document.getElementById(id + '_actBrowse').innerHTML);
	remove_class(id+'_thumb_'+n_alt, 'activeThumb');
	add_class(id+'_thumb_'+n, 'activeThumb');
	document.getElementById(id+'_actBrowse').innerHTML = n;
}

function cm_browseGallery(mode, id, dir) {
	var n = parseInt(document.getElementById(id + '_actBrowse').innerHTML);
	var m = parseInt(document.getElementById(id + '_maxBrowse').innerHTML);
	if (dir=='prev') {
		n = n-1<1 ? m : n-1;
	} 
	else {
		n = n+1>m ? 1 : n+1;
	}
	if (mode=='foto')
		cm_toggleGallery('foto', id, n);
	if (mode=='video')
		cm_toggleGallery('video', id, n);
}

//++++++++++++++++++++++++++
//	tab functions
//++++++++++++++++++++++++++
function cm_showTab(tabId, n, c, mode) {
	$('.'+tabId+'_tabContent').hide();
	if (n!='')
		$('#'+tabId+'_tabContent_'+n).show();
		
	$('.'+tabId+'_tabHandleActive').each(function(){
		$(this).removeClass(tabId+'_tabHandleActive');
		$(this).removeClass(c+'Active');
	});
	if (n!='') {
		cm_hilite($('#'+tabId+'_tabHandle_'+n), tabId+'_tabHandleActive '+c+'Active');
		setCookie(tabId+'_openTab', n);
	}
	if (mode!='') {
		$('#'+tabId+'_mode').val(mode);
	}
}

//++++++++++++++++++++++++++
//	menu functions
//++++++++++++++++++++++++++
var cm_menuFlag = "0";
function cm_hideMenuOrNot(a) {
	if (cm_menuFlag!=a) {
		$('#'+a).hide();
	}
}
function cm_hideMenu(a, duration) {
	cm_menuFlag = "";
	if (duration>0) {
		setTimeout("cm_hideMenuOrNot('" + a + "')", duration);
	}
	else {
		$('#'+a).hide();		
	}
}
function cm_showMenu(a) {
	cm_menuFlag=a;
	$('#'+a).show();
}


function cm_toggleMenu(a, cid, duration) {
	var status = cm_toggleLayer(a, duration) ? 'open' : 'close';
	setCookie('menuState_'+cid, status);
}

function cm_toggleMenuWithIcon(a, cid, img, imgopen, imgclosed, duration) {
	var status = cm_toggleLayer(elem, duration) ? 'open' : 'close';
	setCookie('menuState_'+cid, status);
	if (status=='open') {
		img.src = imgopen;
	}
	else {
		img.src = imgclosed;
	}
}
		
		
//++++++++++++++++++++++++++
//	set a link on an element
//++++++++++++++++++++++++++
function cm_setLinkElement(url, el) {
	$('#'+el).css('cursor', 'pointer');
    $('#'+el).bind('click', function(){
		window.location = url; 
    });
}

//++++++++++++++++++++++++++
//	tree toggling
//++++++++++++++++++++++++++
function cm_stopPropagation(e) {
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

function cm_toggleTreeElement(event, treeId, elementId, childsId, switchId, openIcon, closeIcon, bgImg, duration) {
	cm_stopPropagation(event);
	if ($('#'+childsId).css('display')!="none") {
		cm_hideLayer($('#'+childsId), duration);
		$('#'+switchId).attr('src', openIcon);
		$('#treeIcon_' + treeId + '_' + elementId).css('background-image', 'none');
		setCookie("treeStatus_"+treeId+'_'+elementId, 'close');
	}
	else {
		cm_showLayer($('#'+childsId), duration);
		$('#'+switchId).attr('src', closeIcon);
		$('#treeIcon_' + treeId + '_' + elementId).css('background-image', 'url('+ bgImg + ')');
		setCookie("treeStatus_"+treeId+'_'+elementId, 'open');
	}
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++
//	table row selector (for popup selector tables)
//++++++++++++++++++++++++++++++++++++++++++++++++++++
function cm_handleRowSelector(row, type, target, value) {
	if ($(row).hasClass('rowSelected')) {
		if (type=="ELEM") {
			var tmp = target.split('.');
			var fld = document.forms[tmp[0]].elements[tmp[1]];
			if (fld.type=='select' || fld.type=='select-one') {
				for (var k=0; k<fld.options.length; k++) {
					if (fld.options[k].value==value) {
						fld.options[k].selected = true;
					}
				}
			}
			else if (type=='radio') {
				for (var k=0; k<fld.length; k++) {
					if (fld[k].value==value) {
						fld[k].checked==true;
					}
				}	
			}
			else if (type=='textarea') {
				fld.innerHTML = value;
			}
			else {
				fld.value = value;
			}
			ajaxBoxClose();
		}
		if (type=="PAGE") {
			window.location = target + value;
		}
	}
	else {	
		$('.rowSelector').each(function() {
			if ($(this).hasClass('rowSelected'))
				$(this).removeClass('rowSelected');
		});
		$(row).addClass('rowSelected');
	}
}


//++++++++++++++++++++++++++
//	form functions
//++++++++++++++++++++++++++

function setValueSubmit(formid, field, value) {
	document.forms[formid].elements[field].value = value;
	document.forms[formid].submit();
}

function cm_checkboxAll(elem, cl) {
	if ($(elem).attr('checked')) { 
		$('.'+cl).attr('checked', true);
	}
	else {
		$('.'+cl).attr('checked', false);
	}
}

function cm_enumAll(elem, cl) {
	var value = $(elem).val();
	$('select.'+cl).val(value);
}

function cm_setEnum(elem, value) {
	$('select#'+elem).val(value);
}

function cm_disableFields(cl, value) {
	$('.'+cl).attr('disabled', value);
}

function cm_readonlyFields(cl, value) {
	$('.'+cl).attr('readonly', value);
}

//****************************************************************
// form array handlers
//****************************************************************
function cm_reduceFormArrayEntry(e, msg) {
	if (confirm(msg))
		$('#'+e).remove();
}

function cm_cloneFormArrayEntry(id) {
	var c = $('#arrayCount_' + id).val();
	$('#arrayEntry_' + id + c).css('display', '');
	$('#arrayCount_' + id).val(parseInt(c)+1);
}



//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	INSTANT FORM VALIDATION
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var cm_exclusiveInstantForm = 'off';
function cm_openInstantForm(url, suffix, ident) {
 	
	if (cm_exclusiveInstantForm != 'off') {
		cm_closeInstantForm();
	}
	cm_exclusiveInstantForm = ident; 
	document.getElementById('instantContent_' + ident).style.display = 'none';
	cm_ajaxSimpleLoader(url + '&instant=showForm&' + suffix + '&ident=' + ident, 'instantForm_' + ident);

}

function cm_closeInstantForm() {
	document.getElementById('instantForm_' + cm_exclusiveInstantForm).innerHTML = '';
	document.getElementById('instantContent_' + cm_exclusiveInstantForm).style.display = '';
	cm_exclusiveInstantForm = 'off';
}

function cm_validateInstantForm(url, suffix, ident, fld) {
	if (ident!=cm_exclusiveInstantForm) {
		alert('ERROR in cm_validateInstantForm: bad ident.' + ident + ':' + cm_exclusiveInstantForm);
	}
	else {
		var fldvalue = document.forms["mikroForm"].elements[fld].value;
		var datastring = fld+"="+fldvalue;
		$.ajax({
			url: url + '&instant=validateForm&' + suffix + '&ident=' + ident,
			type: 'post',
			data: datastring,
			success: function(text) {
				if (text=="_CM_FORM_VALID_") {
					document.forms["mikroForm"].submit();
				}
				else {
					document.getElementById('instantForm_' + ident).innerHTML = text;
				}
			}
		 });
	}
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++
// ajax loaders
//++++++++++++++++++++++++++++++++++++++++++++++++++++
/* JUST LOAD */
function cm_ajaxSimpleLoader(url, target) {
	$.ajax({
		url: url,
		success: function(text) {
			document.getElementById(target).innerHTML = text;
		}
	 });
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++
//	OVERLAY
//++++++++++++++++++++++++++++++++++++++++++++++++++++
var cm_oBoxCounter = 0;
function cm_ajaxOverlayBoxLoader(url, args) {
	var contentElement = cm_makeOverlayBox(args);
	$.ajax({
		url: url,
		success: function(text) {
			contentElement.innerHTML = text;
			contentElement.style.display = 'block';
			postPositionElement(contentElement, args);
		}
	});
}
function cm_ajaxOverlayBoxLoader2(url, args) {
	var contentElement = cm_makeOverlayBox(args);
	$.ajax({
		url: url,
		success: function(text) {
			contentElement.innerHTML = text;
			contentElement.style.display = 'block';
			postPositionElement(contentElement, args);
			$(contentElement).bind('click', function(){
			    ajaxBoxClose();
			});			
		}
	});
}

function ajaxBoxClose() {
	$('#overlay-content'+cm_oBoxCounter).remove();
	$('#overlay-bgbox'+cm_oBoxCounter).remove();
	cm_oBoxCounter -= 1;
}

function cm_makeOverlayBox(args) {// args: top, left, [class, fixed, clickaway]
	cm_oBoxCounter += 1;
	if ($('#overlay-bgbox'+cm_oBoxCounter).length > 0) return false;
	
	var docSize = getDocSize();
	var layerElement = document.createElement("div");
	$(layerElement).attr({
		'id' : 'overlay-bgbox'+cm_oBoxCounter,
		'class' : 'overlay-bg'
	}).css({
		'z-index': '650'+cm_oBoxCounter+'0',
		'position': 'absolute',
		'top': '0px',
		'left': '0px', 
		'width': docSize.x+'px', 
		'height': docSize.y+'px'
	}).appendTo(document.body);
	
	if (args.indexOf('clickaway')>0) {
		layerElement.bind('click', function(){
		    ajaxBoxClose();
		});			
	}
	
	var a = args.split(' ');
	if (!a[2])
		a[2] = 'overlay-content';	
		
	var position = args.indexOf('fixed')>0 ? 'fixed' : 'absolute'; 
	var contentElement = document.createElement("div");
	$(contentElement).attr({
		'id': 'overlay-content'+cm_oBoxCounter,
		'class': a[2]
	}).css({
		'z-index': '650'+cm_oBoxCounter+'1',
		'display': 'none',
		'position': position
	}).appendTo(document.body);
	
	return contentElement;
}

function cm_makeDataString(formid) {
	var datastring = '';
	var skipfields = new Array();
	for (var i=0; i<document.forms[formid].elements.length; i++) {
		var tag = document.forms[formid].elements[i].tagName.toLowerCase();
		var type = document.forms[formid].elements[i].type;
		var name = document.forms[formid].elements[i].name;
		var value = '';
		if (type=='checkbox') {
			if (document.forms[formid].elements[i].checked==true)
				value = document.forms[formid].elements[i].value;
		}
		else if (type=='select' || type=='select-one') {
			var k = document.forms[formid].elements[i].selectedIndex;
			value = document.forms[formid].elements[i].options[k].value;
		}
		else if (type=='radio') {
			var r = document.forms[formid].elements[i];
			if (r.checked==true) value = r.value;
			else
				continue;
		}
		else if (type=='button' || tag=='fieldset') {
			continue;
		}
		else {
			value = document.forms[formid].elements[i].value;
		}		
		datastring += (datastring==''?'':'&') + escape(name) + '=' + escape(utf8_encode(value)); 		
	}
	return datastring;
}

function cm_overlayFormRequest(url, formid, args) {
	var datastring = cm_makeDataString(formid);
	var contentElement = cm_makeOverlayBox(args);	
	$.ajax({
		url: url,
		type: 'post',
		data: datastring,
		success: function(text) {
			contentElement.innerHTML = text;;
		}
	 });
}

function cm_validateOverlayAction(url, formid) {
	var datastring = cm_makeDataString(formid);
	$.ajax({
		url: url,
		type: 'post',
		data: datastring,
		success: function(text) {
			if (text.substr(0,15)=="_CM_FORM_SAVED_") {
				if (text.length>16)
					window.location = text.substr(16);
				else
					location.reload();
			}
			else if (text=="_CM_FORM_VALID_") {
				document.forms[formid].submit();
			}
			else {
				document.getElementById('overlay-content'+cm_oBoxCounter).innerHTML = text;
			}
		}
	 });
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// RESIZABLES
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

var // Configurables:
  Drag_increments = 10, // number of pixels that we grow by

  Min_Width =  10,   Max_Width  = 1200,
  Min_Height =  10,   Max_Height = 900
;

var New_width, New_height, Grip, Cursor_start_x, Cursor_start_y, TheCookie;
var Target, Orig_width, Orig_height;

function cm_resize_start (event, draggable, target_id, args) {

	Target = $('#'+target_id);
  
	a = args.split(' ');
	if (a[0]) {	Min_Width = a[0];	}
	if (a[1]) {	Max_Width = a[1];	}
	if (a[2]) {	Min_Height = a[2];	}
	if (a[3]) {	Max_Height = a[3];	}
	if (a[4]) {	Drag_increments = a[4];	}
	TheCookie = (a[5]=='cookie') ? target_id : '';

	//find draggable
	var el;
	if (event.target) el = event.target;
	else el = event.srcElement;
	if (el.nodeType == 3)  el = el.parentNode;
	while(el) {
    	if(el.tagName == "BODY" ) { el = false; break; }
    	if($(el).hasClass(draggable)) break; // found it!
    	el = el.parentNode;
  	}
  	if(!el) return false; // undraggable
  	Grip = el;

  	$(Grip).addClass("activedrag");

  	Cursor_start_x = event.clientX;
  	Cursor_start_y = event.clientY;
  	Orig_width   = $(Target).width();
  	Orig_height  = $(Target).height();

  	// Capture mousemove and mouseup events on the page.
  	if (document.addEventListener) {
		document.addEventListener ("mousemove", cm_resize_move, true);
		document.addEventListener ("mouseup", cm_resize_stop, true);
	} else if (document.attachEvent) {
		document.attachEvent ("onmousemove", cm_resize_move);
		document.attachEvent ("onmouseup", cm_resize_stop);
	} else {
		document.onmousemove = cm_resize_move;
		document.onmouseup = cm_resize_stop;
	}

  	if (event.preventDefault) event.preventDefault();
  	else event.returnValue = false;
  	return;
}


function cm_resize_move(event) {
   	New_width  = event.clientX - Cursor_start_x + Orig_width;
   	New_height = event.clientY - Cursor_start_y + Orig_height;

  	if (Max_Width>0) New_width  = constrain_range(Min_Width, New_width , Max_Width, Drag_increments);;
  	if (Max_Height>0) New_height = constrain_range(Min_Height, New_height, Max_Height, Drag_increments);;

  	if (Max_Width>0) $(Target).width(New_width);
  	if (Max_Height>0) $(Target).height(New_height);

  	if (event.preventDefault) event.preventDefault();
  	else event.returnValue = false;
  	
  	return;
}

function cm_resize_stop(event) {
  	// Stop capturing the mousemove and mouseup events.
  	$(Grip).removeClass("activedrag");
  	if (document.removeEventListener) {
		document.removeEventListener ("mousemove", cm_resize_move, true);
		document.removeEventListener ("mouseup", cm_resize_stop, true);
	} else if (document.detachEvent) {
		document.detachEvent ("onmousemove", cm_resize_move);
		document.detachEvent ("onmouseup", cm_resize_stop);
	} else {
		document.onmousemove = null;
		document.onmouseup = null;
	}
	if (TheCookie!='') {
  		if (Max_Width>0) setCookie(TheCookie + '_width', New_width);
  		if (Max_Height>0) setCookie(TheCookie + '_height', New_height);
  	}
  	return;
}

//------------------------------------------------------------
var multiTarget = new Array();
var multiOrig_width = new Array();
var multiOrig_height = new Array();

function cm_multiResize_start (event, draggable,  target_id, args) {

	multiTarget = $('.' + target_id);
  
	a = args.split(' ');
	if (a[0]!='') {	Min_Width = a[0];	}
	if (a[1]!='') {	Max_Width = a[1];	}
	if (a[2]!='') {	Min_Height = a[2];	}
	if (a[3]!='') {	Max_Height = a[3];	}
	if (a[4]!='') {	Drag_increments = a[4];	}
	TheCookie = (a[5]=='cookie') ? target_id : '';

	//find draggable
	var el = event.target;
	if (el.nodeType == document.TEXT_NODE)  el = el.parentNode;
	while(el) {
    	if(el.tagName == "BODY" ) { el = false; break; }
    	if($(el).hasClass(draggable)) break; // found it!
    	el = el.parentNode;
  	}
  	if(!el) return false; // undraggable
  	Grip = el;

	$(Grip).addClass("activedrag");

  	Cursor_start_x = event.clientX;
  	Cursor_start_y = event.clientY;
  	if (TheCookie!='') {
  		var w = parseInt(getCookie(TheCookie + '_width'));
  		Orig_width = (isNaN(w)) ? 0 : w;
  		var h = parseInt(getCookie(TheCookie + '_height'));
  		Orig_height = (isNaN(h)) ? 0 : h;
  	}
  	else {
  		Orig_width = 0;
  		Orig_height = 0;
  	}  	
  	multiTarget.each(function(index) {
  		multiOrig_width[index] = $(this).width();
  		multiOrig_height[index] = $(this).height();
  	});
  	
  	// Capture mousemove and mouseup events on the page.
  	document.addEventListener("mousemove", cm_multiResize_move, true);
  	document.addEventListener("mouseup",   cm_multiResize_stop, true);

  	event.preventDefault();
  	return;
}


function cm_multiResize_move(event) {
   	if (Max_Width>0) New_width  = event.clientX - Cursor_start_x + Orig_width;
   	if (Max_Height>0) New_height = event.clientY - Cursor_start_y + Orig_height;

  	if (Max_Width>0) New_width  = constrain_range(Min_Width, New_width , Max_Width, Drag_increments);;
  	if (Max_Height>0) New_height = constrain_range(Min_Height, New_height, Max_Height, Drag_increments);;

  	multiTarget.each(function(index) {
	  	if (Max_Width>0) $(this).width( parseInt(multiOrig_width[index]) + parseInt(New_width) - parseInt(Orig_width) );
	  	if (Max_Height>0) $(this).height( parseInt(multiOrig_height[index]) + parseInt(New_height) - parseInt(Orig_height) );
  	});

  	event.preventDefault();
  	return;
}

function cm_multiResize_stop(event) {
  	// Stop capturing the mousemove and mouseup events.
  	$(Grip).removeClass("activedrag");
  	document.removeEventListener("mousemove", cm_multiResize_move, true);
  	document.removeEventListener("mouseup",   cm_multiResize_stop, true);
  	if (TheCookie!='') {
  		if (Max_Width>0) setCookie(TheCookie + '_width', New_width);
  		if (Max_Height>0) setCookie(TheCookie + '_height', New_height);
  	}
  	return;
}



//****************************************************************
// TREE drag'n'drop elements
//****************************************************************

var cm_treeDraggedElement = null;
var cm_treeDroppedElement = null;
var cm_treeDraggedVisible = false;
var cm_treeDropPosition = "";

function cm_treeCreateDraggableImg(treeId, realId, urlPrefix) {
	if (cm_treeDraggedElement!=null)
		return;
		
	$(".treeDraggable_"+treeId).remove();

	cm_treeDraggedElement = null;
	cm_treeDroppedElement = null;
	cm_treeDraggedVisible = false;
	cm_treeDropPosition = "";
	
	var pos = $('#treeIconImg_'+treeId+"_"+realId).offset();
	var img = $('#treeIconImg_'+treeId+'_'+realId).attr('src');
	
	var theDragImg = document.createElement('div');
	$(theDragImg)
	.attr({
	    'id': 'treeDraggable_'+treeId+'_'+realId,
	    'class': "treeDraggable_"+treeId,
	    'unselectable': 'on'
	})
	.bind('mouseout', function() {
		cm_treeRemoveDraggableImg(treeId, realId);
	})
	.html('<img unselectable="on" src="'+img+'" alt="" border="0">')
	.css({
	   'border': 'none',//'2px solid #000',
	   'position': 'absolute',
	   'top': pos.top+'px',
	   'left': pos.left+'px',
	   'cursor': 'move',
	   'display': 'block',
	   'z-index': 9999
	})
	.insertAfter('#treeElement_'+treeId+"_"+realId);

	
	$(theDragImg).draggable({
		start: function () {
            $('#treeElement_'+treeId+'_'+realId).css("opacity", "0.6");
            $(theDragImg).unbind("mouseout");
            $(theDragImg).css("opacity", "0.6");
			cm_treeDraggedElement = $('#treeElement_'+treeId+'_'+realId);
			cm_treeDroppedElement = $('#treeElement_'+treeId+'_'+realId);
			cm_treeShowDragmarker(treeId);
		},
		drag: function () {
			cm_treeShowDragmarker(treeId);
		},
		stop: function () {
			cm_treeRemoveDraggableImg(treeId, realId);
            $('#treeElement_'+treeId+'_'+realId).css("opacity", "1");
			cm_treeDraggedElement = null;
			cm_treeDroppedElement = null;
			cm_treeDraggedVisible = false;
			cm_treeDropPosition = "";
		}
	});	
	$('.treeElementOf_'+treeId).droppable({
		over: function(event, ui) {
			cm_treeDraggedVisible = true;
			cm_treeDroppedElement = $(this);
			cm_treeShowDragmarker(treeId);
		},
		out: function(event, ui) {
			if ($('#treeDragmarker_'+treeId))
				 $('#treeDragmarker_'+treeId).remove();
			cm_treeDraggedVisible = false;
		},
		drop: function(event, ui) {
			cm_treeDropElement(treeId, ui.draggable, $(this), urlPrefix);
		}
	});
}

function cm_treeShowDragmarker(treeId) {

	if ($('#treeDragmarker_'+treeId).length>0 && !cm_treeDraggedVisible)
		 $('#treeDragmarker_'+treeId).remove();
	if (!cm_treeDraggedVisible)
		return;
		
	draggedElement = cm_treeDraggedElement;
	dropElement = cm_treeDroppedElement;
	
	var dm = $('#treeDragmarker_'+treeId);
	if (dm.length==0) {
		var dm = document.createElement('div');
		$(dm)
		.attr({'id' : 'treeDragmarker_'+treeId})
		.html('<font style="font-size:0px">&nbsp;</font>')
		.css({
		   'border': '2px solid #800000',
		   'position': 'absolute',
		   'top': '0px',
		   'left': '0px',
		   'display': 'none',
		   'z-index': '9999'
		})
		.insertAfter($(cm_treeDraggedElement));
	}
	if (dropElement.length>0) {
		var dropCoords = dropElement.offset();
		var dropHeight = dropElement.height();
		var tmp = dropElement.attr('id').split('treeElement_'+treeId+'_');
		var dropId = tmp[1];
		var dropIconCoords = $('#treeIconImg_'+treeId+'_'+dropId).offset();
		var dropIconWidth = $('#treeIconImg_'+treeId+'_'+dropId).width();
		var dropIconHeight = $('#treeIconImg_'+treeId+'_'+dropId).height();
		var zeropx = document.all ? 2 : 0;

		if (mouseY<dropCoords.top+dropHeight/3) { 
			cm_treeDropPosition = "above";
			$(dm).css({
			   'top': (dropCoords.top-2)+'px',
			   'left': dropIconCoords.left+'px',
			   'width': dropIconWidth+'px',
			   'height': zeropx+'px',
			   'display': 'block'
			});
		}
		else if (mouseY>dropCoords.top+dropHeight/3*2) {
			cm_treeDropPosition = "below";
			$(dm).css({
			   'top': (dropCoords.top+dropHeight-2)+'px',
			   'left': dropIconCoords.left+'px',
			   'width': dropIconWidth+'px',
			   'height': zeropx+'px',
			   'display': 'block'
			});
		}
		else {
			cm_treeDropPosition = "inside";
			$(dm).css({
			   'top': dropCoords.top+'px',
			   'left': dropIconCoords.left+'px',
			   'width': dropIconWidth+'px',
			   'height': dropIconHeight+'px',
			   'display': 'block'
			});
		}
	}
}

function cm_treeRemoveDraggableImg(treeId, realId) {
	$('#treeDraggable_'+treeId+'_'+realId).remove();
	$('.treeDraggable_'+treeId).remove();

	if ($('#treeDragmarker_'+treeId))
		 $('#treeDragmarker_'+treeId).remove();
}

var cm_treeDontDropAgain = false;
function cm_treeDropElement(treeId, dragElement, dropElement, urlPrefix) {
	if (cm_treeDontDropAgain)
		return;
	cm_treeDontDropAgain = true;
	var tmp1 = dropElement.attr('id').split('treeElement_'+treeId+'_');
	var dropId = tmp1[1];
	var tmp2 = dragElement.attr('id').split('treeDraggable_'+treeId+'_');
	var dragId = tmp2[1];
	window.location = urlPrefix+"&dropId="+dropId+"&dropPos="+cm_treeDropPosition;
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// drag and drop Elements
//
// handle: id of action handle
// dragPrefix + dragIdent: id of the dragged object
// dropTarget: class of droppables and their id followed by _ident
// urlPrefix: send drop success data to this url//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var cm_draggedElement = false;
var cm_dropElement = false;
var cm_draggingActive = false;

function cm_initElementDragAndDrop(handle, dragPrefix, dragIdent, dropTarget, urlPrefix) {
	if (cm_draggingActive)
		return;
		
	$('.theDragImg').remove();
	
	var pos = $('#'+handle).offset();
	
	var theDragImg = document.createElement('div');	
	$(theDragImg)
	.attr({
	    'id': 'theDragImg_'+dragIdent,
	    'class': 'theDragImg',
	    'unselectable': 'on'
	})
	.bind('mouseout', function() {
		cm_removeElemDragImg(dragIdent, dropTarget);
	})
	.html('<img unselectable="on" src="userfiles/images/actions/move.png" alt="" border="0">')
	.css({
	   'border': 'none',//'2px solid #000',
	   'position': 'absolute',
	   'top': pos.top+'px',
	   'left': pos.left+'px',
	   'cursor': 'move',
	   'display': 'block',
	   'z-index': 9999
	})
	.insertAfter('#'+handle);
	
	
	$(theDragImg).draggable({
		start: function () {
			cm_draggedElement = dragIdent;
            $(theDragImg).unbind("mouseout");
            $(theDragImg).css("opacity", "0.6");
            $('#'+dragPrefix+dragIdent).css("opacity", "0.6");
		},
		stop: function () {
			cm_removeElemDragImg(dragIdent, dropTarget);
            $('#'+dragPrefix+dragIdent).css("opacity", "1");
			cm_draggedElement = false;
			cm_dropElement = false;
			cm_draggingActive = false;
		}
	});	
	$('.'+dropTarget).droppable({
		over: function(event, ui) {
			cm_dropElement = $(this);
			$(this).css('background-color', '#800000');
		},
		out: function(event, ui) {
			cm_dropElement = false;
			$(this).css('background-color', '');
		},
		drop: function(event, ui) {
			cm_dragElementDrop(dragIdent, dropTarget, ui.draggable, $(this), urlPrefix);
			
		}
	});
	
}

function cm_removeElemDragImg(dragIdent, dropTarget) {
	$('#theDragImg_'+dragIdent).remove();
	$('.theDragImg').remove();
}


var cm_elemDontDropAgain = false;
function cm_dragElementDrop(dragIdent, dropTarget, dragElement, dropElement, urlPrefix) {
	if (cm_elemDontDropAgain)
		return;
	cm_elemDontDropAgain = true;
	var tmp1 = dropElement.attr('id').split(dropTarget + '_');
	var dropId = tmp1[1];
	var dragId = dragIdent;
	if (dragIdent==cm_draggedElement)
		window.location = urlPrefix+"&dragId="+dragId+"&dropId="+dropId;
}


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// helpers
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function constrain_range (min, i, max, incr) {
  if(incr)  i = Math.floor(i/incr) * incr;
  return(
	 (i > max) ? max
	:(i < min) ? min
        : i
  );
}

function postPositionElement(el, args) {
	var a = args.split(' ');
	var xx = a[0] ? a[0] : '50%';
	var yy = a[1] ? a[1] : '50%';
	var scrollPos = getScrollPos();
	var windowSize = getWindowSize();
	var width = $(el).width();
	var height = $(el).height();
	var pos = new Object();
	// left
	if (a[0].indexOf('%')>0) {
		xx = (parseInt(xx.substr(0, xx.indexOf('%'))) * 0.01 * windowSize.x + scrollPos.x ) - parseInt(0.5 * width); 
		if (xx<0) xx = 0;
	}
	else {
		if (xx.indexOf('px')>=0) { 
			xx = xx.substr(0, xx.indexOf('px'));
		}
		if (parseInt(xx)<0) { 
			xx = windowSize.x - parseInt(xx);
		}
		//xx = 1*xx + 1*scrollPos.x;
	}
	// top
	if (a[1].indexOf('%')>0) {
		yy = (parseInt(yy.substr(0, yy.indexOf('%'))) * 0.01 * windowSize.y + scrollPos.y ) - parseInt(0.5 * height);
		if (yy<0) yy = 0;
	}
	else {
		if (yy.indexOf('px')>=0) { 
			yy = yy.substr(0, yy.indexOf('px'));
		}
		if (parseInt(yy)<0) { 
			yy = windowSize.y - parseInt(yy);
		}
		//yy = 1*yy + 1*scrollPos.y;
	}
	pos.x = parseInt(xx) + 'px';
	pos.y = parseInt(yy) + 'px';
	$(el).css({
		'top': pos.y,
		'left': pos.x
	});
}


function utf8_encode (argString) {
    // Encodes an ISO-8859-1 string to UTF-8  
    // 
    // version: 1103.1210
    // discuss at: http://phpjs.org/functions/utf8_encode
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: sowberry
    // +    tweaked by: Jack
    // +   bugfixed by: Onno Marsman
    // +   improved by: Yves Sucaet
    // +   bugfixed by: Onno Marsman
    // +   bugfixed by: Ulrich
    // *     example 1: utf8_encode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'
    var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
    var utftext = "",
        start, end, stringl = 0;
 
    start = end = 0;
    stringl = string.length;
    for (var n = 0; n < stringl; n++) {
        var c1 = string.charCodeAt(n);
        var enc = null;
 
        if (c1 < 128) {
            end++;
        } else if (c1 > 127 && c1 < 2048) {
            enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
        } else {
            enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
        }
        if (enc !== null) {
            if (end > start) {
                utftext += string.slice(start, end);
            }
            utftext += enc;
            start = end = n + 1;
        }
    }
 
    if (end > start) {
        utftext += string.slice(start, stringl);
    }
 
    return utftext;
}

function utf8_decode ( str_data ) {
    // Converts a UTF-8 encoded string to ISO-8859-1  
    // 
    // version: 909.322
    // discuss at: http://phpjs.org/functions/utf8_decode    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +      input by: Aman Gupta
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Norman "zEh" Fuchs
    // +   bugfixed by: hitwork    // +   bugfixed by: Onno Marsman
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: utf8_decode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'    var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;
    return str_data;
    
    str_data += '';
    var i=0;
    var tmp_arr
    while ( i < str_data.length ) {        
    	c1 = str_data.charCodeAt(i);
        if (c1 < 128) {
            tmp_arr[ac++] = String.fromCharCode(c1);
            i++;
        } else if ((c1 > 191) && (c1 < 224)) {            
        	c2 = str_data.charCodeAt(i+1);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = str_data.charCodeAt(i+1);            
            c3 = str_data.charCodeAt(i+2);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    } 
    return tmp_arr.join('');
}


var Base64 = {
 
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = Base64._utf8_encode(input);
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
 
		}
 
		return output;
	},
 
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}
 
		output = Base64._utf8_decode(output);
 
		return output;
 
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
 
}
