if(!Impel){var Impel=new Class({})}Impel.inTouch=new Class({Implements:[Options,Events],options:{name:"Impel_inTouch",displayName:"Impel inTouch",maxSize:4096,baseURL:null,versionsFile:"versions.json.php",tableFileSuffix:".json.php"},version:0.7,versions:$H({}),loaded:false,initialize:function(a,b){this.setOptions(a);this.addEvents(b);this.loadVersions(function(){this.loaded=true;this.ready()}.bind(this))},ready:function(){this.fireEvent("ready")},synced:function(){this.fireEvent("synced")},syncFailed:function(a){this.fireEvent("syncFailed",a)},syncing:function(){this.fireEvent("syncing")},updating:function(a){this.fireEvent("updating",a)},updated:function(c,a,b){this.fireEvent("updated",[c,a,b])},updateFailed:function(c,b,a){this.fireEvent("updateFailed",[c,b,a])},created:function(a){this.fireEvent("created",a)},aborted:function(a){this.fireEvent("abort",a)},createFailed:function(b,a){this.fireEvent("createFailed",[b,a])},loadVersions:function(d){try{if(!window.openDatabase){throw ("HTML 5 SQL database not supported")}else{this.db=openDatabase(this.options.name,"1.0",this.options.displayName,this.options.maxSize)}}catch(f){if(f==2){throw ("Encountered an error while opening the database: invalid database version")}else{throw ("Encountered an error while opening the database: unknown error "+f+".")}}var c,a,h,g,b;c=this;a=function(j,e){for(b=0;b<e.rows.length;b++){g=e.rows.item(b);c.versions.set(g.t,g.v)}d()};h=function(j,e){j.executeSql("SELECT * FROM table_versions;",[],a,function(k){throw ("Unable to retrieve list of current table versions: "+k.message)})};this.db.transaction(function(e){e.executeSql("CREATE TABLE IF NOT EXISTS table_versions('t' TEXT NOT NULL PRIMARY KEY, 'v' INT NOT NULL);",[],h,function(j,k){throw ("Unable to create table to cache version data: "+k.message)})}.bind(this),function(j,k){throw ("Unable to create table to cache version data: "+k.message)})},getVersion:function(a){return this.versions.get(a)},setVersion:function(b,a){this.versions.set(b,a);this.db.transaction(function(c){c.executeSql("INSERT INTO table_versions ('t', 'v') VALUES (?,?);",[b,a],null,function(e,d){e.executeSql("UPDATE table_versions SET v=? WHERE t=?",[a,b],null,function(f){throw ("Unable to save record: "+b+" = "+a+"\n"+f.message)})})})},checkForUpdates:function(a){if(this.options.baseURL==null){throw"baseURL attribute must be set when instantiating an Impel.inTouch object"}if(a==null){try{new Impel.JsonP(this.options.baseURL+this.options.versionsFile,{callback:function(e){this.checkForUpdates(e)}.bind(this),onFailure:function(){this.aborted(1)}.bind(this)}).request()}catch(f){throw"Impel.inTouch requires the Impel.JsonP Class."}}else{var g,d,c,b;g=null;d=[];c=null;a.each(function(e){if(e.table!=null){g=this.getVersion(e.table);if(e.version!=null){if(g==null||g<e.version){d.push(e.table)}}else{if(e.versions!=null){if(g==null||g<e.versions[e.versions.length-1]){c=[];for(b=e.versions.indexOf(g)+1;b<e.versions.length;b++){c.push(e.versions[b])}d.push({table:e.table,versions:c});c=null}}}g=null}}.bind(this));this.sync(d)}},sync:function(f){if(!this.loaded){throw"Implen.inTouch.sync() cannot be called before Impel.inTouch is finished initializing. Wait for the 'ready' event."}if(f==null){this.checkForUpdates()}else{if(f.length==0){this.synced();return}var a=[];var g=[];$each(f,function(h){if(typeof h=="string"){g.push(h)}else{h.versions&&h.table&&$each(h.versions,function(l,j){g.push(h.table)})}});this.addEvent("updateFailed",function(h){g.splice(g.indexOf(h),1);a.push(h);if(g.length==0){this.syncFailed(a)}});this.addEvent("updated",function(h){g.splice(g.indexOf(h),1);if(g.length==0){if(a.length>0){this.syncFailed(a)}else{this.synced()}}d(h)});var c,e,d,b;e=this;c=[];this.addEvent("updating",function(h){b=h});d=function(h){if(h&&h!=b){return}var j=c.shift();if(!!j==false){return}e.updating(j.table);var k=e.options.baseURL+j.table;if(j.version){k+="_"+j.version}k+=e.options.tableFileSuffix;new Impel.JsonP(k,{callback:function(l){e.importData(l)}}).request()};f.each(function(h){if(typeof h=="string"){c.push({table:h})}else{if(typeof h=="object"&&$type(h.versions)=="array"){for(i=0;i<h.versions.length;i++){c.push({table:h.table,version:h.versions[i]})}}}}.bind(this));d()}},importData:function(c){if(c.table==null||c.version==null){return}var d=this.getVersion(c.table);d=d||0;if(d!=null&&d>=c.version){this.updated(c.table,d,c.version);return}var a=function(f){return"SQL Error: "+f.message+"("+f.code+")"};var b="";if(c.create!=null||c.data!=null){this.db.transaction(function(f){if(c["pre-create"]!=null&&c["pre-create"].$family.name=="array"){c["pre-create"].each(function(g){f.executeSql(g,[],function(){},function(h,j){throw ("Statement failed: "+g+"\n"+a(j));return true})})}if(c.create!=null){f.executeSql(c.create,[],function(){this.created(c.table)}.bind(this),function(g,h){this.createFailed(c.table,a(h));throw ("Statement failed: "+c.create+"\n"+a(h));return true}.bind(this))}if(c.extra!=null&&c.extra.$family.name=="array"){c.extra.each(function(g){f.executeSql(g,[],null,function(h,j){throw ("Statement failed: "+g+"\n"+a(j));return true})})}if(c.data!=null&&c.data.$family.name=="array"){for(var e=0;e<c.data.length;e++){b=c.data[e];if(typeof(b)=="string"){f.executeSql(b,[],null,function(g,h){throw ("Failed to load data: "+b+"\n"+a(h));return true})}}}}.bind(this),function(){this.updateFailed(c.table,d,c.version)}.bind(this),function(){this.setVersion(c.table,c.version);this.updated(c.table,d,c.version)}.bind(this))}}});Impel.JsonP=new Class({Implements:[Options,Events],options:{callBackKey:"callback",queryString:"",data:{},timeout:5000,callback:function(){throw ("Error: Impel.JsonP objects must have a callback function defined as part of their instantiation options.")}},script:null,initialize:function(b,a){this.setOptions(a);this.url=this.makeUrl(b)},isComplete:function(){try{this.script.dispose()}catch(a){}},request:function(c){var a=Math.floor(Math.random()*101);c=this.makeUrl(c);my=this;Impel.JsonP.callback=function(d){(function(){my.options.callback(d)}).delay(50);my.isComplete()};var b=(Browser.Engine.trident)?50:0;(function(){this.script=new Element("script",{src:c,type:"text/javascript",id:"jsonp_"+a});this.script.inject(document.head);(function(){if(this.script.getParent()){this.fireEvent("onFailure");this.script.dispose()}}).delay(this.options.timeout,this)}.bind(this)).delay(b);return this},makeUrl:function(a){var b;if(a){var c=(a.test("\\?"))?"&":"?";b=a+c+this.options.callBackKey+"=Impel.JsonP.callback";if(this.options.queryString){b+="&"+this.options.queryString}b+="&"+Hash.toQueryString(this.options.data)}else{b=this.url}return b}});
