/**
 * @author Lukas Goldschmidt
 * @projectDescription  A 3D Interface to Wikipeda,
 showcasing HTML5, WebGL, Three.js, JQuery-UI andseveral APIs.
 * @fileOverview A 3D Interface to Wikipeda,
 showcasing HTML5, WebGL, Three.js, JQuery-UI andseveral APIs.
 * @name wiki_browser
 * @version     0.1
 */

/**
 * @namespace LG
 * @desc Namespace of Lukas Goldschmidt
 */

/**
 * @namespace LG.wb
 * @desc Namespace of Wikipedia 3D Browser 2011
 */

/**
 * Holds all Classes  of Wikipedia 3D Browser 2011
 * @namespace LG.wb.Class
 */
Namespace.Manager.Register("LG.wb.Class");

/*
 * @namespace LG.wb.App
 * @desc Holds all Instances of Classes in the Wikipedia 3D Browser 2011
 */
Namespace.Manager.Register("LG.wb.App");

/**
 * Shows the given error message in the browser.
 * @param msg Error message to show in the browser.
 */
function handleError(msg) {
	alert('ERROR: ' + msg);
}




LG.wb.Class.Browser = new Class(/** @lends LG.wb.Class.Browser.prototype */
{
	/** a maximum value for elements */
	maxele : 3,
	/** a maximum value for x position */
	maxx : 950,
	/** a maximum value for y position */
	miny : -950,

	/** initial value for x position */
	ini_xpos : -850,
	/** initial value for y position */
	ini_ypos : 850,
	/** initial value for z position */
	ini_zpos : 0,

	xpos : -850,
	ypos : 850,
	zpos : 0,

	xdis : 411,
	ydis : 411,
	zdis : 500,
	/** FavMe Icon Image	*/
	favmeUrl : '/wikipedia3d/images/Favorite-icon.png',
	/** DelMe Icon Image	*/
	delmeUrl : '/wikipedia3d/images/Remove-icon.png',
	/** BlMe Icon Image	*/
	blmeUrl : '/wikipedia3d/images/blacklist.png',
	/** SoloMe Icon Image	*/
	solomeUrl : '/wikipedia3d/images/eye-icon.png',


	/** object to hold our item instances */
	items : {},
	/** array to hold our item ids in sequence */
	items_ref : [],
	/** array for clickable items */
	click_items : [],
	/** array for favourite items */
	fav_items : [],
	/** array for blacklisted items */
	bl_items : [],

	sky : [],
	/**
	 * @class LG.wb.Class.Browser
	 * The Main Object containing the central logic framework .
	 * @member LG.wb.Class.Browser
	 * @param {Object} ele
	 * @param {int} width
	 * @param {int} height
	 * @constructs LG.wb.Class.Browser
	 */
	initialize : function(ele, width, height) {
		this.width = width;
		this.height = height;
		// Update proportions
		this.resized();

		this.isShiftDown = false;
		this.cur_lang = DEF_LANG;
		this.alurl = 'http://access.alchemyapi.com/calls/url/URLGetRankedNamedEntities';
		this.wpurl = 'http://' + DEF_LANG + '.wikipedia.org/w/api.php';
		this.proxyurl = "/proxy?mode=native&url=";
		this.proxyurl_json = "/proxy?url=";
		//this.img_url = "http://www.world.eu.org/~lucky/wiki_browser/imgsrch.php?wpage=";
		//		this.dbp_onto_url = "http://www.world.eu.org/~lucky/wiki_browser/dbpedia.ontology.owx"; // URL of the ontology
		this.dbp_onto_url = "/dbpedia.ontology.owx";
		// URL of the ontology
		if($.Storage.get("skydir") != undefined){
			this.bg_dir = $.Storage.get("skydir");
		}else{
			this.bg_dir = "images/cube/night_1/";
		}
		if($.Storage.get("maxTypeFetch") != undefined){
			this.maxTypeFetch = $.Storage.get("maxTypeFetch");
		}else{
			this.maxTypeFetch = 128;
		}
		$("#maxtypefetch").val(this.maxTypeFetch); 


		this.projector = new THREE.Projector();
		//		this.renderer = new THREE.CanvasRenderer();
		this.renderer = new THREE.WebGLRenderer();
		var that = this;
		

 		// Google Maps Initialization finished



		// Ontology Initialization
		var text = ungzip(wStr);
		var onto = jsw.owl.xml.parse(text, handleError);
		//		this.dbp_onto = jsw.owl.xml.parseUrl(this.dbp_onto_url , handleError);
		// 		console.log(text);
		// 		console.log(onto);

		try {
			this.reasoner = new jsw.owl.BrandT(onto);
		} catch (ex) {
			handleError(ex);
		}
		// Onto Ini Finished
		
		
		this.renderer.setSize(this.width, this.height);

		ele.innerHTML = "";
		ele.appendChild(this.renderer.domElement);

		ele.onBlur = function() {
			LG.wb.App.Browser.camera.isShiftDown = false;
		};

		this.ctarget = new THREE.Object3D();
		this.ctarget.position.x = 0;
		this.ctarget.position.y = 0;
		this.ctarget.position.z = 0;

		//		this.camera = new LG.FirstPersonCamera({
		this.camera = new LG.THREE.FirstPersonCamera({
			fov : 33,
			aspect : this.width / this.height,
			near : 1,
			far : 30000,
			target : this.ctarget,
			lookSpeed : 1.8,
			movementSpeed : 220,
			noFly : true,
			activeLook : false,
			domElemnt : this.renderer.domElement,
			verticalMin : Math.PI * 0.35,
			verticalMax : Math.PI * 0.65
		});
		this.camera.Browser = this;

		// this.camera.position.z = 1900;
		this.camera.position.x = 300;
		this.camera.position.y = 0;
		this.camera.position.z = 340;
		this.camera.lon = 180;
		this.camera.constrainVertical = true;

		this.scene = new THREE.Scene();
//		this.scene.fog = new THREE.FogExp2( 0xffffff, 0.002 );
//		this.scene.fog = new THREE.Fog( 0xffffff, 30,10000 );
		this.ray = new THREE.Ray(this.camera.position, null)

		this.pointLight = new THREE.PointLight(0xFFFFFF);
		this.pointLight.position.x = 300;
		this.pointLight.position.y = 1000;
		this.pointLight.position.z = 630;
		this.scene.addLight(this.pointLight);

		this.texture_placeholder = document.createElement('canvas');
		this.texture_placeholder.width = 128;
		this.texture_placeholder.height = 128;

		var context = this.texture_placeholder.getContext('2d');
		context.fillStyle = 'rgb( 200, 200, 200 )';
		context.fillRect(0, 0, this.texture_placeholder.width, this.texture_placeholder.height);
		var that = this;
		$.each(BG_ARR, function(key, val) {
			var materials = [that.loadTexture(val + 'px.jpg'), // right 2
			that.loadTexture(val + 'nx.jpg'), // left 4
			that.loadTexture(val + 'py.jpg'), // top 5
			that.loadTexture(val + 'ny.jpg'), // bottom 6
			that.loadTexture(val + 'pz.jpg'), // back 1
			that.loadTexture(val + 'nz.jpg')  // front 3

			];
			that.sky[val] = new THREE.Mesh( new THREE.CubeGeometry( 10000, 10000, 10000, 30, 30, 30, materials, true ), new THREE.MeshFaceMaterial() );
			that.sky[val].overdraw = true;
		 	that.sky[val].visible=false;
		 	that.scene.addObject( that.sky[val]);
			if(val == that.bg_dir){
				that.sky[val].visible=true;	
				that.skycube=that.sky[val];			
			} 
		});
		// grid
		plane = new THREE.Mesh(new THREE.PlaneGeometry(2200, 2200, 20, 20), new THREE.MeshBasicMaterial({
			color : 0x339933,
			wireframe : true
		}));
		plane.rotation.x = -90 * Math.PI / 180;
		plane.position.y = -170;
		this.scene.addObject(plane);

		$("#ac").focus();
		this.resized();
		

	},
	setSkycube : function(skydir) {
		$.Storage.set({"skydir":skydir});
		this.sky[this.bg_dir].visible = false;
		this.bg_dir = skydir;
		this.sky[this.bg_dir].visible = true;
		this.skycube=this.sky[this.bg_dir];
	
	},
	setMaxtypefetch : function (val){
		$.Storage.set({"maxTypeFetch":val});
		this.maxTypeFetch = val;
	},
	setlang: function(lang){
		var url = false;
		for(var idx in this.wp_languages){
			if(this.wp_languages[idx].lang == lang){
				url = this.wp_languages[idx].url; 
			}
		}
		if(url != false){
			this.wpurl = url + 'w/api.php';
			this.cur_lang = lang;
			
		}
		
		
	
	},
	resized : function() {
		var c = $("canvas:last");
		this.offset = c.offset();
		//console.log(this.offset);
		$("#dialog-message").dialog.height = window.innerHeight;
	},
	render : function() {
		for(index in this.items) {
			this.items[index].animate();
		}
		if(this.skycube !== undefined)
		this.skycube.position = this.camera.position;
		this.pointLight.position = this.camera.position;
		this.renderer.render(this.scene, this.camera);
	},
	animate : function() {
		requestAnimationFrame(LG.wb.App.Browser.animate);
		LG.wb.App.Browser.render();
	},
	reset : function() {
		//alert('reset pushed');
		var tmp = this.items;
		// remove from scene
		for(index in this.items) {
			this.remove(this.items[index]);
		}
		// empty array
		this.items = {};
		this.click_items = [];
		this.items_ref = [];

		this.xpos = this.ini_xpos;
		this.ypos = this.ini_ypos;
		this.zpos = this.ini_zpos;

		document.getElementById('mapFrame').contentWindow.clearMarkers();

		$("#ac").val('');
		this.render();
		$("#ac").focus();

	},
	/**
	 * Show the full text of the wikipage, some text
	 * @param (Object) item an Instance of the Class LG.wb.Class.Item
	 */
	showFullText : function(item) {
		var Browser = this;
		$("body").css("cursor", "wait");

		Browser.dialogOpen = true;
		if(item.parsedText == undefined || item.parsedText == ""){
			if(item.text){
				$("#dialog-message").html(item.text);
		
				$("#dialog-message a[href^='\/wiki\/']").each(function() {
		
					var wpage = this.href.substr(this.href.lastIndexOf("/") + 1);
					this.onclick = function() {
						Browser.load(decodeURIComponent(wpage));
						$("#dialog-message").dialog("close");
					};
					//			this.href = 'javascript:LG.wb.App.Browser.load("' + wpage + '"); $("#dialog-message").dialog("close");return false;';
					this.href = "#";
				});
				$("#dialog-message a[href^='\/w\/']").each(function() {
					this.href = '#';
				}).css('color', '#333333');
			//	$("#dialog-message td").each(function() {
			//		if(this.css('background-color') == "#f2f2f4"){
			//			this.css('background-color', '#020204');
			//		}
			//	});
				$("#dialog-message a[href^='http']").each(function() {
		
					this.target = '_blank';
					this.onclick = 'javascript: $("#dialog-message").dialog("close");';
		
				});
			
				item.parsedText = $("#dialog-message").html();
				
			}else{
				$("body").css("cursor", "default");
				return;				
				
			}
			
		} else{
			$("#dialog-message").html(item.parsedText);
		}

		$("#dialog-message").dialog("option", "height", window.innerHeight);

		$("#dialog-message").dialog("option", "title", item.wpage);
		$("body").css("cursor", "default");
		Browser.setlang(item.lang);
		$("#dialog-message").dialog('open');

	},
	/**
	 * makes an item a favorite item
	 * @param {Object} item a LG.wb.Class.Item  
	 */
	makeFav : function (item){
		var l_item={
			wpage:encodeURI(item.wpage),
			id:Sha1.hash(item.lang + "_" + item.wpage.replace(/[\s\,]/g,"_")),
			lang:item.lang,
			img:item.images[0],
			
		};
//		console.log(l_item);
//		console.log(this.fav_items);
		$("#tabs").tabs('select','tabs-Favourites');

		for ( var myi in this.fav_items){
			if(this.fav_items[myi].id == l_item.id){
				console.log(this.fav_items[myi].id);
				return false ;
			} 
		}
		this.fav_items.push(l_item);
		$('#favs').append('<div title="' + l_item.lang + " "  + decodeURI(l_item.wpage) + '" id="' + l_item.id + '" style="float:left;display:inline;margin:4px;"></div>');	

		$( "#" + l_item.id ).append('<span style="background: #333 url(css/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png) 50% 50% repeat-x;" >' + decodeURI(l_item.wpage) + '</span><br />');
		$( "#" + l_item.id ).append('<div style="background: black url(css/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png) 50% bottom repeat-x;"><img src="' + l_item.img + '" width="64" height="64"></div>');
///		$( "#" + l_item.id ).append('<div style="clear: both;"></div>');
//		$( "#favs").append('<div style="clear: both;"></div>');
		$( "#" + l_item.id ).draggable({ revert: false, helper: "clone" });
		
		this.saveLists();
	},
	/**
	 * makes an item a blacklisted item
	 * @param {Object} item a LG.wb.Class.Item  
	 */
	makeBL : function (item){
		var l_item={
			wpage:encodeURI(item.wpage),
			id:Sha1.hash(item.lang + "_" + item.wpage.replace(/[\s\,]/g,"_")),
			lang:item.lang,
			img:item.images[0],
			
		};
		console.log(l_item);
//		console.log(this.fav_items);
		this.remove(item);

		$("#tabs").tabs('select','tabs-Blacklist');
		for ( var myi in this.fav_items){
			if(this.fav_items[myi].id == l_item.id){
				console.log("Already favorite : " + this.fav_items[myi].id);
				return false ;
			} 
		}

		for ( var myi in this.bl_items){
			if(this.bl_items[myi].id == l_item.id){
				console.log("Already Blacklisted : " + this.bl_items[myi].id);
				return false ;
			} 
		}
		this.bl_items.push(l_item);
		$('#blstd').append('<div title="' + l_item.lang + " "  + decodeURI(l_item.wpage) + '" id="' + l_item.id + '" style="float:left;display:inline;margin:4px;"></div>');	

		$( "#" + l_item.id ).append('<span style="background: #333 url(css/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png) 50% 50% repeat-x;" >' + decodeURI(l_item.wpage) + '</span><br />');
//		$( "#" + l_item.id ).append('<div style="background: black url(images/ui-bg_inset-soft_25_000000_1x100.png) 50% bottom repeat-x;"><img src="' + l_item.img + '" width="64" height="64"></div>');
///		$( "#" + l_item.id ).append('<div style="clear: both;"></div>');
//		$( "#favs").append('<div style="clear: both;"></div>');
		$( "#" + l_item.id ).draggable({ revert: false, helper: "clone" });
		
		this.saveLists();

	},
	saveLists : function (){
		// serialize^
		// local store ...
		$.Storage.set("favs", serialize(this.fav_items));
		$.Storage.set("blstd", serialize(this.bl_items));
		
	},
	loadLists : function (){
		if($.Storage.get("favs") !== undefined){
			var list = unserialize($.Storage.get("favs"));
			this.fav_items = new Array();
			for (var idx in list){
				var l_item = list[idx];
				this.fav_items.push(l_item);
				$('#favs').append('<div title="' + l_item.lang + " " +  decodeURI(l_item.wpage)  + '" id="' + l_item.id + '" style="float:left;display:inline;margin:4px;"></div>');	
		
				$( "#" + l_item.id ).append('<span style="background: #333 url(css/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png) 50% 50% repeat-x;" >' + decodeURI(l_item.wpage) + '</span><br />');
				$( "#" + l_item.id ).append('<div style="background: black url(css/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png) 50% bottom repeat-x;"><img src="' + l_item.img + '" width="64" height="64"></div>');
				$( "#" + l_item.id ).draggable({ revert: false, helper: "clone" });


			}
		}
		if($.Storage.get("blstd") !== undefined){
			var list = unserialize($.Storage.get("blstd"));
			this.bl_items = new Array();
			for (var idx in list){
				var l_item = list[idx];
				this.bl_items.push(l_item);
				$('#blstd').append('<div title="' + l_item.lang + " " +  decodeURI(l_item.wpage)  + '" id="' + l_item.id + '" style="float:left;display:inline;margin:4px;"></div>');	
		
				$( "#" + l_item.id ).append('<span style="background: #333 url(css/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png) 50% 50% repeat-x;" >' + decodeURI(l_item.wpage) + '</span><br />');
//				$( "#" + l_item.id ).append('<div style="background: black url(images/ui-bg_inset-soft_25_000000_1x100.png) 50% bottom repeat-x;"><img src="' + l_item.img + '" width="64" height="64"></div>');
				$( "#" + l_item.id ).draggable({ revert: false, helper: "clone" });
			}
		}
		
	},
	removeFav : function (id){
		for ( var myi in this.fav_items){
			if(this.fav_items[myi].id == id){
				var ci = this.fav_items.indexOf(this.fav_items[myi]);
				this.fav_items.splice(ci,1);
				$("#" + id).remove();
				this.saveLists();
				return true;
			} 
		}
		return false;
	},
	/**
	 * load a favorite item into the Browser
	 * @param {String} id hash id of the item
	 */
	loadFav : function (id){
		for ( var myi in this.fav_items){
			if(this.fav_items[myi].id == id){
				console.log("Loading " + this.fav_items[myi].id);
				var lang = $("#langsel option:selected").val();
				this.setlang( this.fav_items[myi].lang);
				this.load(decodeURI(this.fav_items[myi].wpage));
				this.setlang(lang);
				if(lang != this.fav_items[myi].lang){
					$(document).oneTime(1800, "translate", function() {
						if (LG.wb.App.Browser.items[id].langlinks[lang] != undefined) {
							var link = LG.wb.App.Browser.items[id].langlinks[lang];
							var _wpage = link.substring(link.lastIndexOf("/")+1);
							LG.wb.App.Browser.load(decodeURI(_wpage));
						};		
					});
				}; 
				return true;
			} 
		}
		return false;
	},
	removeBL : function (id){
		for ( var myi in this.bl_items){
			if(this.bl_items[myi].id == id){
				var ci = this.bl_items.indexOf(this.bl_items[myi]);
				this.bl_items.splice(ci,1);
				$("#" + id).remove();
				this.saveLists();
				return true;
			} 
		}
		return false;
	},
	
	showTypeLinks : function (item, type){
	var Browser = this;
		$("#dialog-busy").dialog("open");
		Browser.dialogOpen = true;
		if(item.yago_type_links[type] !== undefined && item.yago_type_links[type].length > 0 ) {
			item.yago_type_links[type].sort();
			var el = $( document.createElement('div') );
			el.append('<h2>'+ type +'</h2>');
			for (var i = item.yago_type_links[type].length - 1; i >= 0; i--){
			  
				el.append('<a href="#" onclick="LG.wb.App.Browser.load(\''+ item.yago_type_links[type][i]['label'].value +'\'); $(\'#dialog-message\').dialog(\'close\');"  title="'+ item.yago_type_links[type][i]['abstract'].value +'" >'+item.yago_type_links[type][i]['label'].value+'</a> |  ');
		
			};

		}		
		var txt = el.html();
		$("#dialog-message").html(txt);
		$("#dialog-message").dialog("option", "title", type);
		$("#dialog-message").dialog("option", "height", window.innerHeight);
		$("#dialog-busy").dialog("close");
		Browser.setlang(item.lang);
		$("#dialog-message").dialog("open");
		
	},
	showCatLinks : function (item, cat){
		var Browser = this;
		$("#dialog-busy").dialog("open");
		Browser.dialogOpen = true;
		if(item.cat_links[cat] !== undefined && item.cat_links[cat].length > 0 ) {
			item.cat_links[cat].sort();
			var el = $( document.createElement('div') );
			el.append('<h2>'+ cat +'</h2>');
			for (var i = item.cat_links[cat].length - 1; i >= 0; i--){
			  
				el.append('<a href="#" onclick="LG.wb.App.Browser.load(\''+ item.cat_links[cat][i] +'\'); $(\'#dialog-message\').dialog(\'close\');">'+item.cat_links[cat][i]+'</a> |  ');
		
			};

		}		
		var txt = el.html();
		$("#dialog-message").html(txt);
		$("#dialog-message").dialog("option", "height", window.innerHeight);
		$("#dialog-message").dialog("option", "title", cat);
		$("#dialog-busy").dialog("close");
		Browser.setlang(item.lang);
		$("#dialog-message").dialog("open");
	},
	loadTexture : function(path) {

		var texture = new THREE.Texture(this.texture_placeholder), material = new THREE.MeshBasicMaterial({
			map : texture
		}), image = new Image();

		image.onload = function() {

			texture.needsUpdate = true;
			material.map.image = this;

			//			this.render();

		};

		image.src = path;

		return material;

	},
	remove: function(item){
		if(this.items[item.hashid] !== undefined ) {
			for(var i in item.click_items){
				var ci = this.click_items.indexOf(item.click_items[i]);
				if(ci !== -1){
					this.click_items.splice(ci,1);
				}		
			}
			var idx = this.items_ref.indexOf(item.hashid);
			this.items_ref.splice(idx,1);

			this.scene.removeObject(item.model);

			delete(this.items[item.hashid]);
			item.model = null;
			delete(item);			
		} else {
			
			return false;
		}
	},
	
	toPrev : function() {
		var idx = this.items_ref.indexOf(this.cur_item_idx);
		idx += 1;
		if(idx > this.items_ref.length - 1) {
			idx = 0;
		}
		console.log("toNext - idx:" + idx + " id:" + this.items_ref[idx]);
		this.items[this.items_ref[idx]].panToMe();
		this.cur_item_idx = this.items_ref[idx];
	}, 
	
	toNext : function() {
		var idx = this.items_ref.indexOf(this.cur_item_idx);
		idx -= 1;
		if(idx < 0) {
			idx = this.items_ref.length - 1;
		}
		console.log("toPrev - idx:" + idx + " id:" + this.items_ref[idx]);
		this.items[this.items_ref[idx]].panToMe();
		this.cur_item_idx = this.items_ref[idx];
	},
	overView : function(){
//		var dest = new THREE.Vector3(this.model.position.x+80, this.model.position.y+30, this.model.position.z-380);
		if(this.cur_item_idx == undefined){
			var dest = new THREE.Vector3(0, 830, -1500);
			
			this.camera.panTo(dest,90,-72);
			
		}
		var idx = this.cur_item_idx;
		if(this.overview_toggle){
			this.overview_toggle = false;
			this.items[idx].panToMe();
		}else{
			this.overview_toggle = true;
			
			
			var dest = new THREE.Vector3(680, this.items[idx].model.position.y+530, this.items[idx].model.position.z-1180);
			
			this.camera.panTo(dest,116,-42);
			
		}

		
	},
	findPages : function(latLong){
		console.log(latLong.lat(), latLong.lng());
		var that = this;
		var url = "http://api.geonames.org/findNearbyWikipediaJSON";
		var param = "username=lgolds";
		param += "&maxRows=12";
		param += "&lng=" + latLong.lng();
		param += "&lat=" + latLong.lat();
		param += "&radius=12";
		param += "&lang=" + that.cur_lang;
		
		$.ajax({
			url : url,
			data : param,
			context : that,
			dataType : 'jsonp',
			success : function(data) {
				console.log(data);
				if(data.geonames !== undefined){
					var res=data.geonames;
					for(idx in res){
						that.load(res[idx].title);
						
						
						
					}
				}
			}
		});	

	},
	load : function(wpage) {

		// take a wiki page and initialize an Item Object
		$("#ac").val('');
		$("#ac").blur();
		if(wpage.indexOf("#")>0)
			wpage = wpage.substring(0,wpage.indexOf("#"))
		var s =	Sha1.hash(this.cur_lang + "_" + wpage.replace(/[\s\,]/g,"_"));
//		var s = str_clean(wpage);

		for ( var myi in this.bl_items){
			if(this.bl_items[myi].id == s){
				console.log(wpage + " is blacklisted ...." );
				return false;
			}
		}	

		if(this.items[s] !== undefined){
			this.items[s].panToMe();
			return;
		}
		// item exists, bye

		this.items[s] = new LG.wb.Class.Item(this, wpage);
		// add geometry to scene
		this.scene.addObject(this.items[s].model);

		this.click_items = this.click_items.concat(this.items[s].click_items);
		//		this.click_items.push(this.items[s].Label1);

		this.items[s].goTo(this.xpos, this.ypos, this.zpos);
//		this.items[s].panToMe();
		this.cur_item_idx = s;
		this.items_ref.push(s);
		this.camera.panTo(new THREE.Vector3(this.xpos+80, this.zpos+30, this.ypos-380),100,33);
		this.overview_toggle = false;

		// advance position
		this.xpos += this.xdis;
		if(this.xpos > this.maxx) {
			this.xpos = this.ini_xpos;
			this.ypos -= this.ydis;
		}
		if(this.ypos < this.miny) {
			this.xpos = this.ini_xpos;
			this.ypos = this.ini_ypos;
			this.zpos += this.zdis;
		}

	},
});
// End of LG.wb.Class.Browser

