var loc = {alize:{}};

var flickr = {
	
	url: 		"http://api.flickr.com/services/rest/",
	api_key:	"9b629a5deea5f5e9423ddab9eebca3be",
	
	search: {
		bbox:				"-180,-90,180,90",
		accuracy:			1,
		page:				0,
		per_page:			50,
		extras:				"geo",
		min_upload_date:	1,
		sort:				"date-posted-desc"
	},
	
	userid: {
		method:				"flickr.people.findByUsername"
	},
	
	photoset: {
		
		method:				"flickr.photosets.getList"
	}
};

var SetRecord = Ext.data.Record.create(["title", "id"]);

loc.alize.me = {

	map: null,
	items: null,
	bounds: new GLatLngBounds(new GLatLng(-15,-60),new GLatLng(45,60)),
	flickrPreview: null,
	flickrBackground: null,
	pinkIcon: new GIcon(),
	markerUrl: "../images/",
	user:"",
	size: {width:502, height:302},
	resizer: null,
	
	zoomControl: null,
	typeControl: null,
	scaleControl: null,

	init: function(){
	
		this.params = {};
		try {
		document.location.hash.split("/").each(function(hash){
		    var pair = hash.split(":");
			if (pair.length == 2){
		    	this.params[pair[0]] = pair[1];
			}
		}.bind(this));

		if(this.params.bbox){
			flickr.search.bbox = this.params.bbox;
		}
				
		this.initExt();
	
		if (GBrowserIsCompatible()) {
		
			this.initMap();
			
			this.pinkIcon.shadow = this.markerUrl + "marker/shadow.png";
			this.pinkIcon.image = this.markerUrl + "marker/blue.png";
			this.pinkIcon.transparent = this.markerUrl + "marker/transparent.png";
			this.pinkIcon.iconSize = new GSize(14, 18);
			this.pinkIcon.iconAnchor = new GPoint(6, 18);
			this.pinkIcon.infoWindowAnchor = new GPoint(5, 1);
			this.pinkIcon.shadowSize = new GSize(32, 18);

			var bg = new GIcon();
			bg.image = this.markerUrl + "flickr.gif";
			bg.iconSize = new GSize(80, 85);
			bg.iconAnchor = new GPoint(38, 85);
			
			this.flickrBackground = new GMarker(new GLatLng(0, 0), {
				icon:bg,
				zIndexProcess: function(){return 100000000;},
				clickable: false
			});
			
			var preview = new GIcon();
			preview.iconSize = new GSize(75, 75);
			preview.iconAnchor = new GPoint(36, 83);
			
			this.flickrPreview = new GMarker(new GLatLng(0, 0), {
				icon:preview,
				zIndexProcess: function(){return 100000001;}
			});
			
			GEvent.bind(this.flickrPreview, 'mouseout', this, function(evt) {
				this.flickrPreview.hide();
				this.flickrBackground.hide();
			});				
			
			if (this.items){
				this.draw();
			}
		}
		}catch(e){}
	},
	
	initMap: function(){
		
		this.map = new GMap2(document.getElementById("map"));
		this.checkBounds();	

		this.map.enableDoubleClickZoom();
		this.map.enableContinuousZoom();
		this.map.enableScrollWheelZoom();
		
		GEvent.addListener(this.map, 'zoomend', this.setLink.bind(this));
		GEvent.addListener(this.map, 'dragend', this.setLink.bind(this));
			
		this.resizer = new Ext.Resizable('map', {
	        width: this.size.width,
	        height: this.size.height,
	        minWidth:200,
	        minHeight:100,
			pinned: true
		});	
		
		this.resizer.on("resize", function(evt){
			
			this.map.checkResize();
			this.size = this.map.getSize();
			this.checkBounds();
			
		}, this);
		
		this.resizer.fireEvent("resize", this.resizer);

	},
	
	initExt: function(){
		
	    Ext.QuickTips.init();
	
	    this.form = new Ext.form.Form({
	        labelWidth: 75,
	        url:'#'
	    });
		
		this.sets = new Ext.data.SimpleStore({
		    fields: ['title', 'id']
		});	
		
		this.username = new Ext.form.TextField({
            fieldLabel: 'User Name',
            name: 'username',
			invalidText: "Unknown Flickr user!",
            width: 175,
            allowBlank:true,
			validationDelay: 1000,
			allowBlank: true,
			validator: (function(value){
				return true;
			}).bind(this)
        });

		this.username.oldValue_isValid = true;

		var checkuser = function(event){
			
			var value = event.getValue();
			
			if (value != this.username.oldValue){
			
				this.username.oldValue = value;
				
				if (value !== false){

					if (value === ""){
						
						this.userId.reset();
						this.setsCombo.disable();
						this.setsCombo.reset();
						
						this.load();
						
						return true;
					}	
					
					this.requestJson("method=" + flickr.userid.method + "&username=" + value);
					
					this.userId.setRawValue("Loading...");
					this.setsCombo.disable();
					this.setsCombo.setRawValue("Loading...");
					
					this.username.oldValue_isValid = true;
					
					return true;
				}
				
				this.username.markInvalid(this.username.oldValue_isValid);
			}			
		};

		this.username.on("valid", checkuser.bind(this));
		this.username.on("blur", checkuser.bind(this));
		this.username.on("invalid", (function(){
			
			this.userId.reset();
			this.username.oldValue_isValid = false;		
				
		}).bind(this));
		
		this.userId = new Ext.form.TextField({
            fieldLabel: 'User ID',
            name: 'userid',
			disabled: true, 
            width:175
        });
		
		this.tag = new Ext.form.TextField({
            fieldLabel: 'Tag',
            name: 'tag',
            width:175
        });
		
		this.setsCombo = new Ext.form.ComboBox({
			store: this.sets,
            fieldLabel: 'Set',
			mode: 'local',
			displayField: 'title',
			valueField: 'id',
			forceSelection: true,
			selectOnFocus: true,
			disabled: true,
            name: 'sets',
            width:175
        });
		
	    this.form.fieldset(
			{legend:'Photo'},
			this.username, this.userId, this.tag, this.setsCombo
		);
		
		this.width = new Ext.form.NumberField({
            fieldLabel: 'Width',
            name: 'width',
			maxValue: 1000,
			validator: (function(value){
				if (this.size.width != value){
					this.size.width = value;
					if(this.resizer){
						this.forceResize();
					}
				}
				return true;
				
			}).bind(this)
        });
		
		this.height = new Ext.form.NumberField({
            fieldLabel: 'Height',
            name: 'height',
			maxValue: 1000,
			validator: (function(value){
				if (this.size.height != value){
				
					this.size.height = value;
					if(this.resizer){
						this.forceResize();
					}
				}
				
				return true;
			}).bind(this)
        });
		
		this.form.fieldset({legend:'Map Dimension'}, this.width, this.height);
		
	    this.form.render('form');
		
		this.dialog = new Ext.BasicDialog("main-dialog", { 
	        modal:false,
			width: 350,
			height:350,
			resizable:false,
			animateTarget: 'show-dialog',
	        shadow:true,
			title:"Settings",
			autoCreate: true
		});	
		
		this.dialog.addButton("Show photos", (function(){
			this.load();
		}).bind(this));
		
		this.dialog.addKeyListener(13, this.load, this);
		
		Event.observe("show-dialog", 'click', (function(){
			this.dialog.show();
		}).bind(this));
				
		this.username.focus();
		
		if (this.params.tag) { this.tag.setRawValue(this.params.tag);}
		if (this.params.user) { 
			this.username.setRawValue(this.params.user);
			checkuser.bind(this)(this.username);
		} else {
			
			this.load();
		}
	},
	
	requestJson: function(url){
		new Ajax.ScriptRequest(flickr.url + "?api_key=" +  flickr.api_key + "&format=json&" + url);
	},
	
	load: function(){
		
		var url = "";
		
		$("map-status").innerHTML = "Loading ...";
		
		for (var all in flickr.search){
			url += all + "=" + flickr.search[all] + "&";
		}
		
		if (this.userId.getValue()){
			url += "user_id=" + this.userId.getValue() + "&";
		} 

		if (this.tag.getValue()){
			url += "tags=" + this.tag.getValue() + "&";
		}
		
		if (this.setsCombo.getValue()){
			url += "photoset_id=" + this.setsCombo.getValue() + "&method=" +  "flickr.photosets.getPhotos";
		} else {
			url +="method=" +  "flickr.photos.search";
		}
		
		this.requestJson(url);
		
		if (this.map){
		
			this.setLink();
		}
				

	},
	
	setLink: function(){
		
		var t = new Template('<iframe src="http://loc.alize.us/embed/#/#{params}" width="#{width}" height="#{height}" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe>');
		var params = "";
		
		flickr.search.bbox = this.bbox();
		
		if (this.userId.getValue()){
			params += "user:" + this.userId.getValue() + "/";
		} 

		if (this.tag.getValue()){
			params += "tag:" + this.tag.getValue() + "/";
		}
		
		if (this.setsCombo.getValue()){
			params += "set:" + this.setsCombo.getValue() + "/";
		}
		
		params += "bbox:" + this.bbox() + "/";
		
		$("output-area").value = t.evaluate({
			params:params,
			width: this.size.width-2,
			height: this.size.height-2
		});
		
	},

	bbox: function(){
		
		var minLng, maxLng, minLat, maxLat;
		
		var nw = this.map.fromContainerPixelToLatLng(new GPoint(400,75));
		var b = this.map.getBounds();
		
		var sw = b.getSouthWest();
		var ne = b.getNorthEast();
		
		if (b.isFullLng()){
			minLng = -180;
			maxLng =  180;
		} else {
			minLng = nw.lng();
			maxLng = ne.lng();
			if (maxLng < minLng) {
				if (Math.abs(minLng) < Math.abs(maxLng)){
					maxLng = 180;
				} else {
					minLng = -180;
				}
			}			
		}
		
		if (b.isFullLat()){
			minLat = -90;
			maxLat =  90;
		} else {
			minLat = sw.lat();
			maxLat = nw.lat();
		}

		return minLng + "," + minLat + "," +  maxLng + "," +  maxLat;		
	},
	
	forceResize: function(){
		this.resizer.resizeTo(this.size.width,this.size.height); 
	},
	
	getSets: function(){
		this.requestJson("method=" + flickr.photoset.method + "&user_id=" + this.userId.value);
	},
	
	createMarker: function(point, item){
		
		var marker = new GMarker(point, {
			icon: this.pinkIcon,
			title: item.title
		});
		
		var markerUrl = this.markerUrl;
		
		GEvent.addListener(marker, 'click', function() {
			window.open("http://loc.alize.us/#/flickr:" + item.id);
		});
		
		var fp = this.flickrPreview;
		var bg = this.flickrBackground;
		
		GEvent.addListener(marker, 'mouseover', function() {
			fp.setImage("");
			fp.setPoint(point);
			bg.setPoint(point);
			fp.show();
			bg.show();				
			fp.setImage("http://farm" + item.farm + ".static.flickr.com/" + item.server + "/" + item.id + "_" + item.secret + "_s.jpg");
		});
		
		return marker;	
	},
	
	draw: function(){
		
		this.map.clearOverlays();
		
		this.bounds = new GLatLngBounds();
		
		this.map.addOverlay(this.flickrBackground);
		this.map.addOverlay(this.flickrPreview);
		
		var count = this.items.total;
		
		$("map-status").innerHTML = count + " photos";
		
		this.items.photo.each((function(photo){
			var point = new GLatLng(photo.latitude, photo.longitude); 
			this.bounds.extend(point);
			var marker = this.createMarker(point, photo);
			this.map.addOverlay(marker);
		}).bind(this));
		
		this.checkBounds();
		
		this.flickrBackground.hide();
		this.flickrPreview.hide();
	},
	
	checkBounds:function(){
		
		var zoom = this.map.getBoundsZoomLevel(this.bounds);
		
		var sw = this.bounds.getSouthWest();
		var ne = this.bounds.getNorthEast();
		
		var center = new GLatLng((sw.lat() + ne.lat())/2, (sw.lng() + ne.lng())/2);
					
		this.map.setCenter(center, Math.max(1,zoom-1));
		
		if (this.zoomControl){
			this.map.removeControl(this.zoomControl);
		}
			
		if (this.size.width > 400){
			this.zoomControl = new GMapTypeControl();
			this.map.addControl(this.zoomControl);
		}

		if (this.scaleControl){
			this.map.removeControl(this.scaleControl);
		}
		
		if (this.size.height > 350){
			this.scaleControl = new GScaleControl(); 
			this.map.addControl(this.scaleControl);
		}			
		
		if (this.typeControl){
			this.map.removeControl(this.typeControl);
		}	
		
		if (this.size.height > 150){
			this.typeControl = this.size.height < 300 ? new GSmallZoomControl() : new GLargeMapControl(); 
			this.map.addControl(this.typeControl);
		}
		
		this.width.setRawValue(this.size.width-2);
		this.height.setRawValue(this.size.height-2);
		
		$("map-footer").style.width = this.size.width + "px";
		
		this.setLink();
		
		//this.map.addControl(new GSmallZoomControl());
		//this.map.addControl(new GMapTypeControl());				
	},
	
	onData: function(data){
				
		this.items = data;
		
		if (this.map){
			
			this.draw();
		}
	}
};


var jsonFlickrApi = function(response){
	
	if (response.stat == "ok"){
		
		if (response.user){
			loc.alize.me.userId.setValue(response.user.nsid);
			loc.alize.me.getSets();
		} else if (response.photosets){
			loc.alize.me.sets.removeAll();
			loc.alize.me.sets.add(new SetRecord({title: "-- Any set --", id:null}));
			response.photosets.photoset.each(function(set){
				var data = new SetRecord({title: set.title._content, id:set.id});
				loc.alize.me.sets.add(data);
			});
			
			loc.alize.me.setsCombo.reset();
			if (response.photosets.photoset.length > 0){
				loc.alize.me.setsCombo.enable();
			}
			
			loc.alize.me.load();
			
		} else if (response.photos || response.photoset){
			loc.alize.me.onData(response.photos || response.photoset);
		}		
		
	} else {
		
		if (response.message == "User not found"){
			loc.alize.me.username.fireEvent("invalid");
			loc.alize.me.username.markInvalid(response.message);
		} else {
			alert("Error " + response.code + ": " + response.message);
		}
	}
};