/*
 * Copyright 2006, Jeffrey Palm.
 */

var Flickr = {
  Version: '1.1.2',
  prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
};
if((typeof Prototype=='undefined') || Flickr.prototypeVersion < 1.3)
	throw("Flickr requires the Prototype JavaScript framework >= 1.3");

function doSubmit(url) {
	//alert(url);
	//alert(document.getElementById("jeffForm"));
	//window.close();
}

//---------------------------------------------------
// Constants
// --------------------------------------------------
var API_KEY = 'bb394b10462edca89e719c63a68de4b3';
var REST = 'http://www.flickr.com/services/rest';
var PER_PAGE = 24;

//---------------------------------------------------
// Misc
// --------------------------------------------------
/**
 *  kind if one of
 *   - s	small square 75x75
 *   - t	thumbnail, 100 on longest side
 *   - m	small, 240 on longest side
 *   - -	medium, 500 on longest side
 *   - b	large, 1024 on longest side (only exists for very large original images)
 *   - o	original image, either a jpg, gif or png, depending on source format
*/
function imageURL(id,secret,server,kind) {
	//
	// http://www.flickr.com/services/api/misc.urls.html
	//
	var s = 'http://static.flickr.com/' + server + '/' + id + '_' + secret;
	if (kind && kind != '-') s += '_' + kind;
	s += '.jpg';			
	return s;
}


// --------------------------------------------------
// Classes
// --------------------------------------------------

Flickr.Format = Class.create();

Flickr.Format.prototype = {

	initialize: function() {

	}

	// ------------------------------------------------------------
	// Photos
	// ------------------------------------------------------------
	
	// all first arguments are Flickr.Photo


};

// singleton
var flickrFormat = new Flickr.Format();