include('js/wb_item.js');

// Callbacks

var ac_callback = function(data) {
	// part of the wikipedia Site restriction workaround
	$('#ac').autocomplete('option', 'source', data[1]);
}


// Helper
function str_clean(str) {
	// make function name out of wiki page
//	return 'f_' + str.replace(/\W|\s/gi, "_");
	var out= "";
	for(var i = 0; i < str.length; i++) {
		out += str.charCodeAt(i).toString();
							}
	return out;
}

// user resized window
function resizeUpdate() {
	LG.wb.App.Browser.resized();

};

var resizeTimer;
$(window).resize(function() {
	clearTimeout(resizeTimer);
	resizeTimer = setTimeout(resizeUpdate, 100);
});


/* Execution starts here */
$(document).ready(function() {
	if ( ! Detector.webgl ) {
		Detector.addGetWebGLMessage();
		return false;
		
	}
	

	/**
	 * The object acts as a hub, and vontainer for items and such
	 */
	LG.wb.App.Browser = new LG.wb.Class.Browser(document.getElementById('content'), 960, 480);

	//	LG.wb.App.Browser.wpurl = 'http://de.wikipedia.org/w/api.php';

	//	LG.wb.App.Browser.display('The_Beatles');
	//	LG.wb.App.Browser.display('Bob_Marley');
	//	LG.wb.App.Browser.display('Barack_Obama');
	//	LG.wb.App.Browser.display('Star_Trek');
	//	LG.wb.App.Browser.display('Stargate_Atlantis');

	$("#ac").autocomplete({
		source : function(request, response) {
			url = LG.wb.App.Browser.wpurl + "?action=opensearch&search=" + this.value + "&format=json&callback=ac_callback   ";
			var elem = document.createElement('script');
			elem.setAttribute('src', url);
			elem.setAttribute('type', 'text/javascript');
			document.getElementsByTagName ('head')[0].appendChild(elem);
			response([]);

		},
		search : function(event, ui) {
			//url: 'http://en.wikipedia.org/w/api.php?action=opensearch',
			url = LG.wb.App.Browser.wpurl + "?action=opensearch&search=" + this.value + "&format=json&callback=ac_callback   ";

			var elem = document.createElement('script');
			elem.setAttribute('src', url);
			elem.setAttribute('type', 'text/javascript');
			document.getElementsByTagName ('head')[0].appendChild(elem);
			return true;
		},
		//		autoFocus:true,
		minLength : 2,
		position : {
			my : "left bottom",
			at : "left top"
		},
		select : function(event, ui) {
			LG.wb.App.Browser.load(ui.item.label);
			LG.wb.App.Browser.renderer.domElement.focus();
		}
	});
	$("#ac").click(self.focus());
	$("#dialog-message").dialog({
		maxHeight : window.innerHeight,
		draggable : true,
		minWidth : 800,
		autoOpen : false,
		modal : false,
		close : function(event, ui) {
			LG.wb.App.Browser.dialogOpen = false;
			LG.wb.App.Browser.setlang($("#langsel option:selected").val());
		},
		buttons : {
			Ok : function() {
				$(this).dialog("close");
			},
		}
	});
	$("#dialog-about").dialog({
		minWidth : 480,
		autoOpen : false,
		modal : true,
		close : function(event, ui) {
			LG.wb.App.Browser.dialogOpen = false;
		},
		buttons : {
			Ok : function() {
				$(this).dialog("close");
			}
		}
	});
	$("#dialog-busy").dialog({
		minWidth : 480,
		autoOpen : false,
		modal : false,
	});

	//
	$("#about").button({
		//	text:false,
		icons : {
			primary : "ui-icon-help"
		}
	}).click(function() {
		LG.wb.App.Browser.dialogOpen = true;
		$("#dialog-about").dialog('open');

	});

	$("#reset").button({
		//	text: false,
		icons : {
			primary : "ui-icon-document"
		}
	}).click(function() {
		LG.wb.App.Browser.reset();

	});
	$("#mapButton").button({
		//	text: false,
		icons : {
			primary : "ui-icon-document"
		}
	}).click(function() {
		$( "#GMap" ).dialog('open');

	});
	// Language Selector
	var options = $("#langsel");
	LG.wb.App.Browser.wp_languages = wp_languages;

	$.each(LG.wb.App.Browser.wp_languages, function() {
		if(this.lang == DEF_LANG) {
			options.append($("<option selected />").val(this.lang).text(this.name));
		} else {
			options.append($("<option />").val(this.lang).text(this.name));
		}
	});
	options.change(function() {
		var lang = $("#langsel option:selected").val();
		LG.wb.App.Browser.setlang(lang);
		$.each(LG.wb.App.Browser.items, function(key,val){
			// lookup corresponding entries in selected language
			if (val.langlinks[lang] != undefined) {
				var link = val.langlinks[lang];
				var _wpage = link.substring(link.lastIndexOf("/")+1);
				LG.wb.App.Browser.load(decodeURI(_wpage));

			};		
		});
	});
	// End of Language Selector

	// BG Selector
	var bgoptions = $("#bgsel");
	LG.wb.App.Browser.bg_arr = BG_ARR;
	$.each(LG.wb.App.Browser.bg_arr, function(name, url) {
		if(LG.wb.App.Browser.bg_dir == url) {
			bgoptions.append($("<option selected />").val(url).text(name));
		} else {
			bgoptions.append($("<option />").val(url).text(name));
		}
	});
	bgoptions.change(function() {
		//		LG.wb.App.Browser.bg_url = $("#bgsel option:selected").val() ;
		LG.wb.App.Browser.setSkycube($("#bgsel option:selected").val());
	});

	// End of BG Selector
	$("#maxtypefetch").change(function(){
		LG.wb.App.Browser.setMaxtypefetch($(this).val());
		
	});
	//
	
	//
	$("#icon_help").append('<img src="'+LG.wb.App.Browser.delmeUrl+'" width="24" height="24" />: Delete Item, ');
	$("#icon_help").append('<img src="'+LG.wb.App.Browser.blmeUrl+'" width="24" height="24" />: Blacklist Item, ');
	$("#icon_help").append('<img src="'+LG.wb.App.Browser.favmeUrl+'" width="24" height="24" />: Favourite Item, ');
	$("#icon_help").append('<img src="'+LG.wb.App.Browser.solomeUrl+'" width="24" height="24" />: Solo Item, ');

	// Set up Fav Tab
	$("#tabs-Favourites").append('<h2>Favourites :</h2>');
	$("#tabs-Favourites").append('<div id="trash" style="display:inline;float:left;"><img src="images/trashcan.png"></div>');
	$("#tabs-Favourites").append('<div id="favs" style="overflow:scroll;height:160px"></div>');

	// Set up Blacklist Tab
	$("#tabs-Blacklist").append('<h2>Blacklisted :</h2>');
	$("#tabs-Blacklist").append('<div id="trash2" style="display:inline;float:left;"><img src="images/trash2.png"></div>');
	$("#tabs-Blacklist").append('<div id="blstd" style="overflow:scroll;height:160px"></div>');
	

	// set up the drop targets ...
	// trash
	$("#trash").droppable({
			drop: function( event, ui ) {
					if(confirm("Trash " + ui.draggable.context.title + " ??")){
						LG.wb.App.Browser.removeFav(ui.draggable.context.id);
					}	
			
			},
	});
	// trash
	$("#trash2").droppable({
			drop: function( event, ui ) {
					if(confirm("Remove " + ui.draggable.context.title + " from blacklist ??")){
						LG.wb.App.Browser.removeBL(ui.draggable.context.id);
					}	
			
			},
	});
	

	// 3d canvas as drop target
	$("#content").droppable({
		drop : function(event, ui) {
			//			console.log(ui);
			LG.wb.App.Browser.loadFav(ui.draggable.context.id);
		}
	});




	$('#tabs-About').mouseover(function() {
		$(this).css('cursor', 'help');
	});

	// Activate Tabs	
	$("#tabs").tabs();
	$('#tabs').css('display', 'block');

	LG.wb.App.Browser.loadLists();
// 	
	$("#tabs-Favourites img").each(function(){
    	var imgsrc = $(this).attr('src');
    //	if(imgsrc.match('_th.jpg') || imgsrc.match('_home.jpg')){
  	//	imgsrc = thumbToLarge(imgsrc);
  		(new Image()).src = imgsrc;   
    //	}
	});
	LG.wb.App.Browser.resized();

	LG.wb.App.Browser.animate();

	// open something or not ??
	if(DEF_WPAGE != '') {
		setTimeout(function(){ 
			LG.wb.App.Browser.load(DEF_WPAGE);


		}, 1000);

	}


});
