/**
 * @author Lukas Goldschmidt lukas.goldschmidt@googlemail.com
 * @version     0.1
 */

/**
 * @namespace LG
 * @namespace LG.wb
 * @namespace LG.wb.Class
 */

LG.wb.LBL_STYLE_GRADIENT = 2;
LG.wb.LBL_STYLE_CLEAR = 4;
LG.wb.LBL_STYLE_TOP = 8;

LG.wb.Class.Item = new Class(/** @lends LG.wb.Class.Item.prototype */
{
	/** an array to hold some images */
	images : [],
	/** an array for Alchemy API results */
	alc : [],
	/** an array for Wikipedia Categories */
	categories : [],
	/** an array for clickable 3D objects */
	click_items : [],
	/** an array for RDF Types */
	rdf_type : [],
	/** Default Thumbnail URL	*/
	scriptRoot : '/wikipedia3d/',
	deftbUrl : '/wikipedia3d/images/wikipedia_256.png',
	/** 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',

	dbp_resource : new String(),
	dbp_data : new String(),
	noramlized : null,

	type_label_y : 0,
	_cmstart : "",
	_done : false,
	_more : false,
	
	/**
	 * @class LG.wb.Class.Item
	 * An Item Object containing the data and its representation of a Wikipedia page
	 * @member LG.wb.Class.Item
	 * @param {Object} brw
	 * @param {String} wpage
	 * @constructs LG.wb.Class.Item
	 */
	initialize : function(brw, wpage) {
		/** The Wikipage 		 */
		this.wpage = wpage;
		this.lng=false;
		this.lat=false;
		this.abstr = false;

		/** an array for Wikipedia Links */
		this.links = [];
		/** an array for External Links */
		this.extlinks = [];
		/** an array for Wikipedia Language Links */
		this.langlinks = [];
		/** an array for Yago Class examples */
		this.yago_type_links = [];
		/** an array for Category examples */
		this.cat_links = [];
		this.Browser = brw;
		this.lang = this.Browser.cur_lang;

		this.hashid = Sha1.hash(this.lang + "_" + this.wpage.replace(/[\s\,]/g,"_"));

		this.over_pop = new Sound( [  "sfx/Beeps-very-short-01.wav.OGG" ] , 275, 5 );
		this.over_pop.setVolume(0.1);
		this.click_pop = new Sound( [  "sfx/Pop-01.wav.OGG" ] , 275, 30);
		this.click_pop.setVolume(0.9);

		/** The current drift of the item */
		this.drift = new THREE.Vector3();
		/** The current destination of the item */
		this.dest = new THREE.Object3D();

		/** The current Wikipedia api url */
		this.wpurl = this.Browser.wpurl;
		// 'http://en.wikipedia.org/w/api.php';
		/** The current Alchemy api url */
		this.alurl = this.Browser.alurl;

//		this.img_url = this.Browser.img_url;
		/** The Wikipedia Page URL of this item */
		this.url = new String(this.wpurl);
		this.url = this.url.slice(0, this.url.lastIndexOf('/') - 1) + 'wiki/' + this.wpage;

		/** true if Wikipedia API returned Text */
		this.gottext = false;

		var that = this;


		// search Wikipedia
		this.search_wp();

		// make Label
		if(this.wpage.match(/\:/ig)) {
			//var col = 'rgba(35, 165, 218, 1)';
			var col = this.colFromString(this.wpage,60,80);
		} else {
			var col = 'rgba(238,232,170, 1)';

		}
		this.Label1 = this.makeLabel(300, 60, this.wpage, col, 48 , LG.wb.LBL_STYLE_TOP);
		this.Label1.position.x = 0;
		this.Label1.position.y = 220;

		this.Label1.clicked = function() {
			return that.clickedLabel();
		};
		this.click_items.push(this.Label1);

		// make Image
		this.Image1 = this.makeImage(300, 300, this.deftbUrl);
		this.Image1.clicked = function() {
			return that.clickedImage();
		};
		this.click_items.push(this.Image1);

		// make fav button
		this.favMe = this.makeImage(32, 32, this.favmeUrl);
		this.favMe.position.x = 86;
		this.favMe.position.y = 170;
		this.favMe.clicked = function() {
			return that.clickedFavme();
		};
		this.click_items.push(this.favMe);

		// make delete button
		this.delMe = this.makeImage(32, 32, this.delmeUrl);
		this.delMe.position.x = -120;
		this.delMe.position.y = 170;
		this.delMe.clicked = function() {
			return that.clickedDelme();
		};
		this.click_items.push(this.delMe);

		// make bl button
		this.blMe = this.makeImage(32, 32, this.blmeUrl);
		this.blMe.position.x = -86;
		this.blMe.position.y = 170;
		this.blMe.clicked = function() {
			return that.clickedBlme();
		};
		this.click_items.push(this.blMe);

		// make solo button
		this.soloMe = this.makeImage(32, 32, this.solomeUrl);
		this.soloMe.position.x = 120;
		this.soloMe.position.y = 170;
		this.soloMe.clicked = function() {
			return that.clickedSolome();
		};
		this.click_items.push(this.soloMe);

/*
		// Language label 
		for(var i in wp_languages){
			if(wp_languages[i].lang == this.lang){
				var langname = wp_languages[i].name; 
			}
		}
		var col = this.colFromString(langname,50,50);
		
		this.lang_lbl = this.makeLabel(100,20 , langname, col, 20 , LG.wb.LBL_STYLE_CLEAR);
		this.lang_lbl.position.x = 0;
		this.lang_lbl.position.y = 188;
		this.lang_lbl.position.z = 5 ;
*/		
		// the model
		this.model = new THREE.Object3D();
		this.model.addChild(this.favMe);
		this.model.addChild(this.soloMe);
		this.model.addChild(this.blMe);
		this.model.addChild(this.delMe);
		this.model.addChild(this.Label1);
		this.model.addChild(this.Image1);
//		this.model.addChild(this.over_pop);
//		this.model.addChild(this.click_pop);
		
		for (var idx in this.click_items){
			if(! $.isFunction(this.click_items[idx].mouseOut)){
				this.click_items[idx].mouseOut = function(){
					$("body").css("cursor", "default");
					this.position.z -=18;	
//					this.scale(new THREE.Vector3(1,1,1));	
				};
				this.click_items[idx].mouseIn = function(){
					$("body").css("cursor", "pointer");
					this.position.z +=18;	
//					this.scale(new THREE.Vector3(1.2,1.2,1.2));	
					that.over_pop.play();			
				};
				
			}
		}


		return this;
	},
	loadTexture : function(path) {

		var texture = new THREE.Texture(this.Browser.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;
y
		return material;

	},
	/** the image was clicked	*/
	clickedImage : function() {
		this.click_pop.play();			
		if(this.marker !== undefined )
			this.marker[0].map.panTo(this.marker[0].position);
//		this.Browser.showFullText(this);
		this.panToMe();
	

	},
	panToMe: function(){
		if(this.drift.isZero()){
			this.Browser.camera.panTo(new THREE.Vector3(this.model.position.x+80, this.model.position.y+30, this.model.position.z-380),100,33);
			
		} else {
			this.Browser.camera.panTo(new THREE.Vector3(this.dest.x+80, this.dest.z+30, this.dest.y-380),115,33);
			
		}
		this.Browser.cur_item_idx = this.hashid;		
		this.Browser.overview_toggle = false;

	},
	/** the favme icon was clicked	*/
	clickedFavme : function() {
		this.click_pop.play();			
		this.Browser.makeFav(this);
	},
	/** the favme icon was clicked	*/
	clickedSolome : function() {
		this.click_pop.play();			
		if(this.lang !== $("#langsel option:selected").val()){
			var tmp = this;
			this.Browser.reset();
			this.Browser.setlang(this.lang);
			this.Browser.load(tmp.wpage);

			this.Browser.setlang($("#langsel option:selected").val());
			var lang = $("#langsel option:selected").val();
			if(tmp.langlinks[lang] !== undefined){
				var _wpage = tmp.langlinks[lang].substring(tmp.langlinks[lang].lastIndexOf("/")+1);
				this.Browser.load(decodeURI(_wpage));
			}			

		}else {
			var tmp = this;
			this.Browser.reset();
			this.Browser.load(tmp.wpage);
			
		}
	},
	/** the favme icon was clicked	*/
	clickedDelme : function() {
		this.click_pop.play();			
		var del = this;
		this.Browser.remove(del);

	},
	/** the favme icon was clicked	*/
	clickedBlme : function() {
		this.click_pop.play();			
		this.Browser.makeBL(this);
	},
	/** the label was clicked	*/
	clickedLabel : function() {
		this.click_pop.play();			
		if(this.Browser.camera.isControlDown){
			this.Browser.setlang(this.lang);
			var l = Math.floor(Math.random() * this.links.length);
			var s = this.links[l];
			this.Browser.load(s);
			this.Browser.setlang($("#langsel option:selected").val());
			
		} else if(this.Browser.camera.isShiftDown){
			this.Browser.setlang(this.lang);
			for(var i = 0; i < this.Browser.maxele; i++) {
				var l = Math.floor(Math.random() * this.links.length);
				var s = this.links[l];
				this.Browser.load(s);
			}
			this.Browser.setlang($("#langsel option:selected").val());
			
		} else {
			this.Browser.showFullText(this);
			
		}
		 
	},
	/** make us an image of given width and height
	 * @param {int} w The desired width of the image
	 * @param {int} h The desired height of the image
	 * @param {String} img The image Url
	 * @return {THREE.Mesh} the finished Image
	 */
	makeImage : function(w, h, imgurl) {
				this.imgtex = THREE.ImageUtils.loadTexture(imgurl);

//		this.imgtex = THREE.ImageUtils.loadTexture(this.Browser.proxyurl + imgurl);
		this.imgtex.needsUpdate = true;
		this.imgmat = new THREE.MeshBasicMaterial({
			//			color: 0xffff00,
			//			combine: THREE.MultiplyOperation,
			map : this.imgtex,
			//			 transparent: true,
			//			 wireframe : false,
			//			 shading : THREE.SmoothShading
		});

		//		var cubeGeometry = new THREE.CubeGeometry( w, h, 10 );
		var geometry = new THREE.PlaneGeometry(w, h, 3, 3);
		var ret = new THREE.Mesh(geometry, this.imgmat);
		ret.doublesided = true;
		return ret;

	},
	/** make us a label	of given width and height with arbitrary text and color
	 * @param {int} w The desired width of the label
	 * @param {int} h The desired height of the label
	 * @param {String} t The desired text of the label
	 * @param {String} col a string representing the text color e.g. "rgba(127,127,127,1)"
	 * @param {int} fontsize The desired fontsize of the text
	 * @return {THREE.Mesh} the finished Text Label
	 */
	makeLabel : function(w, h, t, col, fontsize, style) {

		var geometry = new THREE.PlaneGeometry(w, h, 3, 3);
		var canvas = document.createElement('canvas');
		canvas.width = w * 2;
		canvas.height = h * 2;
		var ctx = canvas.getContext("2d");
		switch(style){
			case  LG.wb.LBL_STYLE_GRADIENT:
				// Create gradients
				var lingrad = ctx.createLinearGradient(0, 0, 0, h * 2);
				lingrad.addColorStop(0, '#666');
				lingrad.addColorStop(0.5, '#333');
				lingrad.addColorStop(0.5, '#333');
				lingrad.addColorStop(1, '#666');
				ctx.fillStyle = lingrad;
				// ctx.globalAlpha = 0.5;
				ctx.fillRect(0, 0, w * 2, h * 2);

			break;
			case  LG.wb.LBL_STYLE_CLEAR:
				ctx.globalAlpha = 0;
				ctx.fillRect(0, 0, w * 2, h * 2);
			break;

			case  LG.wb.LBL_STYLE_TOP:
				// Create gradients
				var lingrad = ctx.createLinearGradient(0, 0, 0, h * 2);
				lingrad.addColorStop(0, '#666');
				lingrad.addColorStop(0.5, '#333');
				lingrad.addColorStop(0.5, '#333');
				lingrad.addColorStop(1, '#666');
				ctx.fillStyle = lingrad;
				// ctx.globalAlpha = 0.5;
				ctx.fillRect(0, 0, w * 2, h * 2);
				// Language label 
				for(var i in wp_languages){
					if(wp_languages[i].lang == this.lang){
						var langname = wp_languages[i].name; 
					}
				}
				var lcol = this.colFromString(langname+langname,30,70);
				ctx.fillStyle = lcol;
				ctx.globalAlpha = .7;
				ctx.font = ' 24px sans-serif';
				ctx.textBaseline = 'top';
				ctx.textAlign = 'right';

				if(ctx.fillText) {
					ctx.fillText(langname, w*2 -32 , 6, 200);
				}

			break;

/*
		// Language label 
		for(var i in wp_languages){
			if(wp_languages[i].lang == this.lang){
				var langname = wp_languages[i].name; 
			}
		}
		var col = this.colFromString(langname,50,50);
		
		this.lang_lbl = this.makeLabel(100,20 , langname, col, 20 , LG.wb.LBL_STYLE_CLEAR);
		this.lang_lbl.position.x = 0;
		this.lang_lbl.position.y = 188;
		this.lang_lbl.position.z = 5 ;
*/		




		}


		ctx.fillStyle = col;
		ctx.globalAlpha = 1;
		ctx.font = 'bold ' + fontsize + 'px sans-serif';
		ctx.textBaseline = 'top';
		ctx.textAlign = 'center';

		if(ctx.fillText) {
			ctx.fillText(t, w, 2 * h / 3, w * 2);
		}
		var texture = new THREE.Texture(canvas);
		var material = new THREE.MeshBasicMaterial({
			map : texture,
			combine: THREE.MultiplyOperation,
			wireframe : false,
//			shading : THREE.SmoothShading,
			transparent: true
		});
		//	material.depthTest = false;
		texture.needsUpdate = true;
		var ret = new THREE.Mesh(geometry, material);
		ret.doublesided = true;
		return ret;
	},
	/** This will initiate a wikipedia parse action
	 */
	search_wp : function() {
		// There are some site restrictions which make this workaround necessary ...
		var url = this.wpurl + "?action=parse&page=" + this.wpage + "&format=json&callback=LG.wb.App.Browser.items['" + this.hashid + "'].wp_callback   ";
		var elem = document.createElement('script');
		elem.setAttribute('src', url);
		elem.setAttribute('type', 'text/javascript');
		document.getElementsByTagName ('head')[0].appendChild(elem);
	},

	sparqlcb : function(data) {
		console.log(data);
	},

	search_dbp_sparql : function() {
		var that = this;
		var normalized = new String();
		if(this.lang === "en") {
			normalized = this.wpage.replace(/\s/g,"_");
		} else if(this.langlinks["en"] !== undefined) {
			normalized = decodeURI(this.langlinks["en"].substr(this.langlinks["en"].lastIndexOf("/") + 1).replace(/\s/g,"_").trim());

		} else {
			normalized = false;
		}
		this.normalized = normalized;
		if(normalized) {
			this.dbp_resource = 'http://dbpedia.org/resource/' + normalized;
			console.log(this.wpage + ' -> ' + this.dbp_resource);
			var url =  "http://dbpedia.org/sparql";
			var query = "SELECT DISTINCT ?type ?long ?lat ?abstract WHERE { <" + this.dbp_resource + "> rdf:type ?type  . " 
				+ "OPTIONAL {<" + this.dbp_resource + "> <http://dbpedia.org/ontology/abstract> ?abstract}." 
				+ "FILTER(lang(?abstract) = '" + this.lang + "')." 
				+ "OPTIONAL {<" + this.dbp_resource + "> geo:long  ?long} . " 
				+ "OPTIONAL {<" + this.dbp_resource + "> geo:lat  ?lat} . }";

			var param = "default-graph-uri=http://dbpedia.org";
			param +="&format=application%2Fsparql-results%2Bjson&save=display";
			param += "&query=" + $.URLEncode(query);
			$.ajax({
				url : url,
				context : that,
				data : param,
				context : that,
				dataType : 'jsonp',
				success: function(data){
					return that.dbp_callback(data);
					
				}
			});

		}
	},

	process : function() {
		var that = this;
		// default place mark icon
		var myicon =  "/wikipedia3d/images/map_icons/world.png";
		// default zoom
		var zoom = 14;		
		// Type handling
		this.type_label_y = 80 - this.rdf_type.length * 20 / 2;
		//console.log(this.rdf_type);
		$.each(this.rdf_type, function(key, val) {
			if(val.search(/dbpedia\.org\/class\/yago/) > 0) {
				var yago_type = val.substr(val.lastIndexOf("/") + 1);
				var url = "http://dbpedia.org/sparql";
				var query = ''
				+ 'SELECT ' + 'DISTINCT * WHERE {' + '?item rdf:type <http://dbpedia.org/class/yago/' + yago_type + '> . ' + '	OPTIONAL {?item rdfs:label ?label}.' + 'OPTIONAL {?item geo:long  ?long}.' + 'OPTIONAL {?item geo:lat  ?lat}.' + 'OPTIONAL {?item <http://dbpedia.org/ontology/abstract> ?abstract}.' + "FILTER(lang(?abstract) = '" + that.lang + "')." + "FILTER(lang(?label) = '" + that.lang + "')." + '} LIMIT ' + that.Browser.maxTypeFetch + ' ';
				var me = that;
				var param = "default-graph-uri=http://dbpedia.org";
				param +="&format=application%2Fsparql-results%2Bjson&save=display";
				param += "&query=" + $.URLEncode(query);
				$.ajax({
					url : url,
					data : param,
					context : that,
					dataType : 'jsonp',
					success : function(data) {
						// console.log(yago_type);
						// console.log(data);
						var types = data.results.bindings;
						me.yago_type_links[yago_type] = new Array();
						var that = me;
						$.each(types, function(key, val) {
							if(that.yago_type_links[yago_type].indexOf(val) < 0){
								that.yago_type_links[yago_type].push(val);
								
							}
						});
						// console.log(me.yago_type_links[yago_type]);
						if(me.yago_type_links[yago_type].length > 0) {
							var col = me.colFromString(yago_type,100,100);
							var text = me.yago_type_links[yago_type].length + " " + yago_type;
							var label = that.makeLabel(120, 18, unescape(text), col, 16 , LG.wb.LBL_STYLE_GRADIENT);
							label.position.x = -200;
							label.position.z = 12;
							label.position.y = that.type_label_y;
							that.type_label_y += 20;
							label.mouseIn = function(){
								me.over_pop.play();			
								label.position.z +=12;	
								$("body").css("cursor", "pointer");
							},
							label.mouseOut = function(){
								label.position.z -=12;	
								$("body").css("cursor", "default");
						},
							label.clicked = function() {
								me.click_pop.play();			
								if(me.Browser.camera.isShiftDown){
									me.Browser.setlang(me.lang);
									for(var i = 0; i < me.Browser.maxele; i++) {
										var l = Math.floor(Math.random() * me.yago_type_links[yago_type].length);
										var s = me.yago_type_links[yago_type][l]['label'].value;

										me.Browser.load(s);
									}
									me.Browser.setlang($("#langsel option:selected").val());

								}else if (me.Browser.camera.isControlDown) {
									me.Browser.setlang(me.lang);
//									for(var i = 0; i < me.yago_type_links[yago_type].length; i++) {
//										var s = me.yago_type_links[yago_type][i];
//										me.Browser.load(s);
//									}
									var l = Math.floor(Math.random() * me.yago_type_links[yago_type].length);
									var s = me.yago_type_links[yago_type][l]['label'].value;
									me.Browser.load(s);
									me.Browser.setlang($("#langsel option:selected").val());

								} else {
									me.Browser.showTypeLinks(me,yago_type);

								};
							};
							that.click_items.push(label);
							that.Browser.click_items.push(label);
							that.model.addChild(label);
						}
					},
				});
//				AncientGreekCities
				if(yago_type == 'DestroyedLandmarks') {
					myicon =  "/wikipedia3d/images/map_icons/ruins-2.png";
					zoom = 14; 		
				}
				if(yago_type ==  'Bridge102898711') {
					zoom=16;
					myicon =  "/wikipedia3d/images/map_icons/bridge_modern.png";
				}
				if(yago_type ==  'AncientGreekCities') {
					zoom=14;
					myicon =  "/wikipedia3d/images/map_icons/monument.png";
				}
				
			} else if(val.search(/dbpedia\.org\/ontology/) > 0) {
				var dbp_type = val.substr(val.lastIndexOf("/") + 1);
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'AnatomicalStructure')) {
					 alert(that.normalized + " is an Anatomical Structure");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Beverage')) {
					 alert(that.normalized + " is a Beverage");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'ChemicalCompound')) {
					// alert(that.normalized + " is a Chemical Compound");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Currency')) {
					 alert(that.normalized + " is a Currency");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Disease')) {
					 alert(that.normalized + " is a Disease");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Drug')) {
					// alert(that.normalized + " is a Drug");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'EthnicGroup')) {
					 alert(that.normalized + " is an Ethnic Group");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Event')) {
					// alert(that.normalized + " is an Event");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Grape')) {
					// alert(that.normalized + " is a Grape");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Infrastructure')) {
					// alert(that.normalized + " is Infrastructure");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Language')) {
					// alert(that.normalized + " is a Language");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'MeanOfTransportation')) {
					// alert(that.normalized + " is a Mean of transportation");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'MusicGenre')) {
					// alert(that.normalized + " is a Music Genre");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'OlympicResult')) {
					// alert(that.normalized + " is an Olympic Result");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Organisation')) {
//					 alert(that.normalized + " is an Organisation");
				}

				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Person')) {
					// alert(that.normalized + " is a Person");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Place')) {
				 // alert(that.normalized + " is a Place");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Planet')) {
					// alert(that.normalized + " is a Planet");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Protein')) {
					// alert(that.normalized + " is a Protein");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Species')) {
					// alert(that.normalized + " is a Species");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'SupremeCourtOfTheUnitedStatesCase')) {
					// alert(that.normalized + " is a SupremeCourtOfTheUnitedStatesCase");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Weapon')) {
					// alert(that.normalized + " is a Weapon");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Website')) {
					// alert(that.normalized + " is a Website");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Work')) {
					// alert(that.normalized + " is a Work");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'NaturalPlace')) {
//					 alert(that.normalized + " is a Natural Place");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Country')) {
					zoom = 7;
//					 alert(that.normalized + " is a Country");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'City')) {
//					 alert(that.normalized + " is a City");
					zoom = 11;
					myicon =  "/wikipedia3d/images/map_icons/house.png";
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Artist')) {
//					 alert(that.normalized + " is a Artist");
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'Airport')) {
					myicon =  "/wikipedia3d/images/map_icons/airport.png";
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'MountainRange')) {
					myicon =  "/wikipedia3d/images/map_icons/mountains.png";
				}
				if(that.Browser.reasoner.isSubClassOf(dbp_type, 'MilitaryConflict')) {
					myicon =  "/wikipedia3d/images/map_icons/war.png";
				}

			}
		});
		this.marker_icon = myicon;
		this.marker_zoom = zoom;
		this.process_geoData();

	},
	process_geoData : function(){
		if(this.marker_icon == undefined){
			var myicon = "/wikipedia3d/images/map_icons/world.png";
			
		}else {
			var myicon = this.marker_icon;
			
		}
		if(this.marker_zoom == undefined){
				var zoom = 14;		
			
		}else {
			var zoom = this.marker_zoom;
			
		}
		// Geo location handling
		var that = this;
		if(!this.lng){
			// nothing from dbpedia , lets look at a possible geohack link :)
			// http://toolserver.org/~geohack/geohack.php?pagename=Wat%E2%80%99s_Dyke&language=de&params=52.986666666667_N_3.0286111111111_W_region:GB-WLS/GB-ENG_type:landmark
			//	console.log(this.extlinks);
			
			$.each(this.extlinks, function(key, val){
				if(val.search(/toolserver\.org/i) > 0){
					val = val.replace(/\_{2}/g, "_");
					var pat = /params\=[\d\.\_]*_[N|S]/ig;
					var lat = pat.exec(val)[0];
					lat = lat.substring(lat.indexOf("=") + 1,lat.lastIndexOf("_")); // .replace("_",".");					
					if(lat.indexOf("_") > -1){
						// oh oh sometimes it is deg_min some other times deg_min_sec .... so :
						var deg = lat.substring(0,lat.indexOf("_"));
						
						var min = lat.substr(lat.indexOf("_")+1);
						if(min.indexOf("_") > 0){
							var sec = min.substr(min.indexOf("_")+1);
							min = min.substring(0, min.indexOf("_"));
						} else {
							var sec = 0;
						}		
						console.log(deg,min,sec);										
						lat = deg.toInt() + min.toInt() * 1/ 60 + sec.toInt() * 3600; 
					}
					if(val.indexOf("_S_") > -1){
						lat = lat * -1;						
					}

					var pat2 = /[N|S]_[\d\.\_]*_[E|W]/ig;
					var lng = pat2.exec(val)[0];
					lng = lng.substring(lng.indexOf("_") + 1,lng.lastIndexOf("_")) // .replace("_",".");					

					if(lng.indexOf("_") > -1){
						// oh oh sometimes it is deg_min some other times deg_min_sec .... so :
						var deg = lng.substring(0,lng.indexOf("_"));
						
						var min = lng.substr(lng.indexOf("_")+1);
						if(min.indexOf("_") > 0){
							var sec = min.substr(min.indexOf("_")+1);
						} else {
							var sec = 0;
						}												
						lng = deg.toInt() + min.toInt() * 1/ 60 + sec.toInt() * 3600; 
					}
					if(val.indexOf("_W_") > -1){
						lng = lng * -1;						
					}


					console.log('Coordinates Toolserver Hack : ' + lat + ', ' + lng);
					that.lat = lat;
					that.lng = lng;
				}
			});
			
		}
		if(this.lng !== false && this.marker == undefined){
			
			var text = "<h2>" + this.wpage + "</h2>" + this.makeButtonsHTML(this.wpage).html() + this.abstr;
			var m_opt = {
					'position' : this.lat.toString() + "," + this.lng.toString(),
					'bounds' : true, 
					'icon' : myicon,
					'title' : this.wpage,
					'animation' : google.maps.Animation.DROP
			};
			var inf_opt = {
				content : text,
			};
						
			this.marker = document.getElementById('mapFrame').contentWindow.addMarker(m_opt, inf_opt, this, zoom );
			// make marker button
			var label  = this.makeImage(32, 37, myicon);
			label.position.x =  0;
			label.position.y = 170;
			label.mouseIn = function(){
				that.over_pop.play();			
				label.position.z +=12;	
				$("body").css("cursor", "pointer");
			},
			label.mouseOut = function(){
				label.position.z -=12;	
				$("body").css("cursor", "default");
			},
			label.clicked = function() {
				// http://api.geonames.org/findNearbyWikipedia?lat=52.529040&lng=13.340280&username=lgolds&lang=de&maxRows=24&radius=12

				that.click_pop.play();			
				that.marker[0].map.panTo(that.marker[0].position);
				$("#tabs").tabs('select','tabs-GMap');
				if(that.Browser.camera.isShiftDown){
					var me = that;
					var url = "http://api.geonames.org/findNearbyWikipediaJSON";
					var param = "username=lgolds";
					param += "&maxRows=12";
					param += "&lng=" + that.lng;
					param += "&lat=" + that.lat;
					param += "&radius=12";
					param += "&lang=" + that.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){
									me.Browser.load(res[idx].title);
									
									
									
								}
							}
						}
					});	
				}
			};
			this.click_items.push(label);
			this.Browser.click_items.push(label);
			this.model.addChild(label);
			$("#tabs").tabs('select','tabs-GMap');
		}

	},
	dbp_callback : function(data, textStatus, jqXHR) {
		if(textStatus !== undefined)
			console.log(textStatus);

		var that = this;
		if(data) {
//			console.log(data);
			var res = data.results.bindings;
			$.each(res, function(key, val) {
				if(val['type'] !== undefined){
					if(that.rdf_type.indexOf(val['type'].value) < 0){
						that.rdf_type.push(val['type'].value);
					}
				};
				if(val['long'] !== undefined){
					that.lng = val['long'].value;
					that.lat = val['lat'].value;
				};
				if(val['abstract'] !== undefined){
					that.abstr = val['abstract'].value;
				};
			});
		} else {
			return;
		}

		this.process();
	},
	
	fetchCatMembers:function(cat,cmstart){
		this._more = false;	
		var url=this.wpurl;
		var cmstart = cmstart;
		var that = this;			
		var param = "action=query";
		param += "&cmstart=" + cmstart;
		param += "&format=json&list=categorymembers&cmsort=timestamp&cmdir=desc&limit=max"; // + that.Browser.maxTypeFetch;
		param += "&cmtitle=" + cat ;
		$.ajax({
			url : url,
			data : param,
			context : that,
			dataType : 'jsonp',
			success : function(data) {
				var me = that;
//				console.log(that.wpage + " :::::>>>>> " + cat);
//				console.log(data);
				
				if(data){
					$.each(data.query.categorymembers, function (key,val){
						if(val['ns'] == 0){
							me.cat_links[cat].push(val['title']);
							
						}
					});	

					if(data['query-continue'] !== undefined && that.cat_links[cat].length < that.Browser.maxTypeFetch){
//						console.log('more cats .... ' + data['query-continue'].categorymembers.cmstart);
						that.fetchCatMembers(cat,data['query-continue'].categorymembers.cmstart);

					}else {
						var col = that.colFromString(cat,60,80);
						var text = that.cat_links[cat].length + " " + cat.substring(cat.indexOf(":") + 1);
						var label = that.makeLabel(120, 18, unescape(text), col, 16 , LG.wb.LBL_STYLE_GRADIENT);
						label.position.x = 200;
						label.position.z = 12;
			
						label.position.y = that.cat_label_y;
						that.cat_label_y += 20;
						var me = that;
						label.mouseIn = function(){
							me.over_pop.play();			
							label.position.z +=12;	
							$("body").css("cursor", "pointer");
						},
						label.mouseOut = function(){
							label.position.z -=12;	
							$("body").css("cursor", "default");
						},
						label.clicked = function() {
							me.click_pop.play();			
							if(me.Browser.camera.isShiftDown){
								me.Browser.setlang(me.lang);
								for(var i = 0; i < me.Browser.maxele; i++) {
									var l = Math.floor(Math.random() * me.cat_links[cat].length);
									var s = me.cat_links[cat][l];
									me.Browser.load(s);
								}
								me.Browser.setlang($("#langsel option:selected").val());
							}else if (me.Browser.camera.isControlDown) {
								me.Browser.setlang(me.lang);
//								for(var i = 0; i < me.cat_links[cat].length; i++) {
//									var s = me.cat_links[cat][i];
//									me.Browser.load(s);
//								}
								var l = Math.floor(Math.random() * me.cat_links[cat].length);
								var s = me.cat_links[cat][l];
								me.Browser.load(s);
								me.Browser.setlang($("#langsel option:selected").val());
						} else {
								
								me.Browser.showCatLinks(me,cat);
							}
						};
						that.click_items.push(label);
						that.Browser.click_items.push(label);
						that.model.addChild(label);
						
					}
				}else{
				}
			},
		}); // end ajax

		
	},
	process_cats : function() {
		this.cat_label_y = 80 - this.categories.length * 20 / 2;
		var that = this;
		$.each(this.categories, function(key, cat) {
			var cat = cat;
			var url = that.wpurl ;
			var that1 = that;
			that.cat_links[cat] = new Array();
			that._done = false ;
			that._cmstart = ""; 
			that.fetchCatMembers(cat,"");
		}); 
	},

	/** an initial wikimedia parse-page-query returns its results ....
	 * @param {Array} data The resultset
	 */
	wp_callback : function(data) {
		// process received data
		var that = this;
		try {
			$.each(data['parse']['text'], function(key, val) {
				that.text = val;
				$("#dialog-message").html(that.text);
				var me = that;
				$("#dialog-message img").each(function(index) {
					if(this.width > 100 || this.height > 100)
						me.images.push(this.src);
				});
				if(that.images.length == 0) {
					that.images.push(that.deftbUrl);
				}
				if(that.images.length == 1) {
					that.setimage(that.images[0]);
				} else {
					that.setimage(that.images[Math.floor(Math.random() * that.images.length)]);
				}
			});
		} catch(err) {
			return false;
		}
		if(this.text === undefined || this.text === '') {
			this.text = '<h2><a href="' + this.url + '" target="_blank" >' + this.url + '</a></h2>';
			this.gottext = false;

		} else {
			this.gottext = true;

		}
		$.each(data['parse']['categories'], function(key, val) {
			$.each(val, function(key, val) {
				if(key == "*") {
					if(typeof(val) !== 'string') val = val.toString();
					if(val.search(/articles|wikipedia|all/i) < 0) {
						that.categories.push("Category:" + val);
					}
				} else {
				}
			});
		});
		$.each(data['parse']['links'], function(key, val) {
			if(val['exists'] == "" && val['ns'] == 0)
				that.links.push('' + val['*']);
		});
		$.each(data['parse']['langlinks'], function(key, val) {
			that.langlinks[val['lang']] = val['url'];
		});
		$.each(data['parse']['externallinks'], function(key, val) {
			that.extlinks.push(val.toString());
		});
		if(this.links.length == 1){
			console.log(this.links);
			this.Browser.load(this.links[0]);
			
		}else{
			
			this.search_dbp_sparql();
			this.process_cats();
			$(document).oneTime(3600, 	function(){
				that.process_geoData()
			});

		
		}
	},
	/**
	 * Makes a unique color for a given string
	 * Uses ColorJizz Library !!!
	 * @param (String) val the string
	 * @param (int) s a value for Saturation 0 - 100
	 * @param (int) v a value for brightness 0 - 100
	 * @return (String) rgpa(20,20,20,0.5)
	 */
	colFromString : function(val,s,v){
		var h = 0;
		for(var i = 0; i < val.length; i++) {
			h += val.charCodeAt(i);
		}
		h = h % 360;
		
		var hsv = new HSV(h,s,v);
		var rgb = hsv.toRGB();
		col = "rgba(" + parseInt(rgb.r) + ", " + parseInt(rgb.g) + ", " + parseInt(rgb.b) + ", 1)";
		// console.log(val + " - > " + col);
		return col;
	},

	/**
	 * Sets the image of the texture this.imgmat to the given url
	 * @param {String} imgurl the url of the image we want to display
	 */
	setimage : function(imgurl) {
		//		alert(imgurl);
//		this.imgtex = THREE.ImageUtils.loadTexture(this.Browser.proxyurl + imgurl);
		this.imgtex = THREE.ImageUtils.loadTexture( imgurl);
		this.imgmat = new THREE.MeshBasicMaterial({
			//			color: 0xffff00,
			//			combine: THREE.MultiplyOperation,
			map : this.imgtex,
			transparent : true,
			//			 wireframe : false,
			//			 shading : THREE.SmoothShading
		});

		this.imgtex.needsUpdate = true;
		this.materials = [this.imgmat // front
		];
		this.Image1.materials = this.materials;

	},

	/**
	 * Makes a row of click buttons like fav, del, open wpage,abstract solo
	 * for display on marker info and wpage view ...
	 *
	 */
	makeButtonsHTML : function (wpage){
		var e = $( document.createElement('div') );
		e.append('<a href="#" onclick="LG.wb.App.Browser.remove(\''+ wpage +'\')"><img src="'+LG.wb.App.Browser.delmeUrl+'" width="24" height="24" alt="delete" /></a> ');
		return e;
	},
	
	/**
	 * Tells the item to animate its position to the given coordinates
	 * @param {Float} x
	 * @param {Float} y
	 * @param {Float} z
	 */
	goTo : function(x, y, z) {

		this.dest.position.x = x;
		this.dest.position.y = z;
		this.dest.position.z = y;
	},
	
	/**
	 * Animates the Item periodically
	 */
	animate : function() {
		this.model.lookAt(this.Browser.camera.position);
//		this.over_pop.update(this.camera);
//		this.click_pop.update(this.camera);
		this.drift.sub(this.dest.position, this.model.position);
		if(!this.drift.isZero()) {
			this.model.position.addSelf(this.drift.multiplyScalar(0.5));
		}

		if(Math.random() < 0.0002) {
			if(this.images.length == 1) {
				this.setimage(this.images[0]);
			} else {

				this.setimage(this.images[Math.floor(Math.random() * this.images.length)]);

			}

		}
	}
});