Flickr.Service = Class.create();
Flickr.Service.prototype = {

	initialize: function() {
		this.usernames2ids = [];
	},

	getId: function(username, callback) {
		//
		// first check the cache
		//
		var id = this.usernames2ids[username];
		if (id) {
			callback(id);
			return;
		}
		//
		// now get it
		//
		var url = 'flickr.people.findByUsername';
		var prs = 'username=' + username;
		var thiz = this;
		var cab = function (res) {
			/*
<user nsid="12037949632@N01">
	<username>Stewart</username> 
</user>
			*/
			var doc = getDoc(res);
			if (!doc) return;
			var users = doc.getElementsByTagName('user');
			var user = users[0];
			thiz.usernames2ids[username] = id = user.getAttribute("nsid");
			callback(id);
			
		};
		this.request(url,prs,cab);
	},

	getContacts: function(that, callback) {
		var thiz = this;
		this.getId(that.getName(),
							 function(user_id) {
								 var url = 'flickr.contacts.getPublicList';
								 var prs = 'user_id=' + user_id;
								 var cab = function (res) {
								 /*
<contacts>
	<contact nsid="12037949629@N01" username="Eric" iconserver="1" ignored="1" /> 
	<contact nsid="12037949631@N01" username="neb" iconserver="1" ignored="0" /> 
	<contact nsid="41578656547@N01" username="cal_abc" iconserver="1" ignored="0" />
</contacts>
								 */
									 var doc = getDoc(res);
									 if (!doc) return;
									 var users = doc.getElementsByTagName('contact');
									 var matches = [];
									 $A(users).each(function(user) {
																		var username = user.getAttribute('username');
																		var newUser = new Flickr.User(username);
																		matches.push(newUser);
																	});
									 callback(matches);
								 };
								 thiz.request(url,prs,cab);
							 }
							 );
	},

	getSets: function(that, callback) {
		var thiz = this;
		this.getId(that.getName(),
							 function(user_id) {
								 var url = 'flickr.photosets.getList';
								 var prs = 'user_id=' + user_id;
								 var cab = function (res) {
								 /*							 
<photosets cancreate="1">
	<photoset id="5" primary="2483" secret="abcdef"
		server="8" photos="4">
		<title>Test</title>
		<description>foo</description>
	</photoset>
	<photoset id="4" primary="1234" secret="832659"
		server="3" photos="12">
		<title>My Set</title>
		<description>bar</description>
	</photoset>
</photosets>
								 */
									 var doc = getDoc(res);
									 if (!doc) return;
									 var doc = xml.documentElement;
									 var sets = doc.getElementsByTagName('photoset');
									 var matches = [];
									 $A(sets).each(function(set) {
																	 var id = set.getAttribute('id');
																	 var num = set.getAttribute('photos');
																	 var title = text(getElementByTagName(set,'title'));
																	 var descr = text(getElementByTagName(set,'description'));
																	 var p = new Flickr.PhotoSet(id,title,descr,num,that);
																	 matches.push(p);
																 });
									 callback(matches);
								 };
								 thiz.request(url,prs,cab);
							 }
							 );
	},

	getPages: function(that,callback) {
		var thiz = this;
		this.getId(that.getName(),
							 function(user_id) {
								 var url = 'flickr.people.getInfo';
								 var prs = 'user_id=' + user_id; 
								 var cab = function (res) {
								 /*							 
<person nsid="12037949754@N01" isadmin="0" ispro="0" iconserver="3">
	<username>bees</username>
	<realname>Cal Henderson</realname>
	<mbox_sha1sum>eea6cd28e3d0003ab51b0058a684d94980b727ac</mbox_sha1sum>
	<location>Vancouver, Canada</location>
	<photosurl>http://www.flickr.com/photos/bees/</photosurl> 
	<profileurl>http://www.flickr.com/people/bees/</profileurl> 
	<photos>
		<firstdate>1071510391</firstdate>
		<firstdatetaken>1900-09-02 09:11:24</firstdatetaken>
		<count>449</count>
	</photos>
</person>
								 */
									 var doc = getDoc(res);
									 if (!doc) return;
									 var countNode = doc.getElementsByTagName('count')[0];
									 var countString = countNode.firstChild.nodeValue;
									 var count = parseInt(countString);
									 var N = Math.round(count/PER_PAGE)-1;
									 var matches = [];
									 for (var i=0; i<N; i++) {
										 var p = new Flickr.Page(that,i+1);
										 matches.push(p);
									 }
									 callback(matches);
								 };
								 thiz.request(url,prs,cab);
							 }
							 );
		},

	/*
<photos page="2" pages="89" perpage="10" total="881">
	<photo id="2636" owner="47058503995@N01" 
		secret="a123456" server="2" title="test_04"
		ispublic="1" isfriend="0" isfamily="0" />
	*/

	getPhotosForLocation: function(loc,callback) {
		var url = 'flickr.photos.search';
		var prs = 'text=' + urlencode(loc) + '&per_page=' + PER_PAGE;
		var cab = function (res) {
			var doc = getDoc(res);
			if (!doc) return;
			var matches = new Array();
			var ss = doc.getElementsByTagName('photo');
			if (ss) {
				for (var i=0; i<ss.length; i++) {
					var s = ss[i];
					var id = s.getAttribute('id'); 
					var title = s.getAttribute('title');
					var secret = s.getAttribute('secret');
					var server = s.getAttribute('server');
					var owner = s.getAttribute('owner');
					var p = new Flickr.Photo(id,title,secret,server,owner);
					matches.push(p);
				}
			}
			callback(matches);
		};								 
		this.request(url,prs,cab);
	},

	/*
<photos page="2" pages="89" perpage="10" total="881">
	<photo id="2636" owner="47058503995@N01" 
		secret="a123456" server="2" title="test_04"
		ispublic="1" isfriend="0" isfamily="0" />
	*/
	getPhotosXML: function(that,callback,page) {
		var thiz = this;
		this.getId(that.getName(),
							 function(user_id) {
								 var url = 'flickr.people.getPublicPhotos';
								 var prs = 'user_id=' + user_id;
								 if (page) prs += '&page=' + page + "&per_page=" + PER_PAGE;
								 var cab = function (res) {
									 var doc = getDoc(res);
									 if (!doc) return;
									 callback(doc);
								 };								 
								 thiz.request(url,prs,cab);
							 },
							 page
							 );
	},

	getPhotos: function(that,callback,page) {
		var thiz = this;
		this.getPhotosXML(that,
											function(doc) {												
												thiz.callbackPhotos(doc,callback,that);
											},
											page
											);
	},
	
	/**
	 * Calls callback on all the Flickr.Photos created from theh DOM node
	 * contains <photo> elements
	 */
	callbackPhotos: function(doc,callback,owner) {
		var thiz = this;
		var ss = doc.getElementsByTagName('photo');
		var matches = [];
		$A(ss).each(function(s) {
									matches.push(thiz.newFlickrPhoto(s,owner));
								});
		callback(matches);
	},

	newFlickrPhoto: function(s,owner) {
		var id = s.getAttribute('id'); 
		var title = s.getAttribute('title');
		var secret = s.getAttribute('secret');
		var server = s.getAttribute('server');
		var p = new Flickr.Photo(id,title,secret,server,owner);
		return p;
	},


	// ------------------------------------------------------------
	// Photos
	// ------------------------------------------------------------
	
	// all first arguments are Flickr.Photo
	
	getPhotoInfoXML: function(that, callback) {
		var url = 'flickr.photos.getInfo';
		var prs = 'photo_id=' + that.getId();
		var cab = function (res) {
			var doc = getDoc(res);
			if (!doc) return;
			callback(doc);
		};
		this.request(url,prs,cab);
	},

	// ------------------------------------------------------------
	// PhotoSets
	// ------------------------------------------------------------
	
	// all first arguments are Flickr.PhotoSet

	getSetPhotos: function(that,callback) {
		var thiz = this;
		var url = 'flickr.photosets.getPhotos';
		var prs = 'photoset_id=' + that.getId();
		var cab = function (res) {
			var doc = getDoc(res);
			if (!doc) return; 
			thiz.callbackPhotos(doc,callback,that.getOwner());
		};
		this.request(url,prs,cab);
	},


	// --------------------------------------------------
	// (semi) private
	// --------------------------------------------------

	getParams: function(method, rest) {
		var params = 'api_key=' + API_KEY + '&method='+ method;
		if (rest) params += '&' + rest;
		return params;
	},

	request: function(method, parameters, callback) {
		var url = '/cgi-bin/get3.pl';
		var params = 'url=' + urlencode(REST + '?' + this.getParams(method,parameters));
		new Ajax.Request (url,
											{   method: 'get', 
													parameters: params, 
													onSuccess: callback
													});
	}

};
var flickr = new Flickr.Service();



