/* YetAnotherShoutBox AJAX Javascript
 * author: Thomas Lorenz
 * Version: 2.0.2
 * http://www.freudeamgolfen.de
 */

var YaSB = new Class({
	
	options: {
		refresh: 4,
		base: '/modules/mod_yasb/',
		reverse:false
	},
	
	captcha : {},
	message : {},
	form:	{},
	chat:{},
	AJAX:{},
	smilyWdn:null,
	language :{
			TIMESTRING:'%s ago',
			YEAR:'year',
			YEARS:'years',
			MONTHS:'months',
			MONTH:'month',
			WEEKS:'weeks',
			WEEK:'week',
			DAY:'day',
			DAYS:'days',
			HOURS:'hours',
			HOUR:'hour',
			MINUTES:'minutes',
			MINUTE:'minute',
			LESSMINUTE:'less than 1 minute',
			JAVAWARNING:'Java need to be enabled for sound notifications.'
	},
	
	initialize: function(options){
		
		if(arguments.length > 1){
			this.language = arguments[1];
		}
		
		this.setOptions(options);
		this.captcha = new YaSB.Captcha({
			mediaBase:this.options.base+"media/"
		});
		
		this.message = new YaSB.Message();
		
		this.chat = new YaSB.Chat({reverse:this.options.reverse});
		this.chat.setLanguage(this.language);
		
		this.AJAX = new Json.Remote('index.php?option=com_yasb&task=jsonRequest&tmpl=component',{
			onComplete:this.handleResponce.create({bind:this})
		});
		
		this.form = new YaSB.Form();
		
		this.sound = new YaSB.Sound({
			mediaBase:this.options.base+"media/"
		});
		
		var al = $('yasb').getElements('a.yasbActionLink');
		for(var i=0;i<al.length;i++){
			al[i].href = "javascript:void(0);";
			al[i].addEvent('click',(function(event){
				event = new Event(event);
				var opts = Json.evaluate(event.target.rel) ;
				switch(opts.action){
				case 'smilies':
					this.toggleSmilies();
					break;
				case 'removeShout':
					this.removeShout(opts.id);
					break;
				case 'banShout':
					this.banShout(opts.id);
					break;
				}
			}).bind(this));
		}
		
		this.recieveShout.periodical(this.options.refresh * 1000,this);
		if($chk(this.form.text)) {
			
			this.form.text.addEvent('keydown',(function(event){
				if(event.keyCode == 13){
					this.sendText();
				}
				return false;
			}).bind(this));
			
			$('yasbChatForm').addEvent('submit',(function(event){
				event.preventDefault();
				this.sendText();
				return false;
			}).bind(this));
			
			$('yasbSubmit').addEvent('click',(function(){
				this.sendText();
				return false;
			}).bind(this));
		}
		if($chk(this.captcha.check) ){
			this.captcha.check.addEvent('keydown',(function(event){
				if(event.keyCode == 13){
					this.sendText();
				}
				return false;
			}).bind(this));
		}
		var media = document.getElementById('yasbMedia');
		if($chk(media)){
			if(!navigator.javaEnabled()){
				this.message.setMessage(this.language.JAVAWARNING,this.message.type.error);
			}
		}
	},
	setLanguage:function(language){
		this.language = $merge(this.language,language);
		this.chat.setLanguage(this.language);	
	},
	sendText:function(){
		if(!this.form.checkVars()){	return false; }
		if(!this.captcha.checkVars()){ return false;}
		this.AJAX.send($merge({request:'addShout'},this.form.getVars(),this.captcha.getVars()));
		this.message.hideMessage();
		this.form.reset();
		this.captcha.reset();
		return false;
	},
	handleResponce:function(responce){
		if(responce.status == 1){
			this.message.setMessage(responce.message,this.message.type.error);
		}else if(responce.status == 2){
			this.message.setMessage(responce.message,this.message.type.info);
		}
		switch(responce.request){
		case "getShout":
			for(var i = 0; i < responce.list.length;i++){
				this.form.insertPost(responce.list[i]);
				this.chat.insertPost(responce.list[i]);
			}
			if(responce.list.length>0){
				this.sound.notify();
			}
			this.chat.updateLastPost(this.form.timestamp.value,responce.now);
			break;
		case "addShout":
			if(responce.status == 0){
				this.message.hideMessage();
			}
			break;
		}
	},
	toggleSmilies:function(){
		if($chk(this.smilyWdn) ){
			if(!this.smilyWdn.closed){
				return;
			}
		}
		
		this.smilyWdn = window.open("index.php?option=com_yasb&view=smilies&tmpl=component",
				"smilyWindow",
				"toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,width=500,height=600,resizable=yes,dependent=yes");
		
	},	
	recieveShout:function(){
		var data = {
			request:'getShout'
		};
		data = $merge(data,this.form.getShoutRequestVars());
		this.AJAX.send(data);
	},
	removeShout:function(shoutId){
		var data = {
			request:'deleteShout',
			id:shoutId
			};
		this.AJAX.send(data);
	},
	banShout:function(shoutId){
		var data = {
			request:'banShout',
			id:shoutId
		};
		this.AJAX.send(data);
	}
});
YaSB.implement(new Options);

