/*
Script: standard.js
	global Sipgate 2.0 Javascripts

	!!!!!!!!!!ATTENTION!!!!!!!!

	Ziemlich specked up from eingeloggten Bereich :-)
*/

/*
Function: getImagePath
	get the path for an image including domain

Arguments:
	image - the relative path to the image (optional)
*/
function getImagePath(image) {
	image = (image || "");
	//var imagepath=[ZendFramework.imagePath, image].join('');
	var imagepath=['/static/images/',image].join('');
	return imagepath;
}

var nq=new (new Class({
	domain: true,

	initialize: function() {
		this.logWindow=new Element('div', {
			'styles': {
			},
			'id':'nq_log_window'
		});

		this.logList=new Element('ul').injectTop(this.logWindow);
		this.closer=Asset.image(getImagePath('close_search.gif'),{'class':'nq_close'}).injectTop(this.logWindow);
		this.closer.addEvent('click', function() {
				this.logWindow.remove();
		}.bind(this));
		this.showInfo();
	},

	hide: function() {
		this.logWindow.remove();
	},

	showInfo: function () {
		var message='Dieses Fenster wird nur angezeigt, wenn Sie sich in der "NQ-Domain" befinden. Mit einem Klick auf den Briefumschlag wir der zuständige Entwickler über den Fehler informiert...';

		var msg=new Element('li',{'class':'nq_infotext'}).setText(message).injectTop(this.logList);
	},

	showLine: function(message, data, image, developer) {

		if (!ZendFramework.NQ_DOMAIN) return;
		if (ZendFramework.systemarea != 'dev') return;

		/* if (!$('debugInfo')) return; */

		var time = new Date();

		fullmessage='['+leadingZero(time.getHours())+':'+leadingZero(time.getMinutes())+'] '+message;

		var msg=new Element('li').setText(fullmessage).injectTop(this.logList);

		if (image) {
			var as = new Asset.image(getImagePath(image),{'class':'state_icon'}).injectTop(msg);
		}

		if (!developer) developer='lange-hegermann+jserr@sipgate.de';
		if (developer) {
			var body=data;
			if (ZendFramework) {
				var newdata='';
				//body=Json.toString(ZendFramework)+"\n"+data;
				$each(ZendFramework, function(value,key) {
						newdata+=key+':'+value+";\n";
				});
				body=newdata+"\n"+data;
			}

			var img = new Asset.image(getImagePath('email_go.png'),{'class':'forward_icon'}).injectTop(msg);
			img.addEvent('click', function(evnt) {
					trigger=new EmailTrigger(developer, {
						onConnect: function() {
							img.remove();
							var newimg = new Asset.image(getImagePath('settings/account/ok.gif'),{'class':'forward_icon'}).injectTop(msg);
						}
					}).execute('nq.bugreporter@sipgate.de', '[2.0 bug] '+message, body);
			});
		}

		this.logWindow.injectInside($(document.body));
	},

	log: function(message, data, developer) {
		
		if(typeof(ZendFramework)=='undefined') return;
		if (!ZendFramework.NQ_DOMAIN) return;
		if (ZendFramework.systemarea != 'dev') return;
		
		//this.showLine(message, $pick(data, ''), 'icon_info.gif', $pick(developer, null));
		if (console && console.log) {
			console.log(message);
		}
	},

	err: function(message, data, developer) {
		
		if (!ZendFramework.NQ_DOMAIN) return;
		if (ZendFramework.systemarea != 'dev') return;
		
		//this.showLine(message, $pick(data, ''), 'exclamation.png', $pick(developer, null));
		if (console && console.error) {
			console.error(message);
		}
	}
}))();


/*
Function: sgSuccessMessage
	shows an error message on the top of the Screen

Arguments:
	msg - Success message
	duration - message duration (optional)
*/
function sgSuccessMessage(msg, duration) {
	sgMessage(msg, duration, 'success_bar');
}

/*
Function: sgUserError
	shows an error in a lightbox

Arguments:
	err - Error message
*/
function sgUserError(err, althead) {
	var box = new SipgateModal({
		allowClose:true,
		moveable: false,
		icon:'failure'
	}).show($pick(althead ,lang.get('JS_ERROR_MESSAGE_HEADER')), err);
	return box;
}


