/*
 * zoolib.js
 *
 * Javascript library for zoo.gr
 */

Zoo = window.Zoo || {};

Zoo.Event = window.Zoo.Event || {
	_handlers: {},

	subscribe: function(event, handler) {
		if(!this._handlers[event])
			this._handlers[event] = [];
		this._handlers[event].push(handler);
	},

	_fire: function(event) {
		var handlers = this._handlers[event];
		if(!handlers) return;

		var i;
		for(i = 0; i < handlers.length; i++)
			handlers[i]();
	}
};

Zoo.FB = window.Zoo.FB || {
	_inited: false,
	_onWindowBlock: null,

	_appId: null,
	_useXfbml: null,
	_forcePopup: null,

	// we wrap window.open to detect if a window is blocked
	_window_open: function(url, name, specs, replace) {
		// NOTE: this = window
		var handler = window._fb_open(url, name, specs, replace);

		var blocked = !handler || handler.closed || typeof handler.closed == 'undefined';
		if(blocked && Zoo.FB._onWindowBlock)
			Zoo.FB._onWindowBlock();
		Zoo.FB._onWindowBlock = null;

		return handler;
	},

	// loads facebook library
	init: function(options) {
		this._appId = options.appId;
		this._useXfbml = options.useXfbml;
		this._forcePopup = options.forcePopup;
		this._locale = options.locale;

		// this is called by facebook after initialization
		window.fbAsyncInit = function() {
			FB.init({
				appId  : Zoo.FB._appId,		// must be set in the page the loads this script
				status : !Zoo.FB._forcePopup,// we need this for iframe dialogs for some reason
				cookie : true,				// enable cookies to allow the server to access the session
				xfbml  : Zoo.FB._useXfbml,	// parse XFBML, must be set in the page the loads this script
				channelUrl : location.protocol + '//' + location.hostname + '/channel.html',
				frictionlessRequests : true
			});

			window.fbAsyncInit = null;
			Zoo.FB._inited = true;

			Zoo.Event._fire('Zoo.FB.init');
		};

		// this loads the library
		var e = document.createElement('script');
		e.src = document.location.protocol + '//connect.facebook.net/' + Zoo.FB._locale + '/all.js';
		e.async = true;
		document.getElementById('fb-root').appendChild(e);
	},

	login: function(resultHandler) {
		if(!this._inited) {
			this._sendResult(resultHandler, { status: 'not_inited' });
			return;
		};

		var opt = { scope: 'email' };

		this._onWindowBlock = function() {
			this._sendResult(resultHandler, { status: 'blocked' });
		};
		FB.login(function(response) {
			Zoo.Util.log('FB.login response', response);

			Zoo.FB._onWindowBlock = null;
			var res = { status: response.authResponse ? 'ok' : 'cancelled' };
			Zoo.FB._sendResult(resultHandler, res);
		}, opt);
	},

	getPermissions: function(resultHandler, perms) {
		if(!this._inited) {
			this._sendResult(resultHandler, { status: 'not_inited' });
			return;
		};

		var opt = {
			scope: perms.join(','),
			display: this._forcePopup ? 'popup' : 'iframe'
		};

		this._onWindowBlock = function() {
			this._sendResult(resultHandler, { status: 'blocked' });
		};
		FB.login(function(response) {
			Zoo.Util.log('FB.login response', response);

			// check that the user game the requested permissions
			//
			FB.api('/me/permissions', function(response) {
				var res = { status: 'ok' };
				for(var i = 0; i < perms.length; i++) {
					if(!response.data[0][perms[i]]) {
						res.status = 'cancelled';
						break;
					}
				}

				Zoo.FB._onWindowBlock = null;
				Zoo.FB._sendResult(resultHandler, res);
			});
		}, opt);
	},

	refreshLoginState: function(resultHandler) {
		if(!this._inited) {
			this._sendResult(resultHandler, { status: 'not_inited' });
			return;
		};

		FB.getLoginStatus(function(response) {
			var res = { status: 'ok' };
			Zoo.FB._sendResult(resultHandler, res);
		}, true); // force
	},

	// obsolete, 2delete
	getEmailPermission: function(resultHandler) {
		return this.login(resultHandler);
	},

	// deprecated
	streamPublish: function(resultHandler, params) {
		params.method = 'stream.publish';
		params.display = this._forcePopup ? 'popup' : 'iframe';

		this._onWindowBlock = function() {
			this._sendResult(resultHandler, { status: 'blocked' });
		};
		FB.ui(params, function(response) {
			Zoo.FB._onWindowBlock = null;
			var res = { status: response && response.post_id ? 'ok' : 'cancelled' };
			Zoo.FB._sendResult(resultHandler, res);
		});
	},

	/* uiFeed
	params: {
		link: 'http://google.com/',
		picture: 'http://upload.wikimedia.org/wikipedia/commons/b/bc/Sdf_060304.jpg',
		name: 'The name',
		caption: 'The caption <b>bold</b> <a href="www.google.com">link</a>',
		description: 'The description <b>bold</b> <a href="www.google.com">link</a>',
		properties: {
			Property1: 'no link',
			Property2: { text: 'with link', href: 'http://www.google.com' }
		},
		actions: [
			{ name: 'Action1', link: 'http://www.google.com' }
		],
		ref: 'test',
		to: null
	}
	*/
	uiFeed: function(resultHandler, params) {
		if(!params.ref) throw 'params.ref is needed';

		params.method = 'feed';
		params.display = this._forcePopup ? 'popup' : 'iframe';

		this._onWindowBlock = function() {
			this._sendResult(resultHandler, { status: 'blocked' });
		};
		FB.ui(params, function(response) {
			Zoo.FB._onWindowBlock = null;
			var res = { status: response && response.post_id ? 'ok' : 'cancelled' };
			Zoo.FB._sendResult(resultHandler, res);
		});
	},

	/* uiAppRequest
	params: {
		message: 'a message',
		title: 'a title',
		to: '100003439138397,100003432803002',
		filters: '',
		exclude_ids: [],
		max_recipients: 20,
		data: 'test'
	}
	*/
	uiAppRequest: function(resultHandler, params) {
		params.method = 'apprequests';
		params.display = this._forcePopup ? 'popup' : 'iframe';

		this._onWindowBlock = function() {
			this._sendResult(resultHandler, { status: 'blocked' });
		};
		FB.ui(params, function(response) {
			Zoo.FB._onWindowBlock = null;
			var res = { status: response && response.request ? 'ok' : 'cancelled' };
			Zoo.FB._sendResult(resultHandler, res);
		});
	},


	// deprecated
	shareLink: function(resultHandler, url) {
		this.uiSend(resultHandler, { link: url });
	},

	/* uiSend
	params: {
		link: 'http://www.google.com',
		name: 'foo',
		description: '...',
		picture: 'http://upload.wikimedia.org/wikipedia/commons/b/bc/Sdf_060304.jpg',
		to: '100003432803002'
	};
	*/
	uiSend: function(resultHandler, params) {
		params.method = 'feed';
		params.display = this._forcePopup ? 'popup' : 'iframe';

		this._onWindowBlock = function() {
			this._sendResult(resultHandler, { status: 'blocked' });
		};
		FB.ui(params, function(response) {
			Zoo.FB._onWindowBlock = null;
			var res = { status: response && response.post_id ? 'ok' : 'cancelled' };
			Zoo.FB._sendResult(resultHandler, res);
		});
	},

	pay: function(resultHandler, order_info) {
		var params = {
			method: 'pay',
			order_info: order_info,
			purchase_type: 'item',
			dev_purchase_params: {'oscif': true}
		};
		this._onWindowBlock = function() {
			this._sendResult(resultHandler, { status: 'blocked' });
		};
		FB.ui(params, function(response) {
			Zoo.FB._onWindowBlock = null;
			var res = { status: response && response.order_id ? 'ok' : 'cancelled' };
			Zoo.FB._sendResult(resultHandler, res);
		});
	},

	// generic dialog for inviting new friends
	//
	inviteFriends: function() {
		this.uiAppRequest(null, { message: ' ', filters: ['app_non_users', 'all'] });
	},

	_sendResult: function(handler, res) {
		if(handler) {
			var swf = document.getElementById('zoo_swf');
			swf[handler](res);
		}
	}
};