YaSB.Sound = new Class({
	options: {
		mediaBase: '/modules/mod_yasb/'
	},
	initialize:function(options){
		this.setOptions(options);
		
		this.image = $('yasbMediaImage');
		if(!$chk(this.image)){
			return;
		}
		
		this.value = parseInt(Cookie.get('yasbSound'));
		switch(this.value){
			case 1:
			case 2:
			case 3:
				break;
			default:
				this.value = 0;
		}
		Cookie.set('yasbSound',this.value,{duration:30});
		
		this.image.src = this.options.mediaBase+'speaker_'+this.value+'.png';
		this.image.addEvent('click',this.toggleSound.create({bind:this}));
		
		//load player applet
		this.player = new Element('object',{
			classid:"java:SoundPlayer.class",
			codebase:this.options.mediaBase, 
			id:"yasbSoundPlayer",
			width:"1px", 
			height:"1px" ,
			codetype:"application/java-applet"}
		);
		
		var param = new Element('param',{name:'volume',value:this.value});
		param.inject(this.player);
		this.player.$tmp = false;
		this.player.inject(document.body);	
	},
	toggleSound:function(){
		this.value++;
		this.value = this.value%4;
		this.image.src = this.options.mediaBase+'speaker_'+this.value+'.png';
		Cookie.set('yasbSound',this.value,{duration:30});
		try{
			this.player.setVolume(this.value+"");
		}catch (e) {}
	},
	notify:function(){
		if(!$chk(this.image)){
			return;
		}
		if(this.value > 0){
			try{
				this.player.play();
			}catch (e) {}
		}
	}
	
});
YaSB.Sound.implement(new Options);

YaSB.Form = new Class({
	name:null,
	text:null,
	idFld:null,
	timestamp:null,
	initialize:function(){
		this.name = $('yasbName');
		this.text = $('yasbText');
		this.idFld = $('yasbID');
		this.timestamp = $('yasbTime');
		
		if(!$chk(this.name) || !$chk(this.text)){
			return;
		}
		
		if( this.name.value== "" ){
			var name = Cookie.get('yasbUserName');
			if(name === false){
				name = 'guest_'+ Math.floor((Math.random() * 9000) + 1000);
			}
			this.name.value = name;
		}
		Cookie.set('yasbUserName',this.name.value,{duration:30});
		this.name.addEvent('change',function(){Cookie.set('yasbUserName',this.value,{duration:30});});
		
		var bbOpener = $('yasbBBPanelToggler');
		if(bbOpener){
			bbOpener.addEvent('click',function(){
				var bbpanel = $('yasbBBPanel');
				if(bbpanel.getStyle('display') == 'none'){
					bbpanel.setStyle('display','');
				}else{
					bbpanel.setStyle('display','none');
				}
			});
			var elems = $('yasbBBPanel').getElements('a.yasbBBInsert');
			for ( var i = 0; i < elems.length; i++) {
				elems[i].href='javascript:void(0);';
				elems[i].addEvent('click',function(){
					$('yasbText').insertAroundCursor(Json.evaluate( this.rel ),true);
				});
			}
		}
	},
	toggleBBPanel:function(){
		var bbpanel = $('yasbBBPanel');
		if(!$chk(bbpanel)){return;}
		if(bbpanel.getStyle('display') == 'none'){
			bbpanel.setStyle('display','');
		}else{
			bbpanel.setStyle('display','none');
		}
	},
	checkVars:function(){
		if(this.text.value.trim() == ''){
			this.text.focus();
			return false;
		}
		if(this.name.value.trim() == ''){
			this.name.focus();
			return false;
		}
		return true;
	},
	getVars:function(){
		return {
			name:this.name.value,
			text:this.text.value
		};
	},
	insertSmilie:function(smilie){
		$('yasbText').insertAtCursor(smilie,false);
	},
	
	getShoutRequestVars:function(){
		return {id:this.idFld.value};
	},
	insertPost:function(post){
		this.idFld.value = post.id;
		this.timestamp.value = post.timestamp;
	},
	reset:function(){
		this.text.value = "";
	}
});

