/*
 * registrar-jquery.js
 * Author: Gabe Berke-Williams, 2008
 * Version: 2.7
 * Requires jQuery 1.4.0 or higher for its new recursive $.param.
 * If you really hate jQuery 1.4.0+, you can implement your own $.param that
 * does the same thing and use a lower version of jQuery. This script has only
 * been tested in 1.3.2+.
 *
 * A script to display Brandeis classes in a weekly calendar format. It grabs
 * the data directly from Brandeis.
 */
function registrar(){this.Basedir="/~gbw";this.fullPathToCallback="http://www.people.brandeis.edu/~gbw/schedule_process_ajax.php?full&";this.canSubmit=true;this.timedOutRegex=/Operation timed out after .+ milliseconds with .+ bytes received/;this.noLocation="No classroom provided.";this.queryArr=[];this.codenums=[];this.classesByCodenum={};this.classesToParse=[];this.parsedClasses=[];this.cachedClasses={};this.invalidClasses=[];this.notFoundClasses=[];this.prevClasses=[];this.prevLevel="";this.prevTerm="";this.courseAbbrevMap={AAAS:100,AMST:200,ANTH:300,ARBC:400,BCHM:500,BIOC:750,BIO:700,BIOL:700,BISC:700,BIPH:600,BUS:900,CHEM:1000,CHIN:1100,CLAS:1200,CHIS:1250,COML:1300,COEX:1225,COSI:1400,CP:1450,EAS:1500,ECON:1600,ECS:2000,ED:1700,ENG:1800,ENVS:1900,ESL:1850,FA:2300,FILM:2100,FIN:2200,FYS:8000,FREN:2400,FRENCH:2400,GER:2500,GS:2535,HBRW:2800,HISP:6600,HIST:3000,HOID:3100,HRNS:3200,HS:2900,HSSP:2700,IIM:3300,IGS:3400,IMES:3900,INET:3800,ITAL:4000,JAPN:4100,JOUR:4200,LING:4600,LALS:4300,LGLS:4400,MATH:4700,MEVL:4800,MUS:5000,NEJS:5100,NEUR:5200,NBIO:5200,NPSY:5200,PAX:5300,PE:5500,PHIL:5400,PHYS:5600,POL:5700,PSYC:5900,QBIO:5950,REES:6200,REL:6000,RUS:6300,SAS:6550,SPAN:6625,SJSP:6400,SOC:6500,THA:6700,USEM:7025,UWS:7050,COMP:7050,WMGS:6900,YDSH:7000};this.urlToShort={};this.shortUrlLoadingText="Loading shortened URL...";this.$shortUrlElem=$("#link");this.doTracking=true}registrar.prototype.trackEvent=function(){if(this.doTracking===false||pageTracker===undefined){return false}if(this.parsedClasses.length>0){pageTracker._trackEvent("Registrar Schedule","Success",this.parsedClasses.join(", "),this.parsedClasses.length)}if(this.notFoundClasses.length>0){pageTracker._trackEvent("Registrar Schedule","Not Found",this.notFoundClasses.join(", "),this.notFoundClasses.length)}};registrar.prototype.set_status=function(a){$("#status").text("Status: "+a)};registrar.prototype.set_error=function(a){$("#status").text("Status: "+a).wrap("<b></b>")};registrar.prototype.show_bad=function(){var b="",c,a;if(this.invalidClasses.length===0&&this.notFoundClasses.length===0){this.hide_bad()}else{if(this.invalidClasses.length>0){c='"'+this.invalidClasses.join('", "')+'"';if(this.invalidClasses.length==1){b+="<p>Invalid class: "+c+"</p>"}else{b+="<p>Invalid classes: "+c+"</p>"}}if(this.notFoundClasses.length>0){a='"'+this.notFoundClasses.join('", "')+'"';if(this.notFoundClasses.length==1){b+="<p>The following class was not found: "+a+"</p>"}else{b+="<p>The following classes were not found: "+a+"</p>"}}$("#bad").html(b).show()}};registrar.prototype.hide_bad=function(){$("#bad").hide().empty()};registrar.prototype.reset_vars=function(){this.codenums=[];this.queryArr=[];this.classesByCodenum={};this.classesToParse=[];this.parsedClasses=[];this.notFoundClasses=[];this.invalidClasses=[]};registrar.prototype.check_and_submit=function(){if(this.classesToParse.length!=this.parsedClasses.length){return false}if(this.classesToParse.sort().join()===this.parsedClasses.sort().join()){this.submit_form("formID")}};registrar.prototype.insert_page=function(i,c,d,a){var h=this,j=d.replace("/","_")+"_"+c+"_"+a,m=$("#"+j),f=this.codenums.indexOf(c),b=this.classesByCodenum[c],g=m.length!==0,k=(g&&!m.text().match(this.timedOutRegex)),e,l;if(g&&k){this.set_status("Already fetched page "+(f+1)+".");this.parse_page(j,b);this.check_and_submit()}else{this.set_status("Getting page "+(f+1)+" of "+this.codenums.length+" (this may take a sec)...");if(!k){m.remove()}e=encodeURIComponent("http://www.brandeis.edu/registrar/schedule/classes/"+d+"/"+c+"/"+a);l=this.Basedir+"/proxy?url="+e;$.ajax({url:l,type:"GET",success:function(n,o){h.set_status("Loaded "+(f+1)+" of "+h.codenums.length+" pages.");$("<div/>").attr("id",j).hide().html(n).appendTo("#"+i);h.parse_page(j,b);h.check_and_submit()},error:function(p,n,o){h.set_error("Error: "+p.status+": "+p.statusText)}})}};registrar.prototype.parse_page=function(o,t){this.set_status("Parsing page for "+t.join(", "));var g=this,k=window.setTimeout(function(){alert("Parsing the page seems to be taking a long time. Try reloading.")},500),l,z=this.prevTerm+"_"+this.prevLevel,n,d,c,q,a,v,y,u,p,m,b=false,s,j,x,r,h=null,i,f,e,w=[];if(this.cachedClasses[z]!==undefined){for(l=0;l<t.length;l++){n=this.cachedClasses[z][t[l]];if(n!==undefined){this.parsedClasses.push(t[l]);for(d=0;d<n.length;d++){this.queryArr.push(n[d])}t.splice(l,1)}}if(t.length===0){window.clearTimeout(k);return true}}$("#"+o+" #classes-list tr[class]").each(function(){c=$(this);q=c.find("a:first").text();if(t.indexOf(q)===-1||g.parsedClasses.indexOf(q)!==-1){return true}a=c.find("td");v=q+" ("+$(a[2]).find("strong").text()+")";y=$(a[5]).text().replace(",",", ");u=$(a[3]).html().split(/<hr>/i);for(p=0;p<u.length;p++){h=null;i={};m=u[p];b=m.match(/<strong>(.+):<\/strong><br>/);if(b){m=m.replace(b[0],"");v=v+" ("+b[1]+")"}s=m.split("<br>");r=s[0].match(/^Block&nbsp;(.+)/);if(r){h=r[1];if(s.length==3){x=s[2].replace(/([a-z])([0-9])/,"$1 $2")}else{x=g.noLocation}}else{j=s[0].split(" ");if(s.length==2){x=s[1].replace(/([a-z])([0-9])/,"$1 $2")}else{x=g.noLocation}e=j.shift();f=j.join(" ")}i={"class":v,teacher:y,location:x};if(h===null){i.days=e;i.time=f}else{i.block=h}w.push(i);g.queryArr.push(i)}if(!(z in g.cachedClasses)){g.cachedClasses[z]={}}g.cachedClasses[z][q]=w;g.parsedClasses.push(q)});$.each(t,function(B,A){if(g.parsedClasses.indexOf(A)===-1){g.notFoundClasses.push(A);g.classesToParse.splice(g.classesToParse.indexOf(A),1)}});window.clearTimeout(k);this.set_status("Done parsing page for "+t.join(" "));return true};registrar.prototype.submit_form=function(d){var b=this,a=$.param({classes:this.queryArr}),c,e;this.set_status("Preparing data...");c=this.fullPathToCallback+a;e=c+"&setColor=off";this.showShortPermalinks(c,e);this.set_status("Building schedule...");$.ajax({url:b.Basedir+"/schedule_process_ajax.php",data:a,method:"GET",success:function(f,g){b.set_status("Schedule is displayed. :)");$("#schedTable").html(f)},error:function(h,f,g){b.set_error("There was a problem with the request (code: "+h.status+"; type: "+f+"). Try again.")},complete:function(g,f){b.show_bad();b.trackEvent();b.reset_vars();b.canSubmit=true;if(f!=="error"){$("#schedTable, #link").show()}}})};registrar.prototype.submit=function(){if(this.canSubmit===false){return false}else{this.canSubmit=false}$("#schedTable, #link").hide();var i=this,e=$("#formID").serializeArray(),b=e.shift().value,a=e.shift().value,h,c,l,m,f,n,k,g,d;c=$.map(e,function(o,j){h=$.trim(o.value).replace(/\s+/g," ");return((h==="")?null:h)});if(c.length===0){this.set_status("You might want to enter some classes. :)");this.prevClasses=[];this.hide_bad();this.canSubmit=true;return true}c=$.map(c,function(o,j){if(c.indexOf(o)<j){return null}l=o.split(" ");if(l.length<2){i.invalidClasses.push(o);i.show_bad();return null}m=l.shift().toUpperCase();f=l.shift().toUpperCase();n=l.join(" ").toLowerCase();if(!(m in i.courseAbbrevMap)){i.invalidClasses.push([m,f,n].join(" "));return null}if(n===""){n="1"}else{if(/^(sec\.?\s*)?[0-9]$/.test(n)){n=n.replace(/sec\.?\w*/,"")}else{n="1"}}k=[m,f,n].join(" ");g=i.courseAbbrevMap[m];if(i.codenums.indexOf(g)===-1){i.codenums.push(g);i.classesByCodenum[g]=[]}if(i.classesToParse.indexOf(k)===-1){i.classesToParse.push(k);i.classesByCodenum[g].push(k)}return k});if(this.prevClasses.join()===c.sort().join()&&this.prevLevel===a&&this.prevTerm===b){if(this.invalidClasses.length>0){this.show_bad()}else{this.hide_bad()}this.invalidClasses=[];this.set_status("No real change in classes. Same schedule is displayed. :)");this.canSubmit=true;window.setTimeout(function(){$("#schedTable, #link").show()},1);return false}if(this.invalidClasses.length>0){this.show_bad();if(this.classesToParse.length===0){this.reset_vars();this.canSubmit=true;return false}}this.prevClasses=c.sort();this.prevLevel=a;this.prevTerm=b;for(d=0;d<this.codenums.length;d++){this.insert_page("hook",this.codenums[d],b,a)}};registrar.prototype.showShortPermalinks=function(f,g){var d,b,a=[],e=this,c;if(this.urlToShort[f]!==undefined){d=this.urlToShort[f];b=this.urlToShort[g];$("#link").html('Permanent/printable link to this schedule: <a href="'+d+'">'+d+'</a> (with color) or <a href="'+b+'">'+b+"</a> (no color).")}else{if(f in this.urlToShort&&this.urlToShort[f]===undefined){delete this.urlToShort[f];delete this.urlToShort[g]}this.$shortUrlElem.text(this.shortUrlLoadingText);$.getJSON(this.Basedir+"/bitly.php?url[]="+encodeURIComponent(f)+"&url[]="+encodeURIComponent(g),function(i,j){if(i.errorCode){$("#link").html('Permanent/printable link to this schedule: <a href="'+f+'">permalink</a> (with color) or <a href="'+g+'">permalink</a> (no color).')}else{for(var h in i.results){c=i.results[h].shortUrl;if(c===undefined){c=h}e.urlToShort[h]=c;a.push(c)}d=a[0];b=a[1];$("#link").html('Permanent/printable link to this schedule: <a href="'+d+'">'+d+'</a> (with color) or <a href="'+b+'">'+b+"</a> (no color).")}})}};