Zoo.Canvas = window.Zoo.Canvas || {
	autoResize: function() {
		window.onresize = function() {
			FB.Canvas.getPageInfo(
				function(info) {
					Zoo.Util.log('FB.Canvas.getPageInfo', info);
					document.getElementById('zoo_swf').style.height = (info.clientHeight - info.offsetTop) + 'px';
					FB.Canvas.setSize();
				}
			);
		};
		Zoo.Event.subscribe('Zoo.FB.init', window.onresize);
	},

	forwardWheelEvents: function() {
		// set event handler
		if(window.addEventListener)
			window.addEventListener("DOMMouseScroll", this._handleWheel, false);
		if (document.attachEvent)	//if IE (and Opera depending on user setting)
			document.attachEvent('onmousewheel', this._hadleWheel);
		window.onmousewheel = document.onmousewheel = this._handleWheel;
	},

	_handleWheel : function(e) {
		var swf = document.getElementById('zoo_swf');
		swf.handleWheel({
			x: e.screenX,
			y: e.screenY,
			delta: e.detail,
			ctrlKey: e.ctrlKey,
			altKey: e.altKey,
			shiftKey: e.shiftKey
		});

		// cancel the event's default behaviour
		if(e.preventDefault) e.preventDefault();	// necessary for addEventListener, works with traditional
		e.returnValue = false; 						// necessary for attachEvent, works with traditional
		return false;								// works with traditional, not with attachEvent or addEventListener	
	}
};