YaSB.Captcha = new Class({
	options:{
		mediaBase:''
	},

	code: {},
	check: {},
	image: {},
	
	initialize:function(options){
		this.setOptions(options);
		
		this.check = $('yasbCheck');
		this.code = $('yasbCode');
		this.image = $('yasbCaptImg');
		this.reload();
		var reloadImage = $('yasbCaptReloadImg');
		if(reloadImage){
			reloadImage.addEvent('click',function(){yasb.captcha.reload();});
		}
	},
	reload:function(){
		if(!this.image){return;}
		var newCode = Math.floor(Math.random()*511)+2;
		this.image.setProperty('src',this.options.mediaBase+"captcha.php?code=" + newCode);
		this.code.setProperty('value',newCode);
	},
	reset:function(){
		if(!$chk(this.code) || !$chk(this.check)){
			return ;
		}
		this.reload();
		this.check.value = '';
	},
	checkVars:function(){
		if(!$chk(this.code) || !$chk(this.check)){
			return true;
		}
		if(this.check.value.trim()==""){
			this.check.focus();
			return false;
		}
		return true;
	},
	getVars:function(){
		if(!$chk(this.code) || !$chk(this.check)){
			return {};
		}
		return {
			code:this.code.getProperty('value'),
			check:this.check.getProperty('value')
		};
	}
});
YaSB.Captcha.implement(new Options);

YaSB.Message = new Class({
	type:{clear:0,info:1,error:2},
	element:{},
	initialize:function(){
		this.element = $('yasbMessage');
	},
	setMessage:function(msg,type){
		switch (type) {
			case this.type.info:
				this.element.set({'class':'yasbInfo','styles':{display:''}});
				this.element.setHTML(msg);
				break;
			case this.type.error:
				this.element.set({'class':'yasbError','styles':{display:''}});
				this.element.setHTML(msg);
				break;
			default: 
				this.element.empty();
				this.element.setStyle('display','none');
			break;
		}
	},
	hideMessage:function(){
		this.setMessage('',this.type.clear);
	}
});