/*
Function: sgUserWarning
	shows an error in a lightbox

Arguments:
	err - Error message
*/
function sgUserWarning(err, althead) {
	var box = new SipgateModal({
		allowClose:true,
		moveable: false,
		icon:'warning'
	}).show($pick(althead ,lang.get('JS_WARNING_MESSAGE_HEADER')), err);
	return box;
}

/*
Function: sgTemporaryUserError
	shows an error in a lightbox (and tells the user to try again)

Arguments:
	err - Error message
*/
function sgTemporaryUserError(err, althead) {
	return sgUserError(lang.get('JS_ERROR_TRY_AGAIN')+' '+err, althead);
}

/*
Function: sgErrorMessage
	shows an error message in the error log. NOT INTENDED FOR USER COMMUNICATION!!

Arguments:
	err - Error message
*/
function sgErrorMessage(err) {
	//sgMessage(err, duration, 'failed_bar');
	nq.err(err);
}

/*
Function: sgMessage
	shows an error message on the top of the Screen


Arguments:
	msg - Success message
	duration - message duration (can be null)
	cssclass - css class for the message div
*/
function sgMessage(msg, duration, cssclass) {
	/* better results with firebug */
	try {
		console.group(msg);
		console.trace();
		console.groupEnd();
	} catch(e) {

	}

	if (!duration) duration=5000;
	var errorDisplay=new Element('div');
	errorDisplay.addClass(cssclass);
	errorDisplay.setStyles({
		display:'block',
		visibility:'visible'
	});
	errorDisplay.setText(msg);

	errorDisplay.injectTop($('content_container'));

	(function () {
		errorDisplay.remove();
	}).delay(duration);
}

/*
Function: sgMicroError
	shows a tiny error in a corner of the screen (like google)
*/
function sgMicroError(err, duration) {
	if (!duration) duration=5000;
	var errorDisplay=new Element('div');
	errorDisplay.setStyles({
		left:10,
		top:2,
		border:'1px solid #ff0000',
		backgroundColor:'#ffcccc',
		position:'absolute',
		padding:2
	});

	errorDisplay.setText(err);

	errorDisplay.injectInside(document.body);

	(function () {
		errorDisplay.remove();
	}).delay(duration);
}

/*
Function: sgNQDebug
	shows a tiny error in a corner of the screen (like google)
	NEVER USE THIS WHEn YOU WANT THE USER TO SEE THE ERROR!!!!!!
*/
function sgNQDebug(err) {
	if (Cookie.get('NQDebug')) {
		sgMicroError('NQDebug: '+err);
	}
}

/*
Function: sgNQDebug
	sets a cookie, that enables NQDebug messages
*/
function enableNQDebug(state) {
	if (!state) Cookie.remove('NQDebug');
	else Cookie.set('NQDebug', state);
}


/*
Function: leadingZero
	fill a number with leading zeros util a certain length is reached

Arguments:
	num - the number
	length - destination length

Returns:
	string
*/
function leadingZero(num, length) {
	var numRep=num+"";

	if (!$type(length)) length=2;

	while (numRep.length<length) {
		numRep="0"+numRep;
	}

	return numRep;
}