Zoo.Util = window.Zoo.Util || {
	_blank_windows: {},

	log: function(a, b, c, d, e) {
		if(window.console) {
			// IE does not like console.log.apply
			window.console.log(a, b||'', c||'', d||'', e||'');
		}
	},

	openWindow: function(url, options, name) {
		if(this._blank_windows[name]) {
			// use blank window
			this._blank_windows[name].location = url;
			this._blank_windows[name].focus();
			delete this._blank_windows[name];

		} else if(!url) {
			// open blank window
			this._blank_windows[name] = window.open('', '_blank', options);

		} else {
			window.open(url, name || '_blank', options);
		}
	}
};

Zoo.Storage = window.Zoo.Storage || {
	_get_store: function() {
		if(!this._store) {
			Persist.remove('flash');
			this._store = new Persist.Store('Zoo');
		}
		return this._store;
	},

	get: function(key) {
		var v = this._get_store().get(key);
		try {
			v = JSON.parse(v);
		} catch(e) {
			Zoo.Util.log('Zoo.Storage.get', 'cannot parse "'+v+'": '+e);
			v = null;
		}
		return v;
	},

	set: function(key, value) {
		if(value === undefined)
			value = null;
		var v = JSON.stringify(value);
		this._get_store().set(key, v);
	}
};

Zoo.Analytics = window.Zoo.Analytics || {
	init: function(options) {
		var domain = '.' + document.domain.match(/[^.]*\.[^.]*$/)[0];		// top-level domain

		window._gaq = window._gaq || [];
		_gaq.push(['_setAccount', options.account]);
		_gaq.push(['_setDomainName', domain]);
		_gaq.push(['_trackPageview']);

		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

		Zoo.Util.log('Zoo.Analytics.init', options);
	},

	trackPageview: function(url) {
		_gaq.push(['_trackPageview', url]);

		Zoo.Util.log('Zoo.Analytics.trackPageview', url);
	}
}

// we wrap window.open to detect if a window is blocked
window._fb_open = window.open;
window.open = Zoo.FB._window_open;

// for compatibility we have a top-level openWindow
window.openWindow = Zoo.Util.openWindow;