YaSB.Chat = new Class({
	
	options:{
		reverse:false
	},
	
	language: {},
	lastPost: {},
	shoutList: {},
	
	initialize : function(options) {
		this.setOptions(options);

		this.shoutList = $('yasbShoutList');
		this.lastPost = $('yasbLastPost');
		
		if(this.options.reverse){
			var parent = this.shoutList.getParent();
			parent.scrollTo(0,parent.getSize().scrollSize.y);
		}
	},
	
	setLanguage: function(language){
		this.language = language;
	},
	
	updateLastPost:function(timestamp,now){
		if(!$chk(this.lastPost)){return;}
		var diff =  (now-timestamp);
		var ye = Math.floor(diff/(60*60*24*365)); 
		diff = diff % (60*60*24*365);
		var mo = Math.floor(diff/(60*60*24*30)); 
		diff = diff % (60*60*24*30);
		var we = Math.floor(diff/(60*60*24*7)); 
		diff = diff % (60*60*24*7);
		var da = Math.floor(diff/(60*60*24)); 
		diff = diff % (60*60*24);
		var ho = Math.floor(diff/(60*60)); 
		diff = diff % (60*60);
		var mi = Math.floor(diff/(60));
		
		var timeStr = '';
		if(ye>0){
			timeStr =  ye>1 ? (ye+" "+this.language.YEARS) : ("1 "+this.language.YEAR);
			if(mo>0){
				timeStr +=  mo>1 ? (", "+mo+" "+this.language.MONTHS) : (", 1 "+this.language.MONTH);
			}
		}else if(mo > 0){
			timeStr =  mo>1 ? (mo+" "+this.language.MONTHS) : ("1 "+this.language.MONTH);
			if(we>0){
				timeStr +=  we>1 ? (", "+we+" "+this.language.WEEKS) : (", 1 "+this.language.WEEK);
			}
		}else if(we > 0){
			timeStr =  we>1 ? (we+" "+this.language.WEEKS) : ("1 "+this.language.WEEK);
			if(da>0){
				timeStr +=  da>1 ? (", "+da+" "+this.language.DAYS) : (", 1 "+this.language.DAY);
			}
		}else if(da > 0){
			timeStr =  da>1 ? (da+" "+this.language.DAYS) : ("1 "+this.language.DAY);
			if(ho>0){
				timeStr +=  ho>1 ? (", "+ho+" "+this.language.HOURS) : (", 1 "+this.language.HOUR);
			}
		}else if(ho > 0){
			timeStr =  ho>1 ? (ho+" "+this.language.HOURS) : ("1 "+this.language.HOUR);
			if(mi>0){
				timeStr +=  mi>1 ? (", "+mi+" "+this.language.MINUTES) : (", 1 "+this.language.MINUTE);
			}
		}else{
			if(mi > 0){
				timeStr =  mi>1 ? (mi+" "+this.language.MINUTES) : ("1 "+this.language.MINUTE);
			}else{
				timeStr = this.language.LESSMINUTE;
			}
		}
		var htmlStr = this.language.TIMESTRING;
		htmlStr = htmlStr.replace(/%s/g, timeStr);
		
		this.lastPost.setHTML(htmlStr);	
	},
	insertPost:function(post){
		var listElem = new Element('li');
		listElem.setHTML(post.html);
		if(this.options.reverse){
			listElem.inject(this.shoutList,'bottom');
			var parent = this.shoutList.getParent();
			parent.scrollTo(0,parent.getSize().scrollSize.y);
		}else{
			listElem.inject(this.shoutList,'top');
		}
		
		
		var al = listElem.getElements('a.yasbActionLink');
		for(var i=0;i<al.length;i++){
			al[i].href = "javascript:void(0);";
			al[i].addEvent('click',function(event){
				event = new Event(event);
				var opts = Json.evaluate(event.target.rel) ;
				switch(opts.action){
				case 'removeShout':
					yasb.removeShout(opts.id);
					break;
				case 'banShout':
					yasb.banShout(opts.id);
					break;
				}
			});
		}
	}
});
YaSB.Chat.implement(new Options);

var ColorChooser = new Class({

	options: {
		insertFunction:function(start,end){
				$('yasbText').insertAroundCursor({before:start,after:end},true);
			},
		style:'yasbColorChooser',
		offsets: {'x': 16, 'y': 16}
	},

	initialize: function(elements, options){
		
		this.setOptions(options);
		this.toolTip = new Element('div', {
			'class': this.options.style,
			'styles': {
				'position': 'absolute',
				'top': '0',
				'left': '0',
				'visibility': 'hidden'
			}
		}).inject(document.body);
		
		this.wrapper = new Element('div').inject(this.toolTip);
		var hexC = ['00','33','66','99','cc','ff'];
		
		for(var r = 0;r<6;r++){
			for(var g = 0;g<6;g++){
				for(var b = 0;b<6;b++){
					var span = new Element('span',{
						'styles' : {'background-color':"#"+hexC[r]+hexC[g]+hexC[b]}
					});
					span.addEvent('click',function(event){
						event = new Event(event);
						var color = event.target.getStyle('background-color');
						var tag = this.toolTip.$tag;
						this.options.insertFunction('['+tag+'='+color+']', '[/'+tag+']');
						this.hide();
					}.bind(this));
					span.inject(this.wrapper);
				}
			}
		}
			
			
		$$(elements).each(this.build,this);
	
		$(document.body).addEvent('click',this.hide.bind(this));
	},

	build: function(el){
		el.href = 'javascript:void(0);';
		el.addEvent('click',function(event){
			var opts = Json.evaluate( event.currentTarget.rel);
			this.options.insertFunction('['+opts.tag+'=]', '[/'+opts.tag+']');
		}.bind(this));
		el.addEvent('contextmenu', function(event){
			revent = new Event(event);
			revent.stop();
			this.position(event.currentTarget);
			this.toolTip.$tag = Json.evaluate( event.currentTarget.rel ).tag;
			this.show();
		}.bind(this));
	},

	position: function(element){
		var pos = element.getPosition();
		this.toolTip.setStyles({
			'left': pos.x + this.options.offsets.x,
			'top': pos.y + this.options.offsets.y
		});
	},

	show: function(){
		this.toolTip.setStyle('visibility', 'visible');
	},

	hide: function(){
		this.toolTip.setStyle('visibility', 'hidden');
	}

});

