var ApiClient = new Class({
	Extends: Request,
	
	options: {
		// Default option values for the base class
		'headers': {'Accept':'application/json'},
		'method': 'post',
		'evalScripts': true,
		
		// Igloo specific options below:
		'queryparams': null,														// get added to the URL (can be used in POST and GET requests)
		'postdata': null,															// passed to the Request object later as the 'data' option
		'sessionKey': Cookie.read('iglooauth').replace("\{","").replace("\}",""),	// used in creating the signature
		'secretKey': Cookie.read('igloojs').replace("\{","").replace("\}",""),		// used in creating the signature
		'sendimmediately': true,													// immediately send the request once the ApiClient object is created, no more .send(), thanks Ian!
		'debug': false,																// this can be set to true in development to help with debugging
		
		// These api values are combined to create the Request url
		'apibaseurl': document.location.protocol + '//' + document.location.host,
		'apipath': '/.api/api.svc/',
		'apimethod': null
	},
	
	initialize: function(options){
		this.parent(options);
		
		this.apiurl = this.options.apibaseurl;
		this.apiurl += this.options.apipath;
		this.apiurl += this.options.apimethod;
		
		// this is the querystring in the apiurl. This is one ingredient in the crypted sig
		var apiquerystring = new Hash({'apisecure':'on'});
		if( this.options.queryparams ){
			apiquerystring.combine(this.options.queryparams);
		}
		
		this.apiurl += "?" + Hash.toQueryString(apiquerystring);
		
		// OK now we have a very subtle problem.
		// The API expects queryparams containing a "tilde" ~ to be encoded as %7e
		// however our handydandy encodeURIComponent() function does not encode tildes.
		// thus we have to do it to each item in the queryparams before it's assembled into the querystring.
		// we can do this with a simple text replacement because delimiiters are known not to include tildes.
		// be wary that there may be other cases besides tilde
		this.apiurl = this.apiurl.replace('~','%7e');
		
		
		if( this.options.sendimmediately ){
			this.send();
		}
	},
	
	send: function(query_string){
		// the user can set 'sendimmediately':false and call the send method passing in a query string like "save=username&name=John"
		if( typeof(query_string) === 'string' ){
			this.setOptions({
				postdata: query_string.parseQueryString()
			});
		}
		
		/* interesting little glitch: if the method is POST and postdata is empty, firefox doesn't send a content-length header. This causes problems deeper in the system. So here we will add some dummy data */
		if(this.options.method == 'post'){
			if(this.options.postdata == null){
				this.options.postdata = {
					'post':'empty'
				}
			}
		}
		
		if(this.options.debug){
			alert('### debug mode is on\n\n' + 'apiurl = '+this.apiurl+'\n\npostdata = '+Hash.toQueryString(this.options.postdata));
		}
		
		// sign the request just before it's sent
		var sig = this.signRequest();
		
		// start with the same URL we used to generate the signature (baseurl, path, method, queryparams, apisecure)
		var requesturl = this.apiurl;
		
		// add a qmark or an amp
		requesturl += (requesturl.indexOf('?') == -1)?'?':'&';
		
		// add the other ingredients and stir
		requesturl += 'sessionKey='+this.options.sessionKey;
		requesturl += '&nonce='+this.nonce;
		requesturl += '&signature='+encodeURIComponent(sig);
		
		if(this.options.debug){
			alert('### debug mode is on\n\n' + 'requesturl = '+requesturl+'\n\npostdata = '+Hash.toQueryString(this.options.postdata));
		}
		
		// update the options with the final information needed by Request
		this.setOptions({
			'url': requesturl,
			'data': this.options.postdata
		});
		
		this.parent();
	},
	
	signRequest: function(){
		// right at the moment of sending, generate a new nonce.
		// it mustn't be defined in the initialize method, because then it uses the same nonce every time
		// this way the same api object can be used more than once for repeated requests
		var nonce = this.uniquenonce();
		
		// create the string, as described here -- http://developers.iglooteams.com/wiki/api_signature
		// this string has the format:
		// method : uri sessionKey nonce (but without the spaces)
		var str = this.options.method.toUpperCase();
		str += ":";
		str += this.apiurl;
		str += this.options.sessionKey;
		str += nonce;
		
		// if posting data, append the postdata to the string
		str += this.options.postdata?Hash.toQueryString(this.options.postdata):'';
		
		// encode the strings into arrays of bytes using a UTF encoder
		var utf8str = Utils.Utf8.encode(str);
		var utf8secret = Utils.Utf8.encode(this.options.secretKey);
		
		if(this.options.debug){alert('secret\n\n'+utf8secret);}
		
		// Generate the signature with the HMAC-SHA1 algorithm using the UTF8 encoded string and the API secret key
		var cryp = new Crypt.Sha1.Hmac({
			'b64pad': '=',
			'output': 'b64'
		});
		var sig = cryp.encrypt(utf8secret,utf8str);
		
		if(this.options.debug){alert('utf8str\n\n'+utf8str);}
		
		if(this.options.debug){alert('sig\n\n'+sig);}
		
		// hooray! we have the signature. Now let's build the AJAX Request URL
		return sig;
	},
	
	uniquenonce: function(){
		this.nonce = this.nonce || 1;
		this.Date = this.Date || new Date();
		
		var seed = this.Date.getSeconds() + this.nonce;
		this.nonce = Math.floor( Math.random(seed)*1000000000 ) + 1;
		
		return this.nonce;
	}
});