Flickr.User = Class.create();
Flickr.User.prototype = {

	initialize: function(name) {
		this.name = name;
	},

	getName: function() {
		return this.name;
	},

	getPhotosForLocation: function(loc,callback) {
		flickr.getPhotosForLocation(loc,callback);
	},
	
	getContacts: function(callback) {
		flickr.getContacts(this,callback);
	},

	getPhotos: function(callback,page) {
		flickr.getPhotos(this,callback,page);
	},

	getPages: function(callback) {
		flickr.getPages(this,callback);
	},

	getSets: function(callback) {
		flickr.getSets(this,callback);
	},

	getInfo: function() {
		var url = "http://flickr.com/people/" + this.getName() + "/";
		//todo
		return getName();
	},

	getPhoto: function(id,callback) {
		var url = "http://flickr.com/photos/" + this.getName() + "/" + id + "/";
		callback(0); //todo
	},

	getPhotoPages: function(callback) {
		callback(0); //todo
	},

	toString: function() {
		return this.name;
	},

	_dummy: function() {}

};

Flickr.PhotoSet = Class.create();
Flickr.PhotoSet.prototype = {
	
	initialize: function(id,title,descr,numPhotos,owner) {
		this.id = id;
		this.title = title;
		this.descr = descr;
		this.numPhotos = numPhotos;
		this.owner = owner;
	},

	getId: function() {
		return this.id;
	},

	getTitle: function() {
		return this.title;
	},

	getDescription: function() {
		return this.descr;
	},

	getNumPhotos: function() {
		return this.numPhotos;
	},

	getOwner: function() {
		return this.owner;
	},

	getPhotos: function(callback) {
		flickr.getSetPhotos(this,callback);
	},

	toString: function() {
		return "id=" + this.getId() + ",title=" + this.getTitle() + ",#=" + this.getNumPhotos();
	}	,

	_dummy: function() {}
};

