]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/web/opac/common/js/opac_utils.js
gave org selecter builder the option to display shortname instead of name, good for...
[Evergreen.git] / Open-ILS / web / opac / common / js / opac_utils.js
1 /* - Request ------------------------------------------------------------- */
2
3 /* define it again here for pages that don't load RemoteRequest */
4 function isXUL() { try { if(IAMXUL) return true;}catch(e){return false;}; }
5
6
7 var cookieManager = new HTTP.Cookies();
8
9 var __ilsEvent; /* the last event the occurred */
10
11 var DEBUGSLIM;
12 function Request(type) {
13
14         var s = type.split(":");
15         if(s[2] == "1" && isXUL()) s[1] += ".staff";
16         this.request = new RemoteRequest(s[0], s[1]);
17         var p = [];
18
19         if(isXUL()) {
20                 if(!location.href.match(/^https:/))
21                         this.request.setSecure(false);
22
23         } else {
24
25                 if( G.user && G.user.session ) {
26                         /* if the user is logged in, all activity resets the timeout 
27                                 This is not entirely accurate in the sense that not all 
28                                 requests will reset the server timeout - this should
29                                 get close enough, however.
30                         */
31                         var at = getAuthtime();
32                         if(at) new AuthTimer(at).run(); 
33                 }
34         }
35
36         for( var x = 1; x!= arguments.length; x++ ) {
37                 p.push(arguments[x]);
38                 this.request.addParam(arguments[x]);
39         }
40
41         if( getDebug() ) {
42                 var str = "";
43                 for( var i = 0; i != p.length; i++ ) {
44                         if( i > 0 ) str += ", "
45                         str += js2JSON(p[i]);
46                 }
47                 _debug('request ' + s[0] + ' ' + s[1] + ' ' + str );
48
49         } else if( DEBUGSLIM ) {
50                 _debug('request ' + s[1]);
51         }
52 }
53
54 Request.prototype.callback = function(cal) {this.request.setCompleteCallback(cal);}
55 Request.prototype.send          = function(block){this.request.send(block);}
56 Request.prototype.result        = function(){return this.request.getResultObject();}
57
58 function showCanvas() {
59         for( var x in G.ui.altcanvas ) {
60                 hideMe(G.ui.altcanvas[x]);
61         }
62         hideMe(G.ui.common.loading);
63         unHideMe(G.ui.common.canvas_main);
64         try{G.ui.searchbar.text.focus();}catch(e){}
65 }
66
67 function swapCanvas(newNode) {
68         for( var x in G.ui.altcanvas ) 
69                 hideMe(G.ui.altcanvas[x]);
70
71         hideMe(G.ui.common.loading);
72         hideMe(G.ui.common.canvas_main);
73         unHideMe(newNode);
74 }
75
76 /* finds the name of the current page */
77 var currentPage = null;
78 function findCurrentPage() {
79         if(currentPage) return currentPage;
80
81         var pages = [];
82         for( var p in config.page ) pages.push(config.page[p]);
83         pages = pages.sort( function(a,b){ return - (a.length - b.length); } );
84
85         var path = location.pathname;
86         if(!path.match(/.*\.xml$/))
87                 path += "index.xml"; /* in case they go to  / */
88
89         var page = null;
90         for( var p in pages ) {
91                 if( path.indexOf(pages[p]) != -1)
92                         page = pages[p];
93         }
94
95         for( var p in config.page ) {
96                 if(config.page[p] == page) {
97                         currentPage = p;
98                         return p;
99                 }
100         }
101         return null;
102 }
103
104
105 /* sets all of the params values  ----------------------------- */
106 function initParams() {
107         var cgi = new CGI();    
108
109         /* handle the location var */
110         var org;
111         var loc = cgi.param(PARAM_LOCATION);
112         var lasso = cgi.param(PARAM_LASSO);
113
114     if ( lasso ) {
115                 lasso = findOrgLasso( lasso );
116                 LASSO = lasso ? lasso.id() : null;
117         }
118
119     if (loc) {
120                 org = findOrgUnit(loc);
121                 LOCATION = org ? org.id() : null;
122
123                 if ( !LOCATION ){
124                         org = findOrgUnit(loc);
125                         LOCATION = org ? org.id() : null;
126                 }
127     }
128
129         org = null;
130         loc = cgi.param(PARAM_ORIGLOC);
131         if( loc ) {
132                 org = findOrgUnit(loc);
133                 if(!org) org = findOrgUnitSN(loc);
134         }
135         ORIGLOC = (org) ? org.id() : null;
136
137
138         DEPTH = parseInt(cgi.param(PARAM_DEPTH));
139         if(isNaN(DEPTH)) DEPTH = null;
140
141
142         TERM            = cgi.param(PARAM_TERM);
143         STYPE           = cgi.param(PARAM_STYPE);
144         FORM            = cgi.param(PARAM_FORM);
145         //DEPTH         = parseInt(cgi.param(PARAM_DEPTH));
146         OFFSET  = parseInt(cgi.param(PARAM_OFFSET));
147         COUNT           = parseInt(cgi.param(PARAM_COUNT));
148         HITCOUNT        = parseInt(cgi.param(PARAM_HITCOUNT));
149         MRID            = parseInt(cgi.param(PARAM_MRID));
150         RID             = parseInt(cgi.param(PARAM_RID));
151         AUTHTIME        = parseInt(cgi.param(PARAM_AUTHTIME));
152         ADVTERM = cgi.param(PARAM_ADVTERM);
153         ADVTYPE = cgi.param(PARAM_ADVTYPE);
154         RTYPE           = cgi.param(PARAM_RTYPE);
155         SORT            = cgi.param(PARAM_SORT);
156         SORT_DIR        = cgi.param(PARAM_SORT_DIR);
157         DEBUG           = cgi.param(PARAM_DEBUG);
158         CALLNUM = cgi.param(PARAM_CN);
159         LITFORM = cgi.param(PARAM_LITFORM);
160         ITEMFORM        = cgi.param(PARAM_ITEMFORM);
161         ITEMTYPE        = cgi.param(PARAM_ITEMTYPE);
162         BIBLEVEL        = cgi.param(PARAM_BIBLEVEL);
163         AUDIENCE        = cgi.param(PARAM_AUDIENCE);
164         SEARCHES = cgi.param(PARAM_SEARCHES);
165         LANGUAGE        = cgi.param(PARAM_LANGUAGE);
166         TFORM           = cgi.param(PARAM_TFORM);
167         RDEPTH  = cgi.param(PARAM_RDEPTH);
168     AVAIL   = cgi.param(PARAM_AVAIL);
169     COPYLOCS   = cgi.param(PARAM_COPYLOCS);
170     
171
172         /* set up some sane defaults */
173         //if(isNaN(DEPTH))      DEPTH           = 0;
174         if(isNaN(RDEPTH))       RDEPTH  = 0;
175         if(isNaN(OFFSET))       OFFSET  = 0;
176         if(isNaN(COUNT))        COUNT           = 10;
177         if(isNaN(HITCOUNT))     HITCOUNT        = 0;
178         if(isNaN(MRID))         MRID            = 0;
179         if(isNaN(RID))          RID             = 0;
180         if(isNaN(ORIGLOC))      ORIGLOC = 0; /* so we know it hasn't been set */
181         if(isNaN(AUTHTIME))     AUTHTIME        = 0;
182         if(ADVTERM==null)       ADVTERM = "";
183     if(isNaN(AVAIL))    AVAIL = 0;
184 }
185
186 function clearSearchParams() {
187         TERM        = null;
188         STYPE       = null;
189         FORM        = null;
190         OFFSET      = 0;
191         HITCOUNT    = 0;  
192         ADVTERM     = null;
193         ADVTYPE     = null;
194         MRID        = null;
195         RID         = null;
196         RTYPE       = null;
197         SORT        = null;
198         SORT_DIR    = null;
199         RLIST       = null;
200         CALLNUM     = null;
201         LITFORM     = null;
202         ITEMFORM    = null;
203         ITEMTYPE    = null;
204         BIBLEVEL    = null;
205         AUDIENCE    = null;
206         SEARCHES    = null;
207         LANGUAGE    = null;
208         RDEPTH      = null;
209     AVAIL       = null;
210     COPYLOCS    = null;
211 }
212
213
214 function initCookies() {
215         FONTSIZE = "regular";
216         var font = cookieManager.read(COOKIE_FONT);
217         scaleFonts(font);
218         if(font) FONTSIZE = font;
219         SKIN = cookieManager.read(COOKIE_SKIN);
220     if(findCurrentPage() == HOME)
221         cookieManager.remove(COOKIE_SEARCH);
222         
223
224 }
225
226 /* URL param accessors */
227 function getTerm(){return TERM;}
228 function getStype(){return STYPE;}
229 function getLocation(){return LOCATION;}
230 function getLasso(){return LASSO;}
231 function getDepth(){return DEPTH;}
232 function getForm(){return FORM;}
233 function getTform(){return TFORM;}
234 function getOffset(){return OFFSET;}
235 function getDisplayCount(){return COUNT;}
236 function getHitCount(){return HITCOUNT;}
237 function getMrid(){return MRID;};
238 function getRid(){return RID;};
239 function getOrigLocation(){return ORIGLOC;}
240 function getAuthtime() { return AUTHTIME; }
241 function getSearchBarExtras(){return SBEXTRAS;}
242 function getFontSize(){return FONTSIZE;};
243 function getSkin(){return SKIN;};
244 function getAdvTerm(){return ADVTERM;}
245 function getAdvType(){return ADVTYPE;}
246 function getRtype(){return RTYPE;}
247 function getSort(){return SORT;}
248 function getSortDir(){return SORT_DIR;}
249 function getDebug(){return DEBUG;}
250 function getCallnumber() { return CALLNUM; }
251 function getLitForm() { return LITFORM; }
252 function getItemForm() { return ITEMFORM; }
253 function getItemType() { return ITEMTYPE; }
254 function getBibLevel() { return BIBLEVEL; }
255 function getAudience() { return AUDIENCE; }
256 function getSearches() { return SEARCHES; }
257 function getLanguage() { return LANGUAGE; }
258 function getRdepth() { return RDEPTH; }
259 function getAvail() { return AVAIL; }
260 function getCopyLocs() { return COPYLOCS; }
261
262
263 function findBasePath() {
264         var path = location.pathname;
265         if(!path.match(/.*\.xml$/)) path += "index.xml"; 
266         var idx = path.indexOf(config.page[findCurrentPage()]);
267         return path.substring(0, idx);
268 }
269
270 function findBaseURL(ssl) {
271         var path = findBasePath();
272         var proto = (ssl) ? "https:" : "http:";
273
274         /* strip port numbers.  This is necessary for browsers that
275         send an explicit  <host>:80, 443 - explicit ports
276         break links that need to change ports (e.g. http -> https) */
277         var h = location.host.replace(/:.*/,''); 
278
279         return proto + "//" + h + path;
280 }
281
282 /*
283 function buildISBNSrc(isbn) {
284         return "http://" + location.host + "/jackets/" + isbn;
285 }
286 */
287
288 function buildImageLink(name, ssl) {
289         return findBaseURL(ssl) + "../../../../images/" + name;
290 }
291
292 function buildExtrasLink(name, ssl) {
293         return findBaseURL(ssl) + "../../../../extras/" + name;
294 }
295
296 var consoleService;
297 function _debug(str) { 
298         try { dump('dbg: ' + str + '\n'); } catch(e) {} 
299
300         /* potentially useful, but usually just annoying */
301         /*
302         if(!IE) {
303                 if(!consoleService) {
304                         try {
305                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
306                                 this.consoleService = Components.classes['@mozilla.org/consoleservice;1']
307                                         .getService(Components.interfaces.nsIConsoleService);
308                         } catch(e) {}
309                 }
310         
311                 try {
312                         if(consoleService) {
313                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
314                                 consoleService.logStringMessage(str + '\n');
315                         }
316                 } catch(e){}
317         }
318         */
319 }
320
321 function  buildOPACLink(args, slim, ssl) {
322
323         if(!args) args = {};
324         var string = "";
325
326         if(!slim) {
327                 string = findBaseURL(ssl);
328                 if(args.page) string += config.page[args.page];
329                 else string += config.page[findCurrentPage()];
330         }
331
332         /* this may seem unnecessary.. safety precaution for now */
333         /*
334         if( args[PARAM_DEPTH] == null )
335                 args[PARAM_DEPTH] = getDepth();
336                 */
337
338         string += "?";
339
340         for( var x in args ) {
341                 var v = args[x];
342                 if(x == "page" || v == null || v == undefined || v+'' == 'NaN' ) continue;
343                 if(x == PARAM_OFFSET && v == 0) continue;
344                 if(x == PARAM_COUNT && v == 10) continue;
345                 if(x == PARAM_FORM && v == 'all' ) continue;
346                 if( instanceOf(v, Array) && v.length ) {
347                         for( var i = 0; i < v.length; i++ ) {
348                                 string += "&" + x + "=" + encodeURIComponent(v[i]);
349                         }
350                 } else {
351                         string += "&" + x + "=" + encodeURIComponent(v);
352                 }
353         }
354
355         if(getDebug())
356                 string += _appendParam(DEBUG,           PARAM_DEBUG, args, getDebug, string);
357         if(getOrigLocation() != 1) 
358                 string += _appendParam(ORIGLOC, PARAM_ORIGLOC, args, getOrigLocation, string);
359         if(getTerm()) 
360                 string += _appendParam(TERM,            PARAM_TERM, args, getTerm, string);
361         if(getStype()) 
362                 string += _appendParam(STYPE,           PARAM_STYPE, args, getStype, string);
363         if(getLocation() != 1) 
364                 string += _appendParam(LOCATION, PARAM_LOCATION, args, getLocation, string);
365         if(getLasso() != null) 
366                 string += _appendParam(LASSO, PARAM_LASSO, args, getLasso, string);
367         if(getDepth() != null) 
368                 string += _appendParam(DEPTH,           PARAM_DEPTH, args, getDepth, string);
369         if(getForm() && (getForm() != 'all') ) 
370                 string += _appendParam(FORM,            PARAM_FORM, args, getForm, string);
371         if(getTform() && (getTform() != 'all') ) 
372                 string += _appendParam(TFORM,           PARAM_TFORM, args, getTform, string);
373         if(getOffset() != 0) 
374                 string += _appendParam(OFFSET,  PARAM_OFFSET, args, getOffset, string);
375         if(getDisplayCount() != 10) 
376                 string += _appendParam(COUNT,           PARAM_COUNT, args, getDisplayCount, string);
377         if(getHitCount()) 
378                 string += _appendParam(HITCOUNT, PARAM_HITCOUNT, args, getHitCount, string);
379         if(getMrid())
380                 string += _appendParam(MRID,            PARAM_MRID, args, getMrid, string);
381         if(getRid())
382                 string += _appendParam(RID,             PARAM_RID, args, getRid, string);
383         if(getAuthtime())
384                 string += _appendParam(AUTHTIME,        PARAM_AUTHTIME, args, getAuthtime, string);
385         if(getAdvTerm())
386                 string += _appendParam(ADVTERM, PARAM_ADVTERM, args, getAdvTerm, string);
387         if(getAdvType())
388                 string += _appendParam(ADVTYPE, PARAM_ADVTYPE, args, getAdvType, string);
389         if(getRtype())
390                 string += _appendParam(RTYPE,           PARAM_RTYPE, args, getRtype, string);
391         if(getItemForm())
392                 string += _appendParam(ITEMFORM,        PARAM_ITEMFORM, args, getItemForm, string);
393         if(getItemType())
394                 string += _appendParam(ITEMTYPE,        PARAM_ITEMTYPE, args, getItemType, string);
395         if(getBibLevel())
396                 string += _appendParam(BIBLEVEL,        PARAM_BIBLEVEL, args, getBibLevel, string);
397         if(getLitForm())
398                 string += _appendParam(LITFORM, PARAM_LITFORM, args, getLitForm, string);
399         if(getAudience())
400                 string += _appendParam(AUDIENCE,        PARAM_AUDIENCE, args, getAudience, string);
401         if(getSearches())
402                 string += _appendParam(SEARCHES,        PARAM_SEARCHES, args, getSearches, string);
403         if(getLanguage())
404                 string += _appendParam(LANGUAGE,        PARAM_LANGUAGE, args, getLanguage, string);
405         if(getRdepth() != null)
406                 string += _appendParam(RDEPTH,  PARAM_RDEPTH, args, getRdepth, string);
407         if(getSort() != null)
408                 string += _appendParam(SORT,    PARAM_SORT, args, getSort, string);
409         if(getSortDir() != null)
410                 string += _appendParam(SORT_DIR,        PARAM_SORT_DIR, args, getSortDir, string);
411         if(getAvail())
412                 string += _appendParam(AVAIL, PARAM_AVAIL, args, getAvail, string);
413         if(getCopyLocs())
414                 string += _appendParam(COPYLOCS, PARAM_COPYLOCS, args, getCopyLocs, string);
415
416         return string.replace(/\&$/,'').replace(/\?\&/,"?");    
417 }
418
419 var xx = 1;
420 function _appendParam( fieldVar, fieldName, overrideArgs, getFunc, string ) {
421
422         var ret = "";
423
424         if(     fieldVar != null && 
425                         (fieldVar +'' != 'NaN') && 
426                         overrideArgs[fieldName] == null &&
427                         getFunc() != null &&
428                         getFunc()+'' != '' ) {
429
430                 ret = "&" + fieldName + "=" + encodeURIComponent(getFunc());
431         }
432
433         return ret;
434 }
435
436 /* ----------------------------------------------------------------------- */
437 function cleanISBN(isbn) {
438    if(isbn) {
439       isbn = isbn.toString().replace(/^\s+/,"");
440       var idx = isbn.indexOf(" ");
441       if(idx > -1) { isbn = isbn.substring(0, idx); }
442    } else isbn = "";
443    return isbn;
444 }       
445
446
447 /* builds a link that goes to the title listings for a metarecord */
448 function buildTitleLink(rec, link) {
449         if(!rec) return;
450         link.appendChild(text(normalize(truncate(rec.title(), 65))));
451         var args = {};
452         args.page = RRESULT;
453         args[PARAM_OFFSET] = 0;
454         args[PARAM_MRID] = rec.doc_id();
455         args[PARAM_RTYPE] = RTYPE_MRID;
456         link.setAttribute("href", buildOPACLink(args));
457 }
458
459 function buildTitleDetailLink(rec, link) {
460         if(!rec) return;
461         link.appendChild(text(normalize(truncate(rec.title(), 65))));
462         var args = {};
463         args.page = RDETAIL;
464         //args[PARAM_OFFSET] = 0;
465         args[PARAM_RID] = rec.doc_id();
466         link.setAttribute("href", buildOPACLink(args));
467 }
468
469 /* 'type' is one of STYPE_AUTHOR, STYPE_SUBJECT, ... found in config.js 
470         'trunc' is the number of characters to show in the string, defaults to 65 */
471 function buildSearchLink(type, string, linknode, trunc) {
472         if(!trunc) trunc = 65;
473         var args = {};
474         if( SHOW_MR_DEFAULT) {
475                 args.page = MRESULT;
476         } else {
477                 args.page = RRESULT;
478                 args[PARAM_RTYPE] = type;
479         }
480         args[PARAM_OFFSET] = 0;
481         args[PARAM_TERM] = string;
482         args[PARAM_STYPE] = type;
483         linknode.appendChild(text(normalize(truncate(string, trunc))));
484         linknode.setAttribute("href", buildOPACLink(args));
485 }
486
487 function setSessionCookie(ses) {
488         cookieManager.write(COOKIE_SES, ses, -1);
489 }
490
491
492
493 /* ----------------------------------------------------------------------- */
494 /* user session handling */
495 /* ----------------------------------------------------------------------- */
496 /* session is the login session.  If no session is provided, we attempt
497         to find one in the cookies.  If 'force' is true we retrieve the 
498         user from the server even if there is already a global user present.
499         if ses != G.user.session, we also force a grab */
500 function grabUser(ses, force) {
501
502         if(!ses && isXUL()) {
503                 stash = fetchXULStash();
504                 ses = stash.session.key
505                 _debug("stash auth token = " + ses);
506         }
507
508         if(!ses) {
509                 ses = cookieManager.read(COOKIE_SES);
510                 /* https cookies don't show up in http servers.. */
511         }
512
513         if(!ses) return false;
514
515         if(!force) 
516                 if(G.user && G.user.session == ses)
517                         return G.user;
518
519         /* first make sure the session is valid */
520         var request = new Request(FETCH_SESSION, ses, 1 );
521         request.request.alertEvent = false;
522         request.send(true);
523         var user = request.result();
524
525         if(!user) {
526                 doLogout();
527                 return false; /* unable to grab the session */
528         }
529
530         if( !(typeof user == 'object' && user._isfieldmapper) ) {
531                 doLogout();
532                 return false;
533         }
534
535         G.user = user;
536         G.user.fleshed = false;
537         G.user.session = ses;
538         setSessionCookie(ses);
539
540         grabUserPrefs();
541         if(G.user.prefs['opac.hits_per_page'])
542                 COUNT = parseInt(G.user.prefs['opac.hits_per_page']);
543
544         if(G.user.prefs[PREF_DEF_FONT]) 
545                 setFontSize(G.user.prefs[PREF_DEF_FONT]);
546
547         var at = getAuthtime();
548         //if(isXUL()) at = xulG['authtime'];
549
550         if(at && !isXUL()) new AuthTimer(at).run(); 
551         return G.user;
552 }
553
554
555 /* sets the 'prefs' field of the user object to their preferences 
556         and returns the preferences */
557 function grabUserPrefs(user, force) {
558         if(user == null) user = G.user;
559         if(!force && user.prefs) return user.prefs;     
560         var req = new Request(FETCH_USER_PREFS, user.session, user.id());
561         req.send(true);
562         user.prefs = req.result();
563         return user.prefs;
564 }
565
566 function grabFleshedUser() {
567
568         if(!G.user || !G.user.session) {
569                 grabUser();     
570                 if(!G.user || !G.user.session) return null;
571         }
572
573         if(G.user.fleshed) return G.user;
574
575    var req = new Request(FETCH_FLESHED_USER, G.user.session);
576         req.send(true);
577
578         G.user = req.result();
579
580         if(!G.user || G.user.length == 0) { 
581                 G.user = null; return false; 
582                 cookieManager.write(COOKIE_SES,"");
583         }
584
585         G.user.session = ses;
586         G.user.fleshed = true;
587
588         setSessionCookie(ses);
589         return G.user;
590 }
591
592 function checkUserSkin(new_skin) {
593
594         return; /* XXX do some debugging with this... */
595
596         var user_skin = getSkin();
597         var cur_skin = grabSkinFromURL();
598
599         if(new_skin) user_skin = new_skin;
600
601         if(!user_skin) {
602
603                 if(grabUser()) {
604                         if(grabUserPrefs()) {
605                                 user_skin = G.user.prefs["opac.skin"];
606                                 cookieManager.write( COOKIE_SKIN, user_skin, '+1y' );
607                         }
608                 }
609         }
610
611         if(!user_skin) return;
612
613         if( cur_skin != user_skin ) {
614                 var url = buildOPACLink();
615                 goTo(url.replace(cur_skin, user_skin));
616         }
617 }
618
619 function updateUserSetting(setting, value, user) {
620         if(user == null) user = G.user;
621         var a = {};
622         a[setting] = value;
623         var req = new Request( UPDATE_USER_PREFS, user.session, a );
624         req.send(true);
625         return req.result();
626 }
627
628 function commitUserPrefs() {
629         var req = new Request( 
630                 UPDATE_USER_PREFS, G.user.session, null, G.user.prefs );
631         req.send(true);
632         return req.result();
633 }
634
635 function grabSkinFromURL() {
636         var path = findBasePath();
637         path = path.replace("/xml/", "");
638         var skin = "";
639         for( var i = path.length - 1; i >= 0; i-- ) {
640                 var ch = path.charAt(i);
641                 if(ch == "/") break;
642                 skin += ch;
643         }
644
645         var skin2 = "";
646         for( i = skin.length - 1; i >= 0; i--)
647                 skin2 += skin.charAt(i);
648
649         return skin2;
650 }
651
652
653 /* returns a fleshed G.user on success, false on failure */
654 function doLogin(suppressEvents) {
655
656         abortAllRequests();
657
658         var uname = G.ui.login.username.value;
659         var passwd = G.ui.login.password.value; 
660
661         var init_request = new Request( LOGIN_INIT, uname );
662    init_request.send(true);
663    var seed = init_request.result();
664
665    if( ! seed || seed == '0') {
666       alert( "Error Communicating with Authentication Server" );
667       return null;
668    }
669
670         var args = {
671                 password : hex_md5(seed + hex_md5(passwd)), 
672                 type            : "opac", 
673                 org             : getOrigLocation()
674         };
675
676     r = fetchOrgSettingDefault(globalOrgTree.id(), 'opac.barcode_regex');
677     if(r) REGEX_BARCODE = new RegExp(r);
678     
679     if( uname.match(REGEX_BARCODE) ) args.barcode = uname;
680         else args.username = uname;
681
682    var auth_request = new Request( LOGIN_COMPLETE, args );
683
684         auth_request.request.alertEvent = false;
685    auth_request.send(true);
686    var auth_result = auth_request.result();
687
688         if(!auth_result) {
689                 alertId('patron_login_failed');
690                 return null;
691         }
692
693         if( checkILSEvent(auth_result) ) {
694
695                 if( auth_result.textcode == 'PATRON_INACTIVE' ) {
696                         alertId('patron_inactive_alert');
697                         return;
698                 }
699
700                 if( auth_result.textcode == 'PATRON_CARD_INACTIVE' ) {
701                         alertId('patron_card_inactive_alert');
702                         return;
703                 }
704
705                 if( auth_result.textcode == 'LOGIN_FAILED' || 
706                                 auth_result.textcode == 'PERM_FAILURE' ) {
707                         alertId('patron_login_failed');
708                         return;
709                 }
710         }
711
712
713         AUTHTIME = parseInt(auth_result.payload.authtime);
714         var u = grabUser(auth_result.payload.authtoken, true);
715         if(u && ! suppressEvents) 
716                 runEvt( "common", "locationChanged", u.ws_ou(), findOrgDepth(u.ws_ou()) );
717
718         checkUserSkin();
719
720         return u;
721 }
722
723 function doLogout() {
724
725         /* cancel everything else */
726         abortAllRequests();
727
728         /* be nice and delete the session from the server */
729         if(G.user && G.user.session) { 
730                 var req = new Request(LOGIN_DELETE, G.user.session);
731       req.send(true);
732                 try { req.result(); } catch(E){}
733     }
734
735         G.user = null;
736
737         /* remove any cached data */
738         //cookieManager.remove(COOKIE_IDS);
739         //cookieManager.remove(COOKIE_SRIDS);
740         cookieManager.remove(COOKIE_RIDS);
741         cookieManager.remove(COOKIE_SES);
742         cookieManager.remove(COOKIE_SKIN);
743         cookieManager.remove(COOKIE_SEARCH);
744
745         checkUserSkin("default");
746         COUNT = 10;
747
748
749         var args = {};
750         args[PARAM_TERM] = "";
751         args[PARAM_LOCATION] = getOrigLocation();
752         args[PARAM_DEPTH] = findOrgDepth(getOrigLocation());
753         args.page = "home";
754
755         
756         var nored = false;
757         try{ if(isFrontPage) nored = true; } catch(e){nored = false;}
758         if(!nored) goTo(buildOPACLink(args));
759 }
760
761
762 function hideMe(obj) { addCSSClass(obj, config.css.hide_me); } 
763 function unHideMe(obj) { removeCSSClass(obj, config.css.hide_me); }
764
765
766 /* ----------------------------------------------------------------------- */
767 /* build the org tree */
768 /* ----------------------------------------------------------------------- */
769 function drawOrgTree() {
770         //setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 10 );
771         setTimeout( 'buildOrgSelector(G.ui.common.org_tree, orgTreeSelector);', 1 );
772 }
773         
774 var orgTreeSelector;
775 function buildOrgSelector(node) {
776         var tree = new SlimTree(node,'orgTreeSelector');
777         orgTreeSelector = tree;
778         for( var i in orgArraySearcher ) { 
779                 var node = orgArraySearcher[i];
780                 if( node == null ) continue;
781         if(!isXUL() && !isTrue(node.opac_visible())) continue; 
782                 if(node.parent_ou() == null)
783                         tree.addNode(node.id(), -1, node.name(), 
784                                 "javascript:orgSelect(" + node.id() + ");", node.name());
785                 else {
786                         tree.addNode(node.id(), node.parent_ou(), node.name(), 
787                                 "javascript:orgSelect(" + node.id() + ");", node.name());
788                 }
789         }
790         hideMe($('org_loading_div'));
791         unHideMe($('org_selector_tip'));
792         return tree;
793 }
794
795 function orgSelect(id) {
796         showCanvas();
797         runEvt("common", "locationChanged", id, findOrgDepth(id) );
798
799
800         var loc = findOrgLasso(getLasso());
801         if (!loc) loc = findOrgUnit(id);
802
803         removeChildren(G.ui.common.now_searching);
804         G.ui.common.now_searching.appendChild(text(loc.name()));
805 }
806
807 function setFontSize(size) {
808         scaleFonts(size);
809         cookieManager.write(COOKIE_FONT, size, '+1y');
810 }
811
812 var resourceFormats = [
813    "text",
814    "moving image",
815    "sound recording", "software, multimedia",
816    "still image",
817    "cartographic",
818    "mixed material",
819    "notated music",
820    "three dimensional object" ];
821
822
823 function modsFormatToMARC(format) {
824    switch(format) {
825       case "text":
826          return "at";
827       case "moving image":
828          return "g";
829       case "sound recording":
830          return "ij";
831       case "sound recording-nonmusical":
832          return "i";
833       case "sound recording-musical":
834          return "j";
835       case "software, multimedia":
836          return "m";
837       case "still image":
838          return "k";
839       case "cartographic":
840          return "ef";
841       case "mixed material":
842          return "op";
843       case "notated music":
844          return "cd";
845       case "three dimensional object":
846          return "r";
847    }
848    return "at";
849 }
850
851
852 function MARCFormatToMods(format) {
853    switch(format) {
854       case "a":
855       case "t":
856          return "text";
857       case "g":
858          return "moving image";
859       case "i":
860          return "sound recording-nonmusical";
861       case "j":
862          return "sound recording-musical";
863       case "m":
864          return "software, multimedia";
865       case "k":
866          return "still image";
867       case "e":
868       case "f":
869          return "cartographic";
870       case "o":
871       case "p":
872          return "mixed material";
873       case "c":
874       case "d":
875          return "notated music";
876       case "r":
877          return "three dimensional object";
878    }
879    return "text";
880 }
881
882 function MARCTypeToFriendly(format) {
883         var words = $('format_words');
884         switch(format) {
885                 case 'a' :
886                 case 't' : return $n(words, 'at').innerHTML;
887                 default:
888                         var node = $n(words,format);
889                         if( node ) return node.innerHTML;
890         }
891         return "";
892 }
893
894 function setResourcePic( img, resource ) {
895         img.setAttribute( "src", "../../../../images/tor/" + resource + ".jpg");
896         img.title = resource;
897 }
898
899
900
901 function msg( text ) {
902         try { alert( text ); } catch(e) {}
903 }
904
905 function findRecord(id,type) {
906         try {
907                 for( var i = 0; i != recordsCache.length; i++ ) {
908                         var rec = recordsCache[i];
909                         if( rec && rec.doc_id() == id ) return rec;
910                 }
911         } catch(E){}
912         var meth = FETCH_RMODS
913         if(type == 'M') meth = FETCH_MRMODS;
914         var req = new Request(meth, id);
915         req.request.alertEvent = false;
916         req.send(true);
917         var res = req.result();
918         if( checkILSEvent(res) ) return null; 
919         return res;
920 }
921
922 function Timer(name, node){
923         this.name = name;
924         this.count = 1;
925         this.node = node;
926 }
927 Timer.prototype.start = 
928         function(){_timerRun(this.name);}
929 Timer.prototype.stop = 
930         function(){this.done = true;}
931 function _timerRun(tname) {
932         var _t;
933         eval('_t='+tname);
934         if(_t.done) return;
935         if(_t.count > 100) return;
936         var str = ' . ';
937         if( (_t.count % 5) == 0 ) 
938                 str = _t.count / 5;
939         _t.node.appendChild(text(str));
940         setTimeout("_timerRun('"+tname+"');", 200);
941         _t.count++;
942 }
943
944 function checkILSEvent(obj) {
945         if( obj && obj.ilsevent != null && obj.ilsevent != 0 )
946                 return parseInt(obj.ilsevent);
947         return null;
948 }
949
950
951 function alertILSEvent(evt, msg) {
952    if(!msg) msg = "";
953         if(msg)
954                 alert(msg +'\n' + evt.textcode + '\n' + evt.desc );
955         else 
956                 alert(evt.textcode + '\n' + evt.desc );
957 }
958
959
960 var __authTimer;
961 function AuthTimer(time) { 
962         this.time = (time - LOGOUT_WARNING_TIME) * 1000; 
963         if(__authTimer) 
964                 try {clearTimeout(__authTimer.id)} catch(e){}
965         __authTimer = this;
966 }
967
968 AuthTimer.prototype.run = function() {
969         this.id = setTimeout('_authTimerAlert()', this.time);
970 }
971
972 function _authTimerAlert() {
973         alert( $('auth_session_expiring').innerHTML );
974         if(!grabUser(null, true)) doLogout();
975 }
976
977
978 function grabUserByBarcode( authtoken, barcode ) {
979         var req = new Request( FETCH_USER_BYBARCODE, authtoken, barcode );
980         req.send(true);
981         return req.result();
982 }
983
984
985 function goHome() {
986         goTo(buildOPACLink({page:HOME}));
987 }
988
989
990 function buildOrgSel(selector, org, offset, namecol) {
991     if(!namecol) namecol = 'name';
992         insertSelectorVal( selector, -1, 
993                 org[namecol](), org.id(), null, findOrgDepth(org) - offset );
994         for( var c in org.children() )
995                 buildOrgSel( selector, org.children()[c], offset, namecol);
996 }
997
998 function buildMergedOrgSel(selector, org_list, offset, namecol) {
999     if(!namecol) namecol = 'name';
1000     for(var i = 0; i < org_list.length; i++) {
1001         var org = findOrgUnit(org_list[i]);
1002         insertSelectorVal( selector, -1, 
1003                     org[namecol](), org.id(), null, findOrgDepth(org) - offset );
1004             for( var c in org.children() )
1005                     buildOrgSel( selector, org.children()[c], offset, namecol);
1006     }
1007 }
1008
1009
1010 function parseForm(form) {
1011         if(!form) return {};
1012
1013         var it = form.replace(/-\w+$/,"");
1014         var itf = null;
1015         var item_form;
1016         var item_type;
1017
1018         if(form.match(/-/)) itf = form.replace(/^\w+-/,"");
1019
1020         if(it) {
1021                 item_type = [];
1022                 for( var i = 0; i < it.length; i++ ) 
1023                         item_type.push( it.charAt(i) );
1024         }
1025
1026         if(itf) {
1027                 item_form = [];
1028                 for( var i = 0; i < itf.length; i++ ) 
1029                         item_form.push( itf.charAt(i) );
1030         }
1031
1032         return {item_type: item_type, item_form:item_form};
1033 }
1034
1035
1036 function isTrue(x) { return ( x && x != "0" && !(x+'').match(/^f$/i) ); }
1037
1038 function fetchPermOrgs() {
1039         var a = []; /* why does arguments come accross as an object and not an array? */
1040         for( var i = 0; i < arguments.length; i++ ) 
1041                 a.push(arguments[i])
1042
1043         var preq = new Request(FETCH_HIGHEST_PERM_ORG, 
1044                 G.user.session, G.user.id(), a );
1045         preq.send(true);
1046         return preq.result();
1047 }
1048
1049
1050 function print_tabs(t) {
1051         var r = '';
1052         for (var j = 0; j < t; j++ ) { r = r + "  "; }
1053         return r;
1054 }
1055 function formatJSON(s) {
1056         var r = ''; var t = 0;
1057         for (var i in s) {
1058                 if (s[i] == '{' || s[i] == '[' ) {
1059                         r = r + s[i] + "\n" + print_tabs(++t);
1060                 } else if (s[i] == '}' || s[i] == ']') {
1061                         t--; r = r + "\n" + print_tabs(t) + s[i];
1062                 } else if (s[i] == ',') {
1063                         r = r + s[i] + "\n" + print_tabs(t);
1064                 } else {
1065                         r = r + s[i];
1066                 }
1067         }
1068         return r;
1069 }