ColorChooser.implement(new Events, new Options);

Element.TextSelection = {

	tidy: function(){
		//this.set('value', this.get('value').tidy());
	},

	getTextInRange: function(start, end){
		return this.value.substring(start, end);
	},

	getSelectedText: function(){
		if (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.getSelectionEnd());
		return document.selection.createRange().text;
	},

	getSelectedRange: function() {
		if ($defined(this.selectionStart)) return {start: this.selectionStart, end: this.selectionEnd};
		var pos = {start: 0, end: 0};
		var range = this.getDocument().selection.createRange();
		if (!range || range.parentElement() != this) return pos;
		var dup = range.duplicate();
		if (this.type == 'text') {
			pos.start = 0 - dup.moveStart('character', -100000);
			pos.end = pos.start + range.text.length;
		} else {
			var value = this.value;
			var offset = value.length;
			dup.moveToElementText(this);
			dup.setEndPoint('StartToEnd', range);
			if(dup.text.length) offset -= value.match(/[\n\r]*$/)[0].length;
			pos.end = offset - dup.text.length;
			dup.setEndPoint('StartToStart', range);
			pos.start = offset - dup.text.length;
		}
		return pos;
	},

	getSelectionStart: function(){
		return this.getSelectedRange().start;
	},

	getSelectionEnd: function(){
		return this.getSelectedRange().end;
	},

	setCaretPosition: function(pos){
		if (pos == 'end') pos = this.value.length;
		this.selectRange(pos, pos);
		return this;
	},

	getCaretPosition: function(){
		return this.getSelectedRange().start;
	},

	selectRange: function(start, end){
		if (this.setSelectionRange) {
			this.focus();
			this.setSelectionRange(start, end);
		} else {
			var value = this.value;
			var diff = value.substr(start, end - start).replace(/\r/g, '').length;
			start = value.substr(0, start).replace(/\r/g, '').length;
			var range = this.createTextRange();
			range.collapse(true);
			range.moveEnd('character', start + diff);
			range.moveStart('character', start);
			range.select();
		}
		return this;
	},

	insertAtCursor: function(value, select){
		var pos = this.getSelectedRange();
		var text = this.value;
		this.value = text.substring(0, pos.start) + value + text.substring(pos.end, text.length);
		if ($pick(select, true)) this.selectRange(pos.start, pos.start + value.length);
		else this.setCaretPosition(pos.start + value.length);
		return this;
	},

	insertAroundCursor: function(options, select){
		options = $extend({
			before: '',
			defaultMiddle: '',
			after: ''
		}, options);
		var value = this.getSelectedText() || options.defaultMiddle;
		var pos = this.getSelectedRange();
		var text = this.value;
		if (pos.start == pos.end){
			this.value=text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length);
			this.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length);
		} else {
			var current = text.substring(pos.start, pos.end);
			this.value= text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length);
			var selStart = pos.start + options.before.length;
			if ($pick(select, true)) this.selectRange(selStart, selStart + current.length);
			else this.setCaretPosition(selStart + text.length);
		}
		return this;
	}

};
Element.extend(Element.TextSelection);