Flickr.Photo = Class.create();
Flickr.Photo.prototype = {

	initialize: function(id,title,secret,server,owner) {
		this.id = id;
		this.title = title;
		this.secret = secret;
		this.server = server;
		this.owner = owner;
	},

	getURL: function(kind) {
		return imageURL(this.id,this.secret,this.server,kind);
	},

	getInfoXML: function(callback) {
		flickr.getPhotoInfoXML(this,callback);
	},
	
	getId: function() {
		return this.id;
	},
	
	getTitle: function() {
		return this.title;
	},
	
	getOwner: function() {
		return this.owner;
	},

	getHTML: function(api,callback) {
		flickrFormat.getPhotoHTML(api,flickr,this,callback);
	},

	getXML: function(callback) {
		flicker.getPhotoInfoXML(this,callback);
	},
	
	toString: function() {
		return "id=" + this.getId() + ",title=" + this.getTitle();
	},

	_dummy: function() {}
};

Flickr.Page = Class.create();
Flickr.Page.prototype = {

	initialize: function(owner,n) {
		this.owner = owner;
		this.n = n;
	},
	
	getOwner: function() {
		return this.owner;
	},

	getNum: function() {
		return this.n;
	},
	
	toString: function() {
		return this.getNum();
	},

	_dummy: function() {}
};


// --------------------------------------------------
// Reflect
// --------------------------------------------------

Flickr.Reflect = Class.create();
Flickr.Reflect.prototype = {
	
	initialize: function(id,type) {
		this.name = id;
		this.type = type;
		if (this.type == 'people') {
			//
			// turn this into an id
			//
			var thiz = this;
			flickr.getId(id, function(i) {thiz.id = i;});
		} else {
			this.id = id
		}
	},

	getMethods: function(callback) {
		var url = 'flickr.reflection.getMethods';
		var prs = '';
		var thiz = this;
		var cab = function (res) {
			/*
<methods>
	<method>flickr.blogs.getList</method>
	<method>flickr.blogs.postPhoto</method>
	<method>flickr.contacts.getList</method>
	<method>flickr.contacts.getPublicList</method>
</methods>
			*/
			var doc = getDoc(res);
			if (!doc) return; 
			var ss = doc.getElementsByTagName('method');
			var matches = [];
			if (ss) {
				var re = new RegExp('flickr.' + thiz.type + '.');
				for (var i=0; i<ss.length; i++) {
					var s = ss[i];
					var name = s.firstChild.nodeValue;
					if (name.match(re)) {
						var m = new Flickr.ReflectMethod(thiz.id,name,thiz.type);
						matches.push(m);
					}
				}
			}
			callback(matches);
			
		};
		flickr.request(url,prs,cab);		
	},

	toString: function() {
		var s = this.type + '(' + this.name;
		if (this.id) s +=  + ':' + this.id;
		s += ')';
		return s;
	},

	_dummy: function() {}

};

Flickr.ReflectMethod = Class.create();
Flickr.ReflectMethod.prototype = {
	
	initialize: function(id,name,type) {
		this.id = id;
		this.name = name;
		this.type = type;
		var idn;
		if (type == 'people') {
			idn = 'user_id';
		} else if (type = 'photo') {
			idn = 'photo_id';
		} else {
			idn = name + '_id';
		}
		this.idName = idn;
	},

	getXML: function(callback) {
		var cb = function(res) {
			var doc = getDoc(res);
			if (!doc) return; 
			var rsp = doc.firstChild; 
			var xml = rsp.nextSibling;
			callback(xml);
		};
		var params = this.idName + '=' + this.id;
		flickr.request(this.name,params,cb);
	},

	toString: function() {
		return this.name;
	},

	_dummy: function() {}

};

