var prototypeGetFBWall=Class.create()
prototypeGetFBWall.prototype={
	 URLs:{
		graphBase:"https://graph.facebook.com/"
		,redirect:"/facebook_resources/redirect.php"
	}
	,PREFIXes:{
		callbackFunctionName:"prototypeGetFBWallCallBack"
	}
	,CLASSes:{
		 loading:"fb-wall fb-loading"
		,removeAfterFinish:"fb-loading"
	}
	
	,ACCESS_TOKEN:""

	,initialize:function(options){
		this.config={
			avatarAlternative:		'avatar-alternative.jpg',
			avatarExternal:			'avatar-external.jpg',
			id: 					'neosmart.gmbh',
			max:					5,
			showComments:			true,
			showGuestEntries:		true,
			translateAt:			'at',
			translateLikeThis:		'like this',
			translateLikesThis:		'likes this',
			translateErrorNoData:	'has not shared any information.',
			translatePeople:		'people',
			timeConversion:			24,
			useAvatarAlternative:	false,
			useAvatarExternal:		false,
			accessToken:			''
		}
		for(var prop in options){
			this.config[prop] = options[prop]
		}
		this.wrapperElem = null;
		this.dataObjs = null;
		this.baseData = null;
		
		
		if("category" in this.config){
			this.categoryReg = new RegExp(this.config["category"])
			this.config["max"]=100;
		}
		
		new Ajax.Request(
			 this.URLs.redirect+"?cache="+String((new Date).getTime())
			,{
				 method:"get"
				,onComplete:this.afterAjax.bind(this)
			}
		)
		Event.observe(document,"dom:loaded",this.loadFunction.bind(this),false);
	}
	,afterAjax:function(httpObj){
		this.ACCESS_TOKEN = httpObj.responseText.replace(/^access_token=/,"");
		if(this.ACCESS_TOKEN.length<1)  {
			window.setTimeout(function(){
				new Ajax.Request(
					 this.URLs.redirect+"?cache="+String((new Date).getTime())
					,{
						 method:"get"
						,onComplete:this.afterAjax.bind(this)
					}
				)
				Event.observe(document,"dom:loaded",this.loadFunction.bind(this),false);
			}.bind(this),5000)
			return;
		}
		
		var timeString = String((new Date).getTime());
	
		var callbackFunctionName = this.PREFIXes.callbackFunctionName + timeString
		this.jsonPURL = [
			this.URLs.graphBase ,this.config.id , "/feed?limit=",this.config.max,"&access_token=" , this.ACCESS_TOKEN , "&callback=" , callbackFunctionName ,"&_=", timeString
		].join("");
		this.jsonPURLbase = [
			this.URLs.graphBase ,this.config.id , "/?access_token=" , this.ACCESS_TOKEN , "&callback=" , callbackFunctionName,"base" ,"&_=", timeString,"base"
		].join("");

		window[callbackFunctionName] = this.jsonPCallBack.bind(this)
		window[callbackFunctionName+"base"] = this.jsonPCallBack_base.bind(this)

		
		if(this.wrapperElem!=null){
			this.calljsonP.bind(this)()
		} else {
			Event.observe(window,"load",function(){
				this.calljsonP.bind(this)()
			}.bind(this),false);
		}
			
	}
	,calljsonP:function(){
			[this.jsonPURL,this.jsonPURLbase].each(function(url){
				this.wrapperElem.appendChild(new Element("script",{type:"text/javascript",src:url }))
			}.bind(this))
	}
	,jsonPCallBack:function(jsonpObj){
		if(typeof(jsonpObj["error"])!="undefined") {
			this.onFailureFunction()
			return null;
		}
		this.dataObjs = jsonpObj["data"]
		this.fireFunction()
	}
	,jsonPCallBack_base:function(jsonpObj){
		if(typeof(jsonpObj["error"])!="undefined") {
			this.onFailureFunction()
			return null;
		}
		this.baseData = jsonpObj
		this.fireFunction()
	}
	,onFailureFunction:function(){
		alert("fail");		
	}
	,loadFunction:function(){
		var wrapperElem=$(this.config.wrapperID)
		if(wrapperElem==null) return null;
		
		wrapperElem.addClassName(this.CLASSes.loading)
		this.wrapperElem = wrapperElem
		
		this.fireFunction()
	}
	,fireFunction:function(){
		if(this.baseData==null || this.wrapperElem==null || this.dataObjs==null) return null;
			this.wrapperElem.style.display="none"
				try{
/*===*/
				var data = this.dataObjs
				var baseData = this.baseData
				var max = data.length;
				var thisAvatar, isBase, hasBaseLink, thisDesc;
				var output = "";
				//alert(max);
				var tempcount=0;
				for(var k=0;k<max;k++){
					if("category" in this.config){
						if(this.exists(data[k].message)){
							//if(data[k].message.indexOf(this.config["category"])==-1)
							if(data[k].message.match(this.categoryReg)==null)
						   		continue;
						} else {
							continue ;
						}
					}
					tempcount++;
					// Shortcut ------------------------------------------------------------------------------------------------------------------------------
					isBase = (data[k].from.id==baseData.id);
					hasBaseLink = isBase&&(this.exists(baseData.link));
					if(!this.config.showGuestEntries&&!isBase) continue;
					
					// Box -----------------------------------------------------------------------------------------------------------------------------------
					output += (k==0) ? '<div class="fb-wall-box fb-wall-box-first">' : '<div class="fb-wall-box">';
					output += '<a href="http://www.facebook.com/profile.php?id='+data[k].from.id+'" target="_blank">';
					output += '<img class="fb-wall-avatar" src="'+this.getAvatarURL(data[k].from.id)+'" />';
					output += '</a>';
					output += '<div class="fb-wall-data">';
					
					output += '<span class="fb-wall-message">';
					output += '<a href="http://www.facebook.com/profile.php?id='+data[k].from.id+'" class="fb-wall-message-from" target="_blank">'+data[k].from.name+'</a> ';
					if(this.exists(data[k].message)) output += this.modText(data[k].message);
					output += '</span>';
					
					// Media -----------------------------------------------------------------------------------------------------------------------------------
					if(this.exists(data[k].picture)||this.exists(data[k].link)||this.exists(data[k].caption)||this.exists(data[k].description)){
						output += this.exists(data[k].picture) ? '<div class="fb-wall-media">' : '<div class="fb-wall-media fb-wall-border-left">';
						if(this.exists(data[k].picture)){
							if(this.exists(data[k].link)) output += '<a href="'+data[k].link+'" target="_blank" class="fb-wall-media-link">';
							output += '<img class="fb-wall-picture" src="'+data[k].picture+'" />';
							if(this.exists(data[k].link)) output += '</a>';
						}
						output += '<div class="fb-wall-media-container">';
						if(this.exists(data[k].name)) output += '<a class="fb-wall-name" href="'+data[k].link+'" target="_blank">'+data[k].name+'</a>';
						if(this.exists(data[k].caption)) output += '<a class="fb-wall-caption" href="http://'+data[k].caption+'" target="_blank">'+data[k].caption+'</a>';
						if(this.exists(data[k].properties)){
							for(var p=0;p<data[k].properties.length;p++) output += (p==0) ? '<div>'+this.formatDate(data[k].properties[p].text)+'</div>' : '<div>'+data[k].properties[p].text+'</div>';
						}
						if(this.exists(data[k].description)){
							thisDesc = this.modText(data[k].description);
							if(thisDesc.length>299)thisDesc=thisDesc.substr(0,thisDesc.lastIndexOf(' '))+' ...';
							output += '<span class="fb-wall-description">'+thisDesc+'</span>';
						}
						output += '</div>';
						output += '</div>';
					}
					output += '<span class="fb-wall-date">';
					if(this.exists(data[k].icon)) output += '<img class="fb-wall-icon" src="'+data[k].icon+'" title="'+data[k].type+'" alt="" />';
					output += this.formatDate(data[k].created_time)+'</span>';					
				
					// Likes -------------------------------------------------------------------------------------------------------------------------------
					if(this.exists(data[k].likes)){
						if(parseInt(data[k].likes.count)==1){
							output += '<div class="fb-wall-likes"><div><span>'+data[k].likes.data[0].name+'</span> '+this.config.translateLikesThis+'</div> </div>';
						} else {
							output += '<div class="fb-wall-likes"><div><span>'+data[k].likes.count+' '+this.config.translatePeople+'</span> '+this.config.translateLikeThis+'</div> </div>';
						}
					}
					
					// Comments -------------------------------------------------------------------------------------------------------------------------------
					if(this.exists(data[k].comments) && this.exists(data[k].comments.data) && (this.config.showComments==true||this.config.showComments=='true')){
												
						output += '<div class="fb-wall-comments">';
						for(var c=0;c<data[k].comments.data.length;c++){
							output += '<span class="fb-wall-comment">';
							output += '<a href="http://www.facebook.com/profile.php?id='+data[k].comments.data[c].from.id+'" class="fb-wall-comment-avatar" target="_blank">';
							output += '<img src="'+this.getAvatarURL(data[k].comments.data[c].from.id)+'" />';
							output += '</a>';
							output += '<span class="fb-wall-comment-message">';
							output += '<a class="fb-wall-comment-from-name" href="http://www.facebook.com/profile.php?id='+data[k].comments.data[c].from.id+'" target="_blank">'+data[k].comments.data[c].from.name+'</a> ';
							output += this.modText(data[k].comments.data[c].message);
							output += '<span class="fb-wall-comment-from-date">'+this.formatDate(data[k].comments.data[c].created_time)+'</span>';
							output += '</span>';
							output += '</span>';
						}
						output += '</div>';
					}
					
					output += '</div>';
					output += '<div class="fb-wall-clean"></div>';
					output += '</div>';
				}
				
				// No data found --------------------------------------------------------------------------------------------
				if(max==0){
					output += '<div class="fb-wall-box-first">';
					output += '<img class="fb-wall-avatar" src="'+this.getAvatarURL(baseData.id)+'" />';
					output += '<div class="fb-wall-data">';
					output += '<span class="fb-wall-message"><span class="fb-wall-message-from">'+baseData.name+'</span> '+this.config.translateErrorNoData+'</span>';
					output += '</div>';
					output += '</div>';
				}
/*===*/
			//alert(tempcount);
			this.wrapperElem.update(output)
			new Effect.Appear(this.wrapperElem,{
				duration:0.7,
				afterFinish:function(){
					this.wrapperElem.removeClassName(this.CLASSes.removeAfterFinish)
				}.bind(this)
			});
		}catch(e){
			alert(e.lineNumber)
			alert(e.message)
		}
	}
	,exists:function (data){
		if(!data || data==null || data=='undefined' || typeof(data)=='undefined') return false;
		else return true;
	}
	
	,modText:function (text){
		return this.nl2br(this.autoLink(this.escapeTags(text)));
	}
	
	,escapeTags:function (str){
		return str.replace(/</g,'&lt;').replace(/>/g,'&gt;');
	}
	
	,nl2br:function (str){
		return str.replace(/(\r\n)|(\n\r)|\r|\n/g,"<br>");
	}
	
	,autoLink:function (str){
		return str.replace(/((http|https|ftp):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>))/g, '<a href="$1" target="_blank">$1</a>');
	}

	,getAvatarURL:function(id){
		var avatarURL;
		if(id==this.baseData.id){ avatarURL = (this.config.useAvatarAlternative) ? this.config.avatarAlternative : this.URLs.graphBase+id+'/picture?type=square'; }
		else{ avatarURL = (this.config.useAvatarExternal) ? this.config.avatarExternal : this.URLs.graphBase+id+'/picture?type=square'; }
		return avatarURL;
	}
	,formatDate:function(dateStr){
		var year, month, day, hour, minute, dateUTC, date, ampm, d, time;
		var iso = (dateStr.indexOf(' ')==-1&&dateStr.substr(4,1)=='-'&&dateStr.substr(7,1)=='-'&&dateStr.substr(10,1)=='T') ? true : false;

		if(iso){
			year = dateStr.substr(0,4);
			month = parseInt((dateStr.substr(5,1)=='0') ? dateStr.substr(6,1) : dateStr.substr(5,2))-1;
			day = dateStr.substr(8,2);
			hour = dateStr.substr(11,2);
			minute = dateStr.substr(14,2);
			dateUTC = Date.UTC(year, month, day, hour, minute);
			date = new Date(dateUTC);
		}else{
			d = dateStr.split(' ');
			if(d.length!=6||d[4]!='at')
				return dateStr;
			time = d[5].split(':');
			ampm = time[1].substr(2);
			minute = time[1].substr(0,2);
			hour = parseInt(time[0]);
			if(ampm=='pm')hour+=12;
			date = new Date(d[1]+' '+d[2]+' '+d[3] +' '+ hour+':'+minute);
			date.setTime(date.getTime()-(1000*60*60*7));
		}
		day = (date.getDate()<10)?'0'+date.getDate():date.getDate();
		month = date.getMonth()+1;
		month = (month<10)?'0'+month:month;
		hour = date.getHours();
		minute = (date.getMinutes()<10)?'0'+date.getMinutes():date.getMinutes();
		if(this.config.timeConversion==12){
			ampm = (hour<12) ? 'am' : 'pm';
			if(hour==0)hour==12;
			else if(hour>12)hour=hour-12;
			if(hour<10)hour='0'+hour;
			return day+'.'+month+'.'+date.getFullYear()+' at '+hour+':'+minute+' '+ampm;
		}
		return day+'.'+month+'.'+date.getFullYear()+' '+this.config.translateAt+' '+hour+':'+minute;
	}
}