/*** embed libraries to avoid having too many .js files ***/
/* json2.js 
 * 2008-01-17
 * Public Domain
 * No warranty expressed or implied. Use at your own risk.
 * See http://www.JSON.org/js.html
*/
if(!this.JSON){JSON=function(){function f(n){return n<10?'0'+n:n;}
Date.prototype.toJSON=function(){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};function stringify(value,whitelist){var a,i,k,l,r=/["\\\x00-\x1f\x7f-\x9f]/g,v;switch(typeof value){case'string':return r.test(value)?'"'+value.replace(r,function(a){var c=m[a];if(c){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+
(c%16).toString(16);})+'"':'"'+value+'"';case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
if(typeof value.toJSON==='function'){return stringify(value.toJSON());}
a=[];if(typeof value.length==='number'&&!(value.propertyIsEnumerable('length'))){l=value.length;for(i=0;i<l;i+=1){a.push(stringify(value[i],whitelist)||'null');}
return'['+a.join(',')+']';}
if(whitelist){l=whitelist.length;for(i=0;i<l;i+=1){k=whitelist[i];if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}else{for(k in value){if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}
return'{'+a.join(',')+'}';}}
return{stringify:stringify,parse:function(text,filter){var j;function walk(k,v){var i,n;if(v&&typeof v==='object'){for(i in v){if(Object.prototype.hasOwnProperty.apply(v,[i])){n=walk(i,v[i]);if(n!==undefined){v[i]=n;}}}}
return filter(k,v);}
if(/^[\],:{}\s]*$/.test(text.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof filter==='function'?walk('',j):j;}
throw new SyntaxError('parseJSON');}};}();}

