/* Copyright (c) 1995-2008 Choice Hotels International, Inc. All Rights Reserved. */
if(!RPC){var RPC=$Class.create({_ctor:function(href,callbacks){this.href=href;this.callbacks=callbacks?$Class.clone(callbacks):{};this.efilters=RPC._encode_filters;this.dfilters=RPC._decode_filters},dispose:function(){this.href=null;if(this.callbacks){for(var cb in this.callbacks)this.callbacks[cb]=null;this.callbacks=null}this.efilters=null;this.dfilters=null;if(this.nencode)this.nencode=null},setEncodeFilters:function(filters){this.efilters=filters},setDecodeFilters:function(filters){this.dfilters=filters},setNumberEncoder:function(enc){this.nencode=enc},invoke:function(method,args){var request=new HttpRequest({method:"post",onSuccess:this._onSuccess.bind(this),onFailure:this._onFailure.bind(this)});var enc=new RPCEncoder(this,this.nencode);request.send(this.href+"/"+method,enc.encode($A(arguments,1)));enc.dispose()},getObjectRPCID:function(obj){return ((typeof obj.getRPCID)=="function")?obj.getRPCID(this):null},_onSuccess:function(request){var response=request.responseText;if(response==null)this._onFailure(request);else {var dec=new RPCDecoder(this);var retval=dec.decodeString(response);dec.dispose();if(retval[1]!=null){if(this.callbacks.onStatus200)this.callbacks.onStatus200(retval[1]);if(this.callbacks.onException)this.callbacks.onException(retval[1])}else {if(this.callbacks.onStatus200)this.callbacks.onStatus200(retval[0]);if(this.callbacks.onSuccess)this.callbacks.onSuccess(retval[0])}}},_onFailure:function(request){var cb=this.callbacks["onStatus"+request.status];if(cb)cb();if(this.callbacks.onFailure)this.callbacks.onFailure(request)}});RPC._encode_filters={};RPC._decode_filters={};RPC.setEncodeFilter=function(rpcid,func){RPC._encode_filters[rpcid]=func};RPC.setDecodeFilter=function(rpcid,func){RPC._decode_filters[rpcid]=func};RPC.registerClass=function(cls,rpcid){if(!cls.prototype)cls.prototype={};cls.prototype.getRPCID=function(rpc){return rpcid};RPC._decode_filters[rpcid]=function(obj){return $Class.convert(obj,cls)}};var NumberEncoder=$Class.create({_ctor:function(precision){this.mult=Math.pow(10,precision)},encode:function(num){return (num<0)?Math.ceil(num*this.mult)/this.mult:Math.floor(num*this.mult)/this.mult},getEncodeFunction:function(){return this.encode.bind(this)}});function Decoded(obj,len){this.object=obj;this.length=len};var RPCEncoder=$Class.create({_ctor:function(rpc,nencoder){this.rpc=rpc;this.strlookup={};this.strcount=0;this.nencode=nencoder},dispose:function(){this.rpc=null;this.strlookup=null;this.nencode=null},encode:function(obj){if(obj==null)return "X";switch(typeof obj){case "object":{if(obj instanceof Array){return this.encodeArray(obj)}else {return this.encodeObject(obj)}}case "number":{return (this.nencode?this.nencode(obj):obj.toString())+";"}case "string":{return this.encodeString(obj.toString())}case "boolean":{return obj?"T":"F"}case "undefined":{return "X"}}return ""},encodeString:function(str){var result=new StringBuffer;var key="$"+str;var index=this.strlookup[key];if(!index){index=this.strcount++;this.strlookup[key]=index;result.append("M");result.append(this.escapeString(str));result.append(";")}result.append("s");result.append(index);result.append(";");return result.toString()},encodeArray:function(array){var result=new StringBuffer();result.append("[");result.append(array.length);result.append(";");for(var i=0;i<array.length;i++){result.append(this.encode(array[i]))}return result.toString()},encodeObject:function(obj){var rpcid=this.rpc.getObjectRPCID(obj);var filter=((rpcid!=null)&&this.rpc.efilters)?this.rpc.efilters[rpcid]:null;if(filter){var newobj=filter(obj);if(newobj!==obj)return encodeObject(newobj);obj=newobj;rpcid=this.rpc.getObjectRPCID(obj)}var result=new StringBuffer();result.append("{");result.append(this.encode(rpcid));for(prop in obj){var value=obj[prop];if((typeof value)!="function"){result.append(this.encodeString(prop));result.append(this.encode(obj[prop]))}}result.append(";");return result.toString()},escapeString:function(str){function escapeChar(str,c,r){var index;var result=new StringBuffer();var start=0;while((index=str.indexOf(c,start))>=0){result.append(str.substring(start,index));result.append("\\");result.append(r);if((start=index+1)>=str.length)break}if(start==0)return str;if(start<str.length)result.append(str.substring(start));return result.toString()};str=escapeChar(str,"\\","\\");return escapeChar(str,";","%")}});var RPCDecoder=$Class.create({_ctor:function(rpc){this.rpc=rpc;this.strtable=new Array},dispose:function(){this.rpc=null;this.strtable=null},decodeString:function(str){var decoded=this.decode(str,0);return decoded.object},decode:function(str,start){if(str==null)return null;var tchar=str.charAt(start);if(/[-0-9]/.test(tchar)){var index=str.indexOf(';',start);return new Decoded(Number(str.substring(start,index)),index-start+1)}else switch(tchar){case 'X':;return new Decoded(null,1);case '[':;return this.decodeArray(str,start);case '{':;return this.decodeObject(str,start);case 'S':{var index=str.indexOf(';', ++start);return new Decoded(this.unescapeString(str.substring(start,index)),index-start+2)}case 's':{var index=str.indexOf(';', ++start);return new Decoded(this.strtable[Number(str.substring(start,index))],index-start+2)}case 'M':{var index=str.indexOf(';', ++start);this.strtable.push(this.unescapeString(str.substring(start,index)));var result=this.decode(str,index+1);result.length+=(index-start+2);return result}case 'T':;return new Decoded(true,1);case 'F':;return new Decoded(false,1);default: {throw {name:"ParseError",message:"Unknown encoding"}}}},decodeArray:function(str,start){var index=str.indexOf(';',start+1);var len=str.substring(start+1,index)-0;var result=new Array(len);++index;for(var i=0;i<len;i++){var decoded=this.decode(str,index);result[i]=decoded.object;index+=decoded.length}return new Decoded(result,index-start)},decodeObject:function(str,start){var decoded=this.decode(str,start+1);var rpcid=decoded.object;var index=start+decoded.length+1;var result={};while(str.charAt(index)!=';'){var key=this.decode(str,index);var value=this.decode(str,index+key.length);result[key.object]=value.object;index+=key.length+value.length}var filter=((rpcid!=null)&&this.rpc.dfilters)?this.rpc.dfilters[rpcid]:null;if(filter)result=filter(result);return new Decoded(result,index-start+1)},unescapeString:function(str){var index;var result=new StringBuffer();var start=0;while((index=str.indexOf("\\",start))>=0){result.append(str.substring(start,index));result.append((str.charAt(index+1)=='%')?';':'\\');if((start=index+2)>=str.length)break}if(start==0)return str;if(start<str.length)result.append(str.substring(start));return result.toString()}})}