Json.toString=function(obj){
	switch($type(obj)){
		case 'string':
			return '"' + obj.replace(/([\"\\])/g, '\\$1') + '"';
		case 'array':
			return '[' + obj.map(Json.toString).join(',') + ']';
		case 'object':
			var string = [];
			for (var property in obj) string.push(Json.toString(property) + ':' + Json.toString(obj[property]));
			return '{' + string.join(',') + '}';
		case 'number':
			if (isFinite(obj)) break;
		case 'element':
			return 'false';
		case false:
			return 'null';
	}
	return String(obj);
}
/*
Class: Hash
	additional functions for the Hash Class

Author:
	Stefan Lange-Hegermann (lange-hegermann@sipgate.de)
*/
Hash.implement({
	/*
	Property: toQueryString
		convert hash to query string

	Example:
		(start code)
		$H({}).toQueryString();
		(end)

	Returns:
		The query string.
	*/
	'toQueryString': function(){
		var queryString = [];
		this.each(function(value, name){
			if (value === false || !name) return;
			var qs = function(val){
				queryString.push(name + '=' + encodeURIComponent(val));
			};
			if ($type(value) == 'array') value.each(qs);
			else qs(value);
		});
		return queryString.join('&');
	}
});

/*
Class: Array
	additional functions for the Array Class

Author:
	Michael Rotmanov (rotmanov@sipgate.de)
*/
Array.extend({
	/*
	Property: toQueryString
		convert array to query string

	Example:
		(start code)
		["A","B","C"].toQueryString('example');
		(end)

	Returns:
		example[]="A"&example[]="B"&example[]="C"
		The query string.
	*/
	'toQueryString': function(name){
		var queryString = [];
		if(!$defined(name)) name = 'array';
		this.each(function(value, count){
			if (value === false) return;
			if($type(value) == 'object')
				queryString.push(name + '['+ count +']=' + $H(value).toQueryString());
			else
				queryString.push(name + '['+ count +']=' + encodeURIComponent(value));
		});
		return queryString.join('&');
	}
});

/*
Class: Element
	additional functions for the native Element Class

Author:
	Stefan Lange-Hegermann (lange-hegermann@sipgate.de)
*/
Element.extend({
	/*
	Property: emptyFast
		remove contents of an element much faster then Element.empty().
		Uses only setHTML('');

	Example:
		$('id').emptyFast(); // empties and returns the element
	*/
	emptyFast: function() {
		return this.setHTML('');
	},

	/*
	Property: cloneTemplate
		clone a template for immediate use
		(removes id and view_template class ans the returns a clone of the Element

	Example:
		$('my_view_template').cloneTemplate().injectInside(document.body);
	*/
	cloneTemplate: function(data) {
		//if (!data) {
			return (this.clone(true).removeProperty('id').removeClass('view_template'));
		//}

		var newElement=this.clone(true).removeProperty('id').removeClass('view_template');

		var _fillElement=function(element, data) {
			[element.title, element.name, element.value, element.innerHTML].each(function(property) {
				console.log(property);
			});
		};
	},

	/*
	Property: getDimensions
		get size of an invisible element

	Example:
		$('id').getDimensions().y;  // returns height of the element

	Returns:
		(start code)
		{
			'y': 100,
			'x': 200
		}
		(end)
	*/
	getDimensions: function(options) {
		options = $merge({computeSize: false},options);
		var dim = {};
		function getSize(el, options){
			if(options.computeSize) dim = el.getComputedSize(options);
			else {
				dim.width = el.getSize().size.x;
				dim.height = el.getSize().size.y;
			}
			return dim;
		}
		try { //safari sometimes crashes here, so catch it
			dim = getSize(this, options);
		} catch(e) {}
		if(this.getStyle('display') == 'none'){
			var before = {};
			//use this method instead of getStyles
			['visibility', 'display', 'position'].each(function(style){
				before[style] = this.style[style]||'';
			}, this);
			//this.getStyles('visibility', 'display', 'position');
			this.setStyles({
				visibility: 'hidden',
				display: 'block',
				position:'absolute'
			});
			var b = this.clone(true).injectAfter(this);
			dim = getSize(b, options); //works now, because the display isn't none
			b.remove();
			this.setStyles(before); //put it back where it was
		}
		return $merge(dim, {x: dim.width, y: dim.height});
	},

	'up': function(elements, index){
		var index = $pick(index, 1);
		var parent = $(this);

		if (typeof(elements) == 'number') {
			for(i=0; i<elements; i++) {
				parent = parent.getParent();
			}
			return $(parent);
		}

		elements = $$(elements);
		while ((parent = parent.getParent())) {
			if(parent.tagName == 'HTML') return null;
			if (elements.contains(parent)) index--;
			if (!index) return $(parent);
		}
		return null;
	},

	'down': function(elements, index) {
		if (!index) index=0;

		return this.getElements(elements)[index];
	},


	/*
	Property: toggle
		toggle element visibility

	Example:
		(start code)
		$('id').toggle()
		(end)

	Returns:
		true, when the element is now visible
	*/
	'toggle': function(){
		if (this.getStyle('display') != 'inline') {
			this.setStyles({'display':'inline','visibility':'visible'});
			return true;
		} else {
			this.setStyles({'display':'none','visibility':'hidden'});
			return false;
		}
	},

	/*
	Property: update
		prototype compatibility function
	*/
	'update': function(value) {
		this.setHTML(value);
	},

	/*
	Property: hide
		prototype compatibility function
	*/
	'hide': function() {
		this.setStyles({'display':'none','visibility':'hidden'});
	},

	/*
	Property: show
		prototype compatibility function
	*/
	'show': function(display) {
		if (!display) display='inline';
		this.setStyles({'display':display,'visibility':'visible'});
	},

	/*
	Property: cursorPos
		gets cursor position in text fields and textareas

	Returns:
		the position
	*/
	'cursorPos': function() {
		return this.selectionStart;
	},

	/*
	Property: cloneWithEvents
		clones elements with its origin events

	Returns:
		element
	*/
	cloneWithEvents: function() {
		var clone = this.clone().cloneEvents(this);
		var clone_in = this.getElementsByTagName('*');
		var clone_out = clone.getElementsByTagName('*');
		$A(clone_in).each(function(el, i) {
			if (el.$events) $(clone_out[i]).cloneEvents(el);
		});
		return clone;
	}

});
		
/*
Class: String
	additional functions for the native String Class

Author:
	Stefan Lange-Hegermann (lange-hegermann@sipgate.de)
*/
String.extend({

	'replaceAll': function(pcFrom,pcTo) {
		var i = this.indexOf(pcFrom);
		var c = this;

		while (i > -1){
		c = c.replace(pcFrom, pcTo);
		i = c.indexOf(pcFrom);
		}
		return c;
	},
	/*
	Property: addSlashes
		escape string with backslashes

	Returns:
		escaped string
	*/
	'addSlashes': function() {
		var str = this.replace(/\'/g,'\\\'');
		str = str.replace(/\\/g,'\\\\');
		str = str.replace(/\"/g,'\\"');
		str = str.replace(/\0/g,'\\0');

		// RegExp
		str = str.replace(/\(/g,'\\(');
		str = str.replace(/\)/g,'\\)');
		str = str.replace(/\*/g,'\\*');
		str = str.replace(/\+/g,'\\+');
		str = str.replace(/\[/g,'\\[');
		str = str.replace(/\]/g,'\\]');
		str = str.replace(/\./g,'\\.');

		return str;
	},

	/*
	Property: truncate
		Truncate a string to a certain length if necessary,
	 	optionally splitting in the middle of a word, and
		appending the etc string into the middle.

	Author:
		Monte Ohrt <monte at ohrt dot com>
		ported to Javascript by Michael Rotmanov <rotmanov@sipgate.de>

	Arguments:
		- len: length of result
		- etc: string to append (e.g. '...')
		- break_words: true or false for breaking the words in the middle

	Returns:
		truncated string
	*/
	'truncate': function (len, etc, break_words) {
		if (len == 0) len = 80;
	    if (etc == '') 	etc = '...';

	    if (this.length > len) {
	        len -= etc.length;
	        if (!break_words) {
	        	return this.substr(0, len+1).replace(/\s+?(\S+)?$/,'') + etc;
	        } else {
	            return this.substr(0, len) + etc;
	        }
	    } else {
	        return this;
	    }
	},
	'getTextWidth': function () {

		var tempEl = new Element('span').setText(this);

		tempEl.setStyles({
			visibility: 'hidden',
			display: 'block',
			position:'absolute'
		});
		tempEl.injectInside(document.body);
		var dim = tempEl.getSize(); //works now, because the display isn't none
		tempEl.remove();

		return dim.size.x;
	},
	'truncateAtWidth': function(width) {

		/* long version */
		/*
		var textwidth = (this+'...').getTextWidth();

		var pxPerChar = textwidth / (this+'...').length;

		var desiredCharCount = Math.floor(width / pxPerChar);
		*/

		/* short version */
		if(this.getTextWidth() < width)
			return this;
		else
			return this.truncate(Math.floor(width / ((this+'...').getTextWidth() / (this+'...').length)-1), '...', true);

	},
	'reverse': function() {
		var newstring = "";
		for (var s=0; s < this.length; s++) {
			newstring = this.charAt(s) + newstring;
		}
		return newstring;
	}
});

var lang=new (new Class({
	get: function(key) {
		return key;
	},
	hasKey: function() { return false; }
})); 