/* persist-min.js */
(function(){if(window.google&&google.gears)
return;var F=null;if(typeof GearsFactory!='undefined'){F=new GearsFactory();}else{try{F=new ActiveXObject('Gears.Factory');if(F.getBuildInfo().indexOf('ie_mobile')!=-1)
F.privateSetGlobalObject(this);}catch(e){if((typeof navigator.mimeTypes!='undefined')&&navigator.mimeTypes["application/x-googlegears"]){F=document.createElement("object");F.style.display="none";F.width=0;F.height=0;F.type="application/x-googlegears";document.documentElement.appendChild(F);}}}
if(!F)
return;if(!window.google)
google={};if(!google.gears)
google.gears={factory:F};})();Persist=(function(){var VERSION='0.2.0',P,B,esc,init,empty,ec;ec=(function(){var EPOCH='Thu, 01-Jan-1970 00:00:01 GMT',RATIO=1000*60*60*24,KEYS=['expires','path','domain'],esc=escape,un=unescape,doc=document,me;var get_now=function(){var r=new Date();r.setTime(r.getTime());return r;}
var cookify=function(c_key,c_val){var i,key,val,r=[],opt=(arguments.length>2)?arguments[2]:{};r.push(esc(c_key)+'='+esc(c_val));for(i=0;i<KEYS.length;i++){key=KEYS[i];if(val=opt[key])
r.push(key+'='+val);}
if(opt.secure)
r.push('secure');return r.join('; ');}
var alive=function(){var k='__EC_TEST__',v=new Date();v=v.toGMTString();this.set(k,v);this.enabled=(this.remove(k)==v);return this.enabled;}
me={set:function(key,val){var opt=(arguments.length>2)?arguments[2]:{},now=get_now(),expire_at,cfg={};if(opt.expires){var expires=opt.expires*RATIO;cfg.expires=new Date(now.getTime()+expires);cfg.expires=cfg.expires.toGMTString();}
var keys=['path','domain','secure'];for(i=0;i<keys.length;i++)
if(opt[keys[i]])
cfg[keys[i]]=opt[keys[i]];var r=cookify(key,val,cfg);doc.cookie=r;return val;},has:function(key){key=esc(key);var c=doc.cookie,ofs=c.indexOf(key+'='),len=ofs+key.length+1,sub=c.substring(0,key.length);return((!ofs&&key!=sub)||ofs<0)?false:true;},get:function(key){key=esc(key);var c=doc.cookie,ofs=c.indexOf(key+'='),len=ofs+key.length+1,sub=c.substring(0,key.length),end;if((!ofs&&key!=sub)||ofs<0)
return null;end=c.indexOf(';',len);if(end<0)
end=c.length;return un(c.substring(len,end));},remove:function(k){var r=me.get(k),opt={expires:EPOCH};doc.cookie=cookify(k,'',opt);return r;},keys:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push(un(p[0]));}
return r;},all:function(){var c=doc.cookie,ps=c.split('; '),i,p,r=[];for(i=0;i<ps.length;i++){p=ps[i].split('=');r.push([un(p[0]),un(p[1])]);}
return r;},version:'0.2.1',enabled:false};me.enabled=alive.call(me);return me;}());var index_of=(function(){if(Array.prototype.indexOf)
return function(ary,val){return Array.prototype.indexOf.call(ary,val);};else
return function(ary,val){var i,l;for(i=0,l=ary.length;i<l;i++)
if(ary[i]==val)
return i;return-1;};})();empty=function(){};esc=function(str){return'PS'+str.replace(/_/g,'__').replace(/ /g,'_s');};C={search_order:['localstorage','globalstorage','gears','cookie','ie','flash'],name_re:/^[a-z][a-z0-9_ -]+$/i,methods:['init','get','set','remove','load','save','iterate'],sql:{version:'1',create:"CREATE TABLE IF NOT EXISTS persist_data (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)",get:"SELECT v FROM persist_data WHERE k = ?",set:"INSERT INTO persist_data(k, v) VALUES (?, ?)",remove:"DELETE FROM persist_data WHERE k = ?",keys:"SELECT * FROM persist_data"},flash:{div_id:'_persist_flash_wrap',id:'_persist_flash',path:'persist.swf',size:{w:1,h:1},args:{autostart:true}}};B={gears:{size:-1,test:function(){return(window.google&&window.google.gears)?true:false;},methods:{init:function(){var db;db=this.db=google.gears.factory.create('beta.database');db.open(esc(this.name));db.execute(C.sql.create).close();},get:function(key){var r,sql=C.sql.get;var db=this.db;var ret;db.execute('BEGIN').close();r=db.execute(sql,[key]);ret=r.isValidRow()?r.field(0):null;r.close();db.execute('COMMIT').close();return ret;},set:function(key,val){var rm_sql=C.sql.remove,sql=C.sql.set,r;var db=this.db;var ret;db.execute('BEGIN').close();db.execute(rm_sql,[key]).close();db.execute(sql,[key,val]).close();db.execute('COMMIT').close();return val;},remove:function(key){var get_sql=C.sql.get;sql=C.sql.remove,r,val=null,is_valid=false;var db=this.db;db.execute('BEGIN').close();db.execute(sql,[key]).close();db.execute('COMMIT').close();return true;},iterate:function(fn,scope){var key_sql=C.sql.keys;var r;var db=this.db;r=db.execute(key_sql);while(r.isValidRow()){fn.call(scope||this,r.field(0),r.field(1));r.next();}
r.close();}}},globalstorage:{size:5*1024*1024,test:function(){return window.globalStorage?true:false;},methods:{key:function(key){return esc(this.name)+esc(key);},init:function(){this.store=globalStorage[this.o.domain];},get:function(key){key=this.key(key);return this.store.getItem(key);},set:function(key,val){key=this.key(key);this.store.setItem(key,val);return val;},remove:function(key){var val;key=this.key(key);val=this.store[key];this.store.removeItem(key);return val;}}},localstorage:{size:-1,test:function(){return window.localStorage?true:false;},methods:{key:function(key){return this.name+'>'+key;},init:function(){this.store=localStorage;},get:function(key){key=this.key(key);return this.store.getItem(key);},set:function(key,val){key=this.key(key);this.store.setItem(key,val);return val;},remove:function(key){var val;key=this.key(key);val=this.store.getItem(key);this.store.removeItem(key);return val;},iterate:function(fn,scope){var l=this.store;for(i=0;i<l.length;i++){keys=l[i].split('>');if((keys.length==2)&&(keys[0]==this.name)){fn.call(scope||this,keys[1],l[l[i]]);}}}}},ie:{prefix:'_persist_data-',size:64*1024,test:function(){return window.ActiveXObject?true:false;},make_userdata:function(id){var el=document.createElement('div');el.id=id;el.style.display='none';el.addBehavior('#default#userdata');document.body.appendChild(el);return el;},methods:{init:function(){var id=B.ie.prefix+esc(this.name);this.el=B.ie.make_userdata(id);if(this.o.defer)
this.load();},get:function(key){var val;key=esc(key);if(!this.o.defer)
this.load();val=this.el.getAttribute(key);return val;},set:function(key,val){key=esc(key);this.el.setAttribute(key,val);if(!this.o.defer)
this.save();return val;},remove:function(key){var val;key=esc(key);if(!this.o.defer)
this.load();val=this.el.getAttribute(key);this.el.removeAttribute(key);if(!this.o.defer)
this.save();return val;},load:function(){this.el.load(esc(this.name));},save:function(){this.el.save(esc(this.name));}}},cookie:{delim:':',size:4000,test:function(){return P.Cookie.enabled?true:false;},methods:{key:function(key){return this.name+B.cookie.delim+key;},get:function(key,fn){var val;key=this.key(key);val=ec.get(key);return val;},set:function(key,val,fn){key=this.key(key);ec.set(key,val,this.o);return val;},remove:function(key,val){var val;key=this.key(key);val=ec.remove(key);return val;}}},flash:{test:function(){if(!deconcept||!deconcept.SWFObjectUtil)
return false;var major=deconcept.SWFObjectUtil.getPlayerVersion().major;return(major>=8)?true:false;},methods:{init:function(){if(!B.flash.el){var o,key,el,cfg=C.flash;el=document.createElement('div');el.id=cfg.div_id;document.body.appendChild(el);o=new deconcept.SWFObject(this.o.swf_path||cfg.path,cfg.id,cfg.size.w,cfg.size.h,'8');for(key in cfg.args)
o.addVariable(key,cfg.args[key]);o.write(el);B.flash.el=document.getElementById(cfg.id);}
this.el=B.flash.el;},get:function(key){var val;key=esc(key);val=this.el.get(this.name,key);return val;},set:function(key,val){var old_val;key=esc(key);old_val=this.el.set(this.name,key,val);return old_val;},remove:function(key){var val;key=esc(key);val=this.el.remove(this.name,key);return val;}}}};var init=function(){var i,l,b,key,fns=C.methods,keys=C.search_order;for(i=0,l=fns.length;i<l;i++)
P.Store.prototype[fns[i]]=empty;P.type=null;P.size=-1;for(i=0,l=keys.length;!P.type&&i<l;i++){b=B[keys[i]];if(b.test()){P.type=keys[i];P.size=b.size;for(key in b.methods)
P.Store.prototype[key]=b.methods[key];}}
P._init=true;};P={VERSION:VERSION,type:null,size:0,add:function(o){B[o.id]=o;C.search_order=[o.id].concat(C.search_order);init();},remove:function(id){var ofs=index_of(C.search_order,id);if(ofs<0)
return;C.search_order.splice(ofs,1);delete B[id];init();},Cookie:ec,Store:function(name,o){if(!C.name_re.exec(name))
throw new Error("Invalid name");if(!P.type)
throw new Error("No suitable storage found");o=o||{};this.name=name;o.domain=o.domain||location.hostname||'localhost';o.domain=o.domain.replace(/:\d+$/,'')
o.domain=(o.domain=='localhost')?'':o.domain;this.o=o;o.expires=o.expires||365*2;o.path=o.path||'/';this.init();}};init();return P;})();

