﻿/*	Script: jsonp.js
		Creates a Json request using a script tag include and handles the callbacks for you.
		
		Dependencies:
		Mootools - <Moo.js>, <Array.js>, <String.js>, <Function.js>, <Utility.js>, <Element.js>, <Common.js>
		
		Author:
		Aaron Newton <aaron [dot] newton [at] cnet [dot] com>
		
		Class: JsonP
		Creates a Json request using a script tag include and handles the callbacks for you.
		
		Arguments:
		url - the url to get the json data
		options - an object with key/value options
		
		Options:
		onComplete - (optional) function to execute when the data returns; it will be passed the data
		callBackKey - (string) the key in the url that the server uses to wrap the Json results. 
				So, for example, if you used "callBackKey: 'callback'" then the server is expecting
				something like http://..../?q=search+term&callback=myFunction
				defaults to "callback". This must be defined correctly.
		queryString - (string, optional) additional query string values to append to the url
		data - (object, optional) additional key/value data to append to the url
		
		Example:
(start code)
new JsonP('http://api.cnet.com/restApi/v1.0/techProductSearch', {
	data: {
		partTag: 'mtvo',
		iod: 'hlPrice',
		iewType: 'json',
		results: '100',
		query: 'ipod'
	},
	onComplete: myFunction.bind(someObject)
}).request();
(end)

		The above example would generate this url:
(start code) http://api.cnet.com/restApi/v1.0/techProductSearch?partTag=mtvo&iod=hlPrice&viewType=json&results=100&query=ipod&callback=JsonP.requestors[0].handleResults&
(end)

		It would embed this script tag (in the head of the document) and, when it loaded, execute the "myFunction"
		callback defined.
	*/
var JsonP = new Class({
	options: {
		onComplete: Class.empty,
		callBackKey: "callback",
		queryString: "",
		data: {}
	},
	initialize: function(url, options){
		this.setOptions(options);
		this.url = this.makeUrl(url).url;
		this.fired = false;
		this.scripts = [];
	},
/*	Property: request
		Executes the Json request.
	*/
	request: function(url){
	
	    if (url)
	    {
		    var u = this.makeUrl(url);
		    if(url) this.url = u.url;
		}
		else
		    var u = this.url;
		
		//dbug.log('retrieving by json script method: %s', this.url);
		var dl = (window.ie)?50:0; //for some reason, IE needs a moment here...
		(function(){
		
			var script = new Asset.javascript(this.url, {id: 'jsonp_'+u.index});
			this.fired = true;
			this.addEvent('onComplete', function(){
				try {script.remove();}catch(e){}
			}.bind(this));
		}.bind(this)).delay(dl);
		
	},
	makeUrl: function(url){
		var index = (JsonP.requestors.contains(this))?
								JsonP.requestors.indexOf(this):
								JsonP.requestors.push(this) - 1;
		var separator = (url.test('\\?'))?'&':'?';
		var jurl = url + separator + this.options.callBackKey + "=JsonP.requestors[" +
				index+"].handleResults";
		if(this.options.queryString) jurl += "&"+this.options.queryString;
		return {url: jurl, index: index};
	},
	handleResults: function(data){
	    
		this.fireEvent('onComplete', data);
	}
});
JsonP.requestors = [];
JsonP.implement(new Options);
JsonP.implement(new Events);



