function showlayer(layer){
var myLayer = document.getElementById(layer).style.display;
if(myLayer=="none"){
document.getElementById(layer).style.display="block";
} else {
document.getElementById(layer).style.display="none";
}
}


$(function() {
$("#a_date").date_input();
});


function calcHeight()
{
//find the height of the internal page
var the_height=
document.getElementById('test').contentWindow.
document.body.scrollHeight;

//change the height of the iframe
document.getElementById('test').height=the_height;
}


$(function() {

//cache the ticker
var ticker = $("#ticker");

//wrap dt:dd pairs in divs
ticker.children().filter("dt").each(function() {

var dt = $(this),
container = $("<div>");

dt.next().appendTo(container);
dt.prependTo(container);

container.appendTo(ticker);
});

//hide the scrollbar
ticker.css("overflow", "hidden");

//animator function
function animator(currentItem) {

//work out new anim duration
var distance = currentItem.height();
duration = (distance + parseInt(currentItem.css("marginTop"))) / 0.025;

//animate the first child of the ticker
currentItem.animate({ marginTop: -distance }, duration, "linear", function() {

//move current item to the bottom
currentItem.appendTo(currentItem.parent()).css("marginTop", 0);

//recurse
animator(currentItem.parent().children(":first"));
}); 
};

//start the ticker
animator(ticker.children(":first"));

//set mouseenter
ticker.mouseenter(function() {

//stop current animation
ticker.children().stop();

});

//set mouseleave
ticker.mouseleave(function() {

//resume animation
animator(ticker.children(":first"));

});
}); 


var TINY={};function T$(i){return document.getElementById(i)}function T$$(e,p){return p.getElementsByTagName(e)}TINY.accordion=function(){function slider(n){this.n=n;this.a=[]}slider.prototype.init=function(t,e,m,o,k){var a=T$(t),i=s=0,n=a.childNodes,l=n.length;this.s=k||0;this.m=m||0;for(i;i<l;i++){var v=n[i];if(v.nodeType!=3){this.a[s]={};this.a[s].h=h=T$$(e,v)[0];this.a[s].c=c=T$$('div',v)[0];h.onclick=new Function(this.n+'.pr(0,'+s+')');if(o==s){h.className=this.s;c.style.height='auto';c.d=1}else{c.style.height=0;c.d=-1}s++}}this.l=s};slider.prototype.pr=function(f,d){for(var i=0;i<this.l;i++){var h=this.a[i].h,c=this.a[i].c,k=c.style.height;k=k=='auto'?1:parseInt(k);clearInterval(c.t);if((k!=1&&c.d==-1)&&(f==1||i==d)){c.style.height='';c.m=c.offsetHeight;c.style.height=k+'px';c.d=1;h.className=this.s;su(c,1)}else if(k>0&&(f==-1||this.m||i==d)){c.d=-1;h.className='';su(c,-1)}}};function su(c){c.t=setInterval(function(){sl(c)},20)};function sl(c){var h=c.offsetHeight,d=c.d==1?c.m-h:h;c.style.height=h+(Math.ceil(d/5)*c.d)+'px';c.style.opacity=h/c.m;c.style.filter='alpha(opacity='+h*100/c.m+')';if((c.d==1&&h>=c.m)||(c.d!=1&&h==1)){if(c.d==1){c.style.height='auto'}clearInterval(c.t)}};return{slider:slider}}();eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(3(c){3 p(d,a,b){8 e=7,j=d.11(7),h=d.T(b.U),k=a.2E?a:d.1F(a),i;h.D||(h=d.1F());k.D||(k=d.28().T(a));k.D||(k=c(a));c.M(7,{y:3(f,g){8 l=h.B(f);5(1G f=="1H"&&f.29("#","")){l=h.3u("[1I*="+f.29("#","")+"]");f=18.2a(h.1J(l),0)}5(b.2F){8 n=h.D-1;5(f<0)4 e.y(n,g);5(f>n)4 e.y(0,g)}5(!l.D){5(i>=0)4 e;f=b.12;l=h.B(f)}5(f===i)4 e;g=g||c.19();g.L="1K";j.C(g,[f]);5(!g.13()){o[b.G].N(e,f,3(){g.L="2b";j.C(g,[f])});i=f;h.3v(b.1L);l.1M(b.1L);4 e}},H:3(){4 b},2G:3(){4 h},V:3(){4 k},2H:3(){4 k.B(i)},3w:3(){4 h.B(i)},2I:3(){4 i},W:3(){4 e.y(i+1)},1a:3(){4 e.y(i-1)}});c.O("1K,2b".14(","),3(f,g){c.1b(b[g])&&c(e).z(g,b[g]);e[g]=3(l){c(e).z(g,l);4 e}});5(b.1n&&c.1c.1n){c.x.1n.3x(h);b.2c="1n"}h.O(3(f){c(7).z(b.2c,3(g){e.y(f,g);4 g.1o()})});k.T("a[1I^=#]").y(3(f){e.y(c(7).1p("1I"),f)});5(2J.2K)e.y(2J.2K);X 5(b.12===0||b.12>0)e.y(b.12)}c.x=c.x||{1q:"1.2.0"};c.x.U={R:{U:"a",1L:"1L",1K:Y,2b:Y,G:"1N",12:0,2c:"y",2F:I,1n:I},1d:3(d,a){o[d]=a}};8 o={"1N":3(d,a){7.V().P().B(d).15();a.N()},2L:3(d,a){8 b=7.H(),e=b.2d,j=7.V();5(!j.B(d).1r(":3y")){e?j.2e(e):j.P();j.B(d).1O(b.1P,a)}},3z:3(d,a){7.V().3A(3B);7.V().B(d).3C(2M,a)},3D:3(d,a){7.V().B(0).1e(7.2G().B(d).1p("1I"),a)}},m;c.x.U.1d("3E",3(d,a){m||(m=7.V().B(0).Q());7.2H().1f({Q:0},3(){c(7).P()});7.V().B(d).1f({Q:m},3(){c(7).15();a.N()})});c.1c.U=3(d,a){8 b=7.J("U");5(b)4 b;5(c.1b(a))a={1K:a};a=c.M({},c.x.U.R,a);7.O(3(){b=1Q p(c(7),d,a);c(7).J("U",b)});4 a.1R?b:7}})(1s);(3(f){3 p(a,b,c){8 h=c.2f?a.A().9:a.1g().9,e=c.2f?a.A().w:a.1g().w,i=c.A[0];h-=b.1S()-c.1g[0];e+=a.1t()+c.1g[1];8 j=b.1S()+a.1S();5(i=="1h")h+=j/2;5(i=="3F")h+=j;i=c.A[1];a=b.1t()+a.1t();5(i=="1h")e-=a/2;5(i=="w")e-=a;4{9:h,w:e}}3 t(a,b){8 c=7,h=a.11(c),e,i=0,j=0,m=a.1p("2g"),q=n[b.G],k,r=a.1r(":1u"),u=r&&a.1r(":2N, :2O, 3G, :3H"),s=a.1p("L"),l=b.1v[s]||b.1v[r?u?"2P":"1u":"2Q"];5(!q)1i\'3I G "\'+b.G+\'"\';l=l.14(/,\\s*/);5(l.D!=2)1i"3J: 3K 1v 3L 2h "+s;a.z(l[0],3(d){5(b.2i){1T(i);j=2R(3(){c.15(d)},b.2i)}X c.15(d)}).z(l[1],3(d){5(b.2j){1T(j);i=2R(3(){c.P(d)},b.2j)}X c.P(d)});5(m&&b.2S){a.3M("2g");a.J("2g",m)}f.M(c,{15:3(d){5(!e){5(m)e=f(b.2T).1M(b.2U).2V(1w.2W).P();X 5(b.2k)e=f(b.2k).B(0);X{e=a.W();e.D||(e=a.28().W())}5(!e.D)1i"3N T S 2h "+a;}5(c.2l())4 c;e.3O(E,E);8 g=p(a,e,b);m&&e.3P(m);d=d||f.19();d.L="2X";h.C(d,[g]);5(d.13())4 c;g=p(a,e,b);e.F({A:"1x",9:g.9,w:g.w});k=E;q[0].N(c,3(){d.L="2Y";k="2Z";h.C(d)});g=b.1v.S.14(/,\\s*/);e.z(g[0],3(){1T(i);1T(j)});g[1]&&!a.1r("1u:1U(:2N, :2O), 3Q")&&e.z(g[1],3(o){o.3R!=a[0]&&a.C(l[1].14(" ")[0])});4 c},P:3(d){5(!e||!c.2l())4 c;d=d||f.19();d.L="31";h.C(d);5(!d.13()){k=I;n[b.G][1].N(c,3(){d.L="32";k=I;h.C(d)});4 c}},2l:3(d){4 d?k=="2Z":k},H:3(){4 b},1y:3(){4 e},1V:3(){4 a}});f.O("32,2X,2Y,31".14(","),3(d,g){f.1b(b[g])&&f(c).z(g,b[g]);c[g]=3(o){f(c).z(g,o);4 c}})}f.x=f.x||{1q:"1.2.0"};f.x.S={R:{G:"33",2d:"2m",2i:0,2j:30,2n:1,2k:0,A:["9","1h"],1g:[0,0],2f:I,2S:E,1v:{2Q:"2o,2p",1u:"2q,34",2P:"2q 2o,34 2p",S:"2o,2p"},2T:"<2r/>",2U:"S"},1d:3(a,b,c){n[a]=[b,c]}};8 n={33:[3(a){8 b=7.H(),c=7.1y();b=b.2n;b<1&&c.F({2n:b});c.15();a.N()},3(a){7.1y().P();a.N()}],2L:[3(a){7.1y().1O(7.H().1P,a)},3(a){7.1y().2e(7.H().2d,a)}]};f.1c.S=3(a){8 b=7.J("S");5(b)4 b;a=f.M(E,{},f.x.S.R,a);5(1G a.A=="1H")a.A=a.A.14(/,?\\s/);7.O(3(){b=1Q t(f(7),a);f(7).J("S",b)});4 a.1R?b:7}})(1s);(3(e){3 n(f,c){8 a=e(c);4 a.D<2?a:f.28().T(c)}3 t(f,c){8 a=7,k=f.11(a),g=f.1F(),l=0,m=c.35;j||(j=a);5(g.D>1)g=e(c.2s,f);e.M(a,{H:3(){4 c},2I:3(){4 l},1j:3(){4 a.1k().3S()},3T:3(){4 o.11(p)},3U:3(){4 f},3V:3(){4 g},1k:3(){4 g.1F(c.36).1U("."+c.1W)},1l:3(b,d){4 a.16(l+b,d)},W:3(b){4 a.1l(1,b)},1a:3(b){4 a.1l(-1,b)},3a:3(b){4 a.16(0,b)},3b:3(b){4 a.16(a.1j()-1,b)},2q:3(){4 j=a},3W:3(b){b=e(b);5(c.1z){e(".2t:3X").3Y(b);e(".2t:3Z").41(b.2u().1M(c.1W))}X g.3c(b);k.C("3d",[b]);4 a},16:3(b,d,h){5(!c.1z&&b<0||b>a.1j())4 a;8 i=b;5(b.2E)b=a.1k().1J(b);X i=a.1k().B(b);8 q=e.19("1A");5(!h){k.C(q,[b,d]);5(q.13()||!i.D)4 a}i=m?{9:-i.A().9}:{w:-i.A().w};g.1f(i,d,c.3e,h||3(){k.C("3f",[b])});j=a;l=b;4 a}});e.O(["1A","3f","3d"],3(b,d){e.1b(c[d])&&e(a).z(d,c[d]);a[d]=3(h){e(a).z(d,h);4 a}});5(c.1z){8 r=a.1k().2v(-1).2u().42(g),s=a.1k().B(1).2u().2V(g);r.11(s).1M(c.1W);a.1A(3(b,d,h){5(!b.13())5(d==-1){a.16(r,h,3(){a.3b(0)});4 b.1o()}X d==a.1j()&&a.16(s,h,3(){a.3a(0)})});a.16(0,0)}8 o=n(f,c.1a).y(3(){a.1a()}),p=n(f,c.W).y(3(){a.W()});!c.1z&&a.1j()>1&&a.1A(3(b,d){o.3g(c.2w,d<=0);p.3g(c.2w,d>=a.1j()-1)});c.1B&&e.1c.1B&&f.1B(3(b,d){5(c.1B){a.1l(d<0?1:-1,c.3h||43);4 I}});c.1X&&e(1w).z("2x.1m",3(b){5(!(!c.1X||b.44||b.45||e(b.1Y).1r(":1u")))5(!(c.1X!="46"&&j!=a)){8 d=b.3i;5(m&&(d==38||d==40)){a.1l(d==38?-1:1);4 b.1o()}5(!m&&(d==37||d==39)){a.1l(d==37?-1:1);4 b.1o()}}});e(a).C("1A",[c.12])}e.x=e.x||{1q:"1.2.0"};e.x.1m={R:{47:"48",1z:I,1W:"2t",2w:"49",3e:"4a",12:0,36:Y,2s:".2s",1X:E,1B:I,W:".W",1a:".1a",1Z:2M,35:I,3h:0}};8 j;e.1c.1m=3(f){8 c=7.J("1m");5(c)4 c;f=e.M({},e.x.1m.R,f);7.O(3(){c=1Q t(e(7),f);e(7).J("1m",c)});4 f.1R?c:7}})(1s);(3(a){3 t(d,b){8 c=7,i=d.11(c),o=a(2y),k,f,m,g=a.x.2z&&(b.20||b.2z),n=18.4b().4c().2v(10);5(g){5(1G g=="1H")g={4d:g};g.21=g.2A=I}8 p=b.1Y||d.1p("4e");f=p?a(p):d;5(!f.D)1i"4f 1U T 3j: "+p;d&&d.1J(f)==-1&&d.y(3(e){c.1e(e);4 e.1o()});a.M(c,{1e:3(e){5(c.22())4 c;8 h=q[b.G];5(!h)1i\'3j: 4g T G : "\'+b.G+\'"\';b.3k&&a.O(s,3(){7.K(e)});e=e||a.19();e.L="2B";i.C(e);5(e.13())4 c;m=E;g&&a(f).2z(g);8 j=b.9,r=b.w,u=f.1t({2C:E}),v=f.1S({2C:E});5(1G j=="1H")j=j=="1h"?18.2a((o.23()-v)/2,0):4h(j,10)/4i*o.23();5(r=="1h")r=18.2a((o.Q()-u)/2,0);h[0].N(c,{9:j,w:r},3(){5(m){e.L="3l";i.C(e)}});g&&b.21&&a.20.4j().4k("y",c.K);b.21&&a(1w).z("y."+n,3(l){a(l.1Y).4l(f).D||c.K(l)});b.2A&&a(1w).z("2x."+n,3(l){l.3i==27&&c.K(l)});4 c},K:3(e){5(!c.22())4 c;e=e||a.19();e.L="3m";i.C(e);5(!e.13()){m=I;q[b.G][1].N(c,3(){e.L="3n";i.C(e)});a(1w).3o("y."+n).3o("2x."+n);g&&a.20.K();4 c}},1C:3(){4 f},1V:3(){4 d},4m:3(){4 k},22:3(){4 m},H:3(){4 b}});a.O("2B,4n,3l,3m,3n".14(","),3(e,h){a.1b(b[h])&&a(c).z(h,b[h]);c[h]=3(j){a(c).z(h,j);4 c}});k=f.T(b.K||".K");5(!k.D&&!b.K){k=a(\'<2r 4o="K"></2r>\');f.4p(k)}k.y(3(e){c.K(e)});b.1e&&c.1e()}a.x=a.x||{1q:"1.2.0"};a.x.Z={1d:3(d,b,c){q[d]=[b,c]},R:{K:Y,21:E,2A:E,2D:"2m",G:"1N",17:!a.3p.4q||a.3p.1q>6,w:"1h",1e:I,20:Y,3k:E,1Z:"4r",1Y:Y,9:"10%"}};8 s=[],q={};a.x.Z.1d("1N",3(d,b){8 c=7.H(),i=a(2y);5(!c.17){d.9+=i.24();d.w+=i.25()}d.A=c.17?"17":"1x";7.1C().F(d).1O(c.1Z,b)},3(d){7.1C().2e(7.H().2D,d)});a.1c.Z=3(d){8 b=7.J("Z");5(b)4 b;5(a.1b(d))d={2B:d};d=a.M(E,{},a.x.Z.R,d);7.O(3(){b=1Q t(a(7),d);s.4s(b);a(7).J("Z",b)});4 d.1R?b:7}})(1s);(3(i){3 j(b){8 d=b.1g();4{9:d.9+b.23()/2,w:d.w+b.Q()/2}}8 k=i.x.Z,f=i(2y);i.M(k.R,{1D:{9:Y,w:Y},1P:"2m",1E:4t});3 n(b,d){8 a=7.1C(),c=7.H(),g=7.1V(),o=7,l=a.1t({2C:E}),h=a.J("26");5(!h){8 e=a.F("3q");5(!e)1i"4u-4v 4w 4x 1U 4y 2h Z";e=e.2v(e.3r("(")+1,e.3r(")")).29(/\\"/g,"");a.F("3q","3s");h=i(\'<26 4z="\'+e+\'"/>\');h.F({4A:0,4B:"3s"}).Q(l);i("2W").3c(h);a.J("26",h)}e=c.1D.9||18.3t(f.23()/2);8 m=c.1D.w||18.3t(f.Q()/2);5(g){g=j(g);e=g.9;m=g.w}h.F({A:"1x",9:e,w:m,Q:0,1E:c.1E}).15();b.9+=f.24();b.w+=f.25();b.A="1x";a.F(b);h.1f({9:a.F("9"),w:a.F("w"),Q:l},c.1Z,3(){5(c.17){b.9-=f.24();b.w-=f.25();b.A="17";h.11(a).F(b)}a.F("1E",c.1E+1).1O(c.1P,3(){o.22()&&!i(7).1J(a)?d.N():a.P()})})}3 p(b){8 d=7.1C().P(),a=7.H(),c=7.1V();d=d.J("26");8 g={9:a.1D.9,w:a.1D.w,Q:0};c&&i.M(g,j(c));a.17&&d.F({A:"1x"}).1f({9:"+="+f.24(),w:"+="+f.25()},0);d.1f(g,a.2D,b)}k.1d("4C",n,p)})(1s);',62,287,'|||function|return|if||this|var|top|||||||||||||||||||||||left|tools|click|bind|position|eq|trigger|length|true|css|effect|getConf|false|data|close|type|extend|call|each|hide|width|conf|tooltip|find|tabs|getPanes|next|else|null|overlay||add|initialIndex|isDefaultPrevented|split|show|seekTo|fixed|Math|Event|prev|isFunction|fn|addEffect|load|animate|offset|center|throw|getSize|getItems|move|scrollable|history|preventDefault|attr|version|is|jQuery|outerWidth|input|events|document|absolute|getTip|circular|onBeforeSeek|mousewheel|getOverlay|start|zIndex|children|typeof|string|href|index|onBeforeClick|current|addClass|default|fadeIn|fadeInSpeed|new|api|outerHeight|clearTimeout|not|getTrigger|clonedClass|keyboard|target|speed|mask|closeOnClick|isOpened|height|scrollTop|scrollLeft|img||parent|replace|max|onClick|event|fadeOutSpeed|fadeOut|relative|title|for|predelay|delay|tip|isShown|fast|opacity|mouseenter|mouseleave|focus|div|items|cloned|clone|slice|disabledClass|keydown|window|expose|closeOnEsc|onBeforeLoad|margin|closeSpeed|jquery|rotate|getTabs|getCurrentPane|getIndex|location|hash|fade|400|checkbox|radio|widget|def|setTimeout|cancelDefault|layout|tipClass|appendTo|body|onBeforeShow|onShow|full||onBeforeHide|onHide|toggle|blur|vertical|item||||begin|end|append|onAddItem|easing|onSeek|toggleClass|wheelSpeed|keyCode|Overlay|oneInstance|onLoad|onBeforeClose|onClose|unbind|browser|backgroundImage|indexOf|none|round|filter|removeClass|getCurrentTab|init|visible|slide|slideUp|200|slideDown|ajax|horizontal|bottom|select|button|Nonexistent|Tooltip|bad|configuration|removeAttr|Cannot|stop|html|textarea|relatedTarget|size|getNaviButtons|getRoot|getItemWrap|addItem|last|before|first||replaceWith|prependTo|50|altKey|ctrlKey|static|activeClass|active|disabled|swing|random|toString|color|rel|Could|cannot|parseInt|100|getMask|one|parents|getClosers|onStart|class|prepend|msie|normal|push|9999|background|image|CSS|property|set|src|border|display|apple'.split('|'),0,{}))//POI Auto Map v4.0.0 11Jan2011 - (c) Gavin Smith 2010 - 2011 - http://codecanyon.net/item/point-of-interest-poi-auto-map/101599
//Commercial License
//Google Search Based POIs require you to sign up for your Google AJAX Key Here: http://code.google.com/apis/ajaxsearch/signup.html
google.load("search", "1");
// Map Configuration
var defaultAddress = "";
var defaultHTML = "";
var defaultZoomLevel = 15; //Larger Number = Higher Zoom 
var infoHTML = "<h4>Instructions</h4><p>Drag the map or enter an address above to view a different area's information. Click on the list of categories to show points of interest on the map. Click on each point to see more detail.</p>";
var searchControls = true;
var mapDivID = "map";
var categoriesList = "poiList";
var directionsMode = 'DRIVING'; //change to 'walking' WALKING for walking directions
//Database Bounds Search Extension
var extendLat = 0.05;
var extendLng = 0.005;
//Main Marker Configuration
var mainIconWidth = 43;
var mainIconHeight = 50;
var mainAnchorPointX = 17;
var mainAnchorPointY = 49;
// Icon Configuration
var iconPath = "icons/";
var iconWidth = 32;
var iconHeight = 37;
var anchorPointX = 16;
var anchorPointY = 34; 

var dbPath = "db/";
var xmlExtra = false; //runs if true: xmlPost(xml);
var mapExtra = false; //runs if true: mapPost(xml);
/*-------------------------------*/
/*  Do Not edit below this line  */
/*-------------------------------*/
var classAdder;
var markerGroups = "";
var map = null;
var searchCenter;
var addressSet;
var overlayControls;
var wikiLayer;
var photoLayer;
var startAddress;
var directions;
var myPano;
var jsonGroups;
var mapDiv;
var mapLoading;
var ddBoxDiv;
var batchGeoLat = [];
var batchGeoLng = [];
var lastInfoWindow;
var directionDisplay;
var directionsService;


function setupAddress() {
  if (typeof poiAddress === 'undefined') {
    startAddress = defaultAddress;
  } else {
    startAddress = poiAddress;
  }
  if (typeof poiHTML === 'undefined') {
    markerHTML = defaultHTML;
  } else {
    markerHTML = poiHTML;
  }
  if (typeof poiZoomLevel === 'undefined') {
    zoomLevel = defaultZoomLevel;
  } else {
    zoomLevel = poiZoomLevel;
  }
}

function centerBox(child, parent) {
  var h = document.getElementById(child).offsetHeight;
  var a = Math.round(parseInt(document.getElementById(parent).offsetHeight, 10) / 2);
  var b = Math.round(h / 2);
  var c = (a - b) + "px";
  document.getElementById(child).style.top = c;
  var w = document.getElementById(child).offsetWidth;
  var x = Math.round(parseInt(document.getElementById(parent).offsetWidth, 10) / 2);
  var y = Math.round(w / 2);
  var z = x - y;
  document.getElementById(child).style.left = z + "px";
}

function hideInfoBox() {
  document.getElementById("infoBox").style.display = "none";
}

function infoBox() {
  mapLoading = document.createElement('div');
  mapLoading.style.zIndex = 10;
  mapLoading.setAttribute('id', 'mapLoading');
  mapDiv.appendChild(mapLoading);
  centerBox("mapLoading", "map");
  if (infoHTML != "") {
    var infoBoxDiv = document.createElement('div');
    infoBoxDiv.setAttribute('id', 'infoBox');
    mapDiv.appendChild(infoBoxDiv);
    infoBoxDiv.innerHTML = infoHTML;
    infoBoxDiv.style.position = "absolute";
	infoBoxDiv.style.zIndex = "1";
    infoBoxDiv.style.top = (mapDiv.offsetHeight - infoBoxDiv.offsetHeight) + "px";
    var infoBoxClose = document.createElement('a');
    infoBoxClose.setAttribute('id', 'infoBoxClose');
    infoBoxDiv.appendChild(infoBoxClose);
    infoBoxClose.style.position = "absolute";
    infoBoxClose.style.top = "4px";
    infoBoxClose.style.left = "4px";
    infoBoxClose.onclick = function() { 
		hideInfoBox();
	};
  }
  var overlayDiv = document.createElement('div');
  overlayDiv.setAttribute('id', 'overlayControl');
  mapDiv.appendChild(overlayDiv);
  overlayDiv.style.position = "absolute";
  overlayDiv.style.zIndex = 2;
  
  var overlayHTML = "";
  if (searchControls === true) {
    overlayHTML = overlayHTML + '<form id="searchForm" action="#" onsubmit="findAddress(this.address.value); return false">';
    overlayHTML = overlayHTML + '<input id="searchTxt" type="text" size="20" name="address" value="Enter a City or Address" />';
    overlayHTML = overlayHTML + '<input id="searchButton" type="submit" value="Go" /> </form>';
  }
  overlayDiv.innerHTML = overlayHTML;
}

function createMarker(latlng, index, html, category, icon) {

    var myHtml;
	if ( icon === undefined ) {
      icon = category;
   }
  if (category == "pin") {

		if (markerGroups["pin"]) {

		for (var i = 0; i < markerGroups["pin"].length; i++) {
		  markerGroups["pin"][i].setMap(null);
		}
		markerGroups["pin"].length = 0;
		}

	  var image = new google.maps.MarkerImage(iconPath + category + ".png",
      new google.maps.Size(mainIconWidth, mainIconHeight),
      new google.maps.Point(0,0),
      new google.maps.Point(mainAnchorPointX, mainAnchorPointY));
	  
	  var shadow = new google.maps.MarkerImage( iconPath + category + "-shadow.png",
      new google.maps.Size(mainIconWidth, mainIconHeight),
      new google.maps.Point(0,0),
      new google.maps.Point(mainAnchorPointX, mainAnchorPointY));

	  var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        shadow: shadow,
        icon: image
    });
	  markerGroups["pin"].push(marker);
	  var infowindow = new google.maps.InfoWindow({
        content: html
    });
	  google.maps.event.addListener(marker, 'click', function() {
      infowindow.open(map,marker);
    });

  } else {
  if (icon == ""){ icon = category; }
  	  var image = new google.maps.MarkerImage(iconPath + icon + ".png",
      new google.maps.Size(iconWidth, iconHeight),
      new google.maps.Point(0,0),
      new google.maps.Point(anchorPointX, anchorPointY));
	  
	  var shadow = new google.maps.MarkerImage( iconPath + icon + "-shadow.png",
      new google.maps.Size(iconWidth, iconHeight),
      new google.maps.Point(0,0),
      new google.maps.Point(anchorPointX, anchorPointY));


}
  if (category == "xml") {


  } else {


	  var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        shadow: shadow,
        icon: image,
		title: category
    });
	  markerGroups[category].push(marker);
	  var infowindow = new google.maps.InfoWindow({
        content: html
    });
	  google.maps.event.addListener(marker, 'click', function() {   
	  if (lastInfoWindow) lastInfoWindow.close();
      infowindow.open(map,marker);
	  lastInfoWindow = infowindow;
    });
  }
}

function createHTML(title, url, address1, address2, website, phone, lat, lng) {
  var onClickSVCode = '"' + lat + '","' + lng + '","' + address1 + '","' + address2 + '"';
  var onClickDDCode = '"' + address1 + ' ' + address2 + '"';
  var finalHTML;
  finalHTML = '<div class="gs-localResult gs-result">';
  finalHTML = finalHTML + '<div class="gs-title"><a target="_blank" class="gs-title" href="' + url + '">' + title + '</a></div>';
  finalHTML = finalHTML + '<div class="gs-address">';
  finalHTML = finalHTML + '<div class="gs-street gs-addressLine">' + address1 + '</div>';
  if (address2 !== null) {
    finalHTML = finalHTML + '<div class="gs-city gs-addressLine">' + address2 + '</div>';
  }
  finalHTML = finalHTML + '</div>';
  finalHTML = finalHTML + '<div class="gs-phone">Phone: ' + phone + '</div>';
  finalHTML = finalHTML + "<div class='gs-streetview'><a class='gs-sv-link' onclick='showStreetView(" + onClickSVCode + ")' style='cursor: pointer'>Street View</a><a class='gs-dd-link' onclick='showDirections(" + onClickDDCode + ")' style='cursor: pointer'>Directions</a></div>";
  finalHTML = finalHTML + '</div>';
  return finalHTML;
}

function createXmlHTML(address, title, html, url, lat, lng) {
  var onClickSVCode = '"' + lat + '","' + lng + '","' + address + '"';
  var onClickDDCode = '"' + address + '"';
  var finalHTML;
  finalHTML = '<div class="gs-localResult gs-result">';
  finalHTML = finalHTML + '<div class="gs-title"><a target="_blank" class="gs-title" href="' + url + '">' + title + '</a></div>';
  finalHTML = finalHTML + '<div class="gs-customHTML">' + html;
  finalHTML = finalHTML + '</div>';
//  finalHTML = finalHTML + "<div class='gs-streetview'><a class='gs-sv-link' onclick='showStreetView(" + onClickSVCode + ")' style='cursor: pointer'>Street View</a></div>";
    finalHTML = finalHTML + "<div class='gs-streetview'><a class='gs-sv-link' onclick='showStreetView(" + onClickSVCode + ")' style='cursor: pointer'>Street View</a><a class='gs-dd-link' onclick='showDirections(" + onClickDDCode + ")' style='cursor: pointer'>Directions</a></div>";
  finalHTML = finalHTML + '</div>';
  return finalHTML;
}

function createXmlHttpRequest() {
 try {
   if (typeof ActiveXObject != 'undefined') {
     return new ActiveXObject('Microsoft.XMLHTTP');
   } else if (window["XMLHttpRequest"]) {
     return new XMLHttpRequest();
   }
 } catch (e) {
   changeStatus(e);
 }
 return null;
};

function downloadUrl(url, callback) {
 var status = -1;
 var request = createXmlHttpRequest();
 if (!request) {
   return false;
 }

 request.onreadystatechange = function() {
   if (request.readyState == 4) {
     try {
       status = request.status;
     } catch (e) {
       // Usually indicates request timed out in FF.
     }
     if (status == 200) {
       callback(request.responseXML, request.status);
       request.onreadystatechange = function() {};
     }
   }
 }
 request.open('GET', url, true);
 try {
   request.send(null);
 } catch (e) {
   changeStatus(e);
 }
};

function xmlParse(str) {
  if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
    var doc = new ActiveXObject('Microsoft.XMLDOM');
    doc.loadXML(str);
    return doc;
  }

  if (typeof DOMParser != 'undefined') {
    return (new DOMParser()).parseFromString(str, 'text/xml');
  }

  return createElement('div', null);
}

function downloadScript(url) {
  var script = document.createElement('script');
  script.src = url;
  document.body.appendChild(script);
}


/* To Do */
function doSearch(keyword, type) {
  currentCategory = type;
  var icon;
  
  		if (markerGroups[type]) {

		for (var i = 0; i < markerGroups[type].length; i++) {
		  markerGroups[type][i].setMap(null);
		}
		markerGroups[type].length = 0;
		}


  if (keyword.substr(0,3) == "db:"){ 
  var bounds = map.getBounds();
  var southWest = bounds.getSouthWest();
  var northEast = bounds.getNorthEast();
  var swLat = southWest.lat();
  var swLng = southWest.lng();
  var neLat = northEast.lat();
  var neLng = northEast.lng();
  var dbCat = keyword.substr(3);
  
  var filename = dbPath + "db.php?cat="+ dbCat + "&swLat="+ swLat + "&swLng="+ swLng + "&neLat="+ neLat + "&neLng="+ neLng + "&extendLat="+ extendLat + "&extendLng="+ extendLng;

	downloadUrl(filename, function (data) {
    var markers = data.documentElement.getElementsByTagName("marker");
    var hider = document.getElementById(type).getAttribute("caption");
    if (hider != "hidden") {
	if (markers.length !== 0) {

      for (var xmlItem = 0; xmlItem < markers.length; xmlItem++) {
		if (markers[xmlItem].getAttribute("icon") == "" ) {
				icon = type;
			} else {
				icon = markers[xmlItem].getAttribute("icon");
			}
        var xmlHTML = createXmlHTML(markers[xmlItem].getAttribute("address"), markers[xmlItem].getAttribute("title"), markers[xmlItem].getAttribute("html"), markers[xmlItem].getAttribute("url"), markers[xmlItem].getAttribute("lat"), markers[xmlItem].getAttribute("lng"));
		var latlng = new google.maps.LatLng(parseFloat(markers[xmlItem].getAttribute("lat")), parseFloat(markers[xmlItem].getAttribute("lng")));
		createMarker(latlng, xmlItem, xmlHTML, type, icon);
      }
    }
  }
      mapLoading.style.display = "none";
});
  
  } else {
	  
  var phoneNumber;
  var searchControl = new google.search.SearchControl();
  var localSearch = new google.search.LocalSearch();
  var options = new google.search.SearcherOptions();
  options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
  searchControl.addSearcher(localSearch, options);
  searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
  searchControl.draw(document.getElementById("searchcontrol"));
  searchControl.setSearchCompleteCallback(localSearch, function () {
    var resultcontent = '';
    var results = localSearch.results; // Grab the results array
    var hider = document.getElementById(type).getAttribute("caption");
    if (hider != "hidden") {
      if (results.length !== 0) {
        for (var i = 0; i < results.length; i++) {
          var result = results[i];
		    if (typeof result.phoneNumbers != 'undefined') {
				phoneNumber = result.phoneNumbers[0].number;
			  } else {
				phoneNumber = "";
			  }
          var latlng = new google.maps.LatLng(parseFloat(result.lat), parseFloat(result.lng));
          var resultHTML = createHTML(result.titleNoFormatting, result.url, result.addressLines[0], result.addressLines[1], result.visibleUrl, phoneNumber, result.lat, result.lng);

          createMarker(latlng, i, resultHTML, type);
          if (hider == "hidden") {
            markerGroups[type][i].hide();
          }
        }
      }
    }
    mapLoading.style.display = "none";
  });
  if (addressSet != 1) {
    localSearch.setCenterPoint(startAddress);
  } else {
    localSearch.setCenterPoint(map.getCenter());
  }
  searchControl.execute(keyword);
  }
  return 1;
}

function hasClass(ele, cls) {
  return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}

function addClass(ele, cls) {
  if (!this.hasClass(ele, cls)) {
	  ele.className += " " + cls;
  }
}

function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
    ele.className = ele.className.replace(reg, ' ');
  }
}

function toggleGroup(type) {
  classAdder = document.getElementById(type);
  if (markerGroups[type].length !== 0) {
    for (var i = 0; i < markerGroups[type].length; i++) {
      var marker = markerGroups[type][i];
      if (marker.getVisible() === false) {
        classAdder.attributes.getNamedItem("caption").value = "";
        addClass(classAdder, "visibleLayer");
        marker.setVisible(true);
      } else {
        classAdder.attributes.getNamedItem("caption").value = "hidden";
        removeClass(classAdder, "visibleLayer");
        marker.setVisible(false);
      }
    }
  } else {
    mapLoading.style.display = "block";
    doSearch(classAdder.attributes.getNamedItem("title").value, type);
    classAdder.attributes.getNamedItem("caption").value = "";
    addClass(classAdder, "visibleLayer");
  }
}

function handleDDErrors() {
  var ddError = "<h4>Unable to retreive driving directions to this location.</h4><a onclick='closeDirections();' style='text-decoration: underline; cursor: pointer; color: blue'>close</a>";
  var ddErrorDiv = document.createElement('div');
  ddErrorDiv.setAttribute('id', 'ddError');
  ddBoxDiv.appendChild(ddErrorDiv);
  ddErrorDiv.innerHTML = ddError;
  ddErrorDiv.style.width = "50%";
  ddErrorDiv.style.marginLeft = "10%";
}


function closeDirections() {
  mapDiv.removeChild(document.getElementById("ddFrame"));
}

function showDirections(toAddress) {
  var ddFrame = document.createElement('div');
  ddFrame.setAttribute('id', 'ddFrame');
  mapDiv.appendChild(ddFrame);
  centerBox("ddFrame", "map");
  ddBoxDiv = document.createElement('div');
  ddBoxDiv.setAttribute('id', 'ddBox');
  ddFrame.appendChild(ddBoxDiv);
  ddBoxDiv.style.position = "absolute";
  ddBoxDiv.style.left = "5px";
  var ddBoxClose = document.createElement('a');
  ddBoxClose.setAttribute('id', 'ddBoxClose');
  ddFrame.appendChild(ddBoxClose);
  ddBoxClose.style.position = "absolute";
  ddBoxClose.style.zIndex = "10";
  ddBoxClose.style.top = "0px";
  ddBoxClose.style.left = (ddFrame.offsetWidth - ddBoxClose.offsetWidth - 4) + "px";
  ddBoxClose.onclick = function() { 
    closeDirections();
  };
  var ddBoxPrint = document.createElement('a');
  ddBoxPrint.setAttribute('id', 'ddBoxPrint');
  ddFrame.appendChild(ddBoxPrint);
  ddBoxPrint.innerHTML = "<span>Print</span>";
  ddBoxPrint.style.position = "absolute";
  ddBoxPrint.style.zIndex = "10";
  ddBoxPrint.style.top = "4px";
  ddBoxPrint.style.left = (ddFrame.offsetWidth - ddBoxClose.offsetWidth - 29) + "px";
  ddBoxPrint.setAttribute("href", "print/print.html?start=" + escape(startAddress) + "&end=" + escape(toAddress));
  ddBoxPrint.setAttribute("target", "_blank");
  
  directionsService = new google.maps.DirectionsService();
  directionsDisplay = new google.maps.DirectionsRenderer();
  directionsDisplay.setMap(map);
  directionsDisplay.setPanel(ddBoxDiv);
  var travMode;
  var loadStr = "from: " + startAddress + " to: " + toAddress;
  if (directionsMode == 'DRIVING') {
	  travMode = google.maps.DirectionsTravelMode.DRIVING;
  } else {
	  travMode = google.maps.DirectionsTravelMode.WALKING;  }

    var request = {
        origin: startAddress, 
        destination: toAddress,
        travelMode: travMode
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
		return false;
      } else {
		handleDDErrors();  
		return false;
	  }
    });


}

function closeStreetView() {
  mapDiv.removeChild(document.getElementById("svFrame"));
}

function showStreetView(lat, lng, address1, address2) {
  var svFrame = document.createElement('div');
  svFrame.setAttribute('id', 'svFrame');
  mapDiv.appendChild(svFrame);
  centerBox("svFrame", "map");
  var svBoxDiv = document.createElement('div');
  svBoxDiv.setAttribute('id', 'svBox');
  svFrame.appendChild(svBoxDiv);
  svBoxDiv.style.position = "absolute";
  var svBoxClose = document.createElement('a');
  svBoxClose.setAttribute('id', 'svBoxClose');
  svFrame.appendChild(svBoxClose);
  svBoxClose.style.position = "absolute";
  svBoxClose.style.zIndex = "10";
  svBoxClose.style.top = "0px";
  svBoxClose.style.left = (svFrame.offsetWidth - svBoxClose.offsetWidth - 5) + "px";
  svBoxClose.onclick = function() { 
    closeStreetView();
  };
  var svLatLng = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
	var panoramaOptions = {
		position: svLatLng
	};
	var panorama = new  google.maps.StreetViewPanorama(document.getElementById("svBox"), panoramaOptions);
	map.setStreetView(panorama);
}


function toggleOverlay(layerState, layer, control) {
  if (overlayControls === true) {	
	  var toggleControl = document.getElementById(control);
	  if (layerState == "off") {
		if (layer.isHidden() === true) {
		  layer.show();
		} else {
		  map.addOverlay(layer);
		}
		toggleControl.style.backgroundColor = "#fc9";
		toggleControl.onclick = function() { toggleOverlay('on', layer , control );};
	  }
	  if (layerState == "on") {
		layer.hide();
		toggleControl.style.backgroundColor = "#fff";
		toggleControl.onclick = function() { toggleOverlay('off', layer , control );};
	  }
  }
}


function getCategories(initial) {
  var i;
  mapLoading.style.display = "block";
  var elem = document.getElementById(categoriesList);
  for (i = 0; i < elem.childNodes.length; i++) {
    if (elem.childNodes[i].nodeName == "LI") {
		var catType = elem.childNodes[i].attributes.getNamedItem("id").value;
		
      result = doSearch(elem.childNodes[i].attributes.getNamedItem("title").value, elem.childNodes[i].attributes.getNamedItem("id").value);
    }
  }
  if (initial == 1) {
  jsonGroups = "";
  jsonGroups = '{ xml: [], "pin": [] ';
  for (i = 0; i < elem.childNodes.length; i++) {
    if (elem.childNodes[i].nodeName == "LI") {
      jsonGroups = jsonGroups + ',  "' + elem.childNodes[i].attributes.getNamedItem("id").value + '": [] ';
    }
  }
  jsonGroups = jsonGroups + "}";
  markerGroups = eval('(' + jsonGroups + ')');

for (i = 0; i < elem.childNodes.length; i++) {
      if (elem.childNodes[i].nodeName == "LI") {
        var elemID = elem.childNodes[i].attributes.getNamedItem("id").value;
        if (elemID != "user") {
          elem.childNodes[i].innerHTML = "<a onclick='" + 'toggleGroup("' + elemID + '")' + "'>" + elem.childNodes[i].innerHTML + "</a>";
        } else {
          elem.childNodes[i].innerHTML = '<form id="userPOIForm" action="#" onsubmit="userPOIFind(this.userPOI.value); return false"><input id="userPOITxt" size="20" name="userPOI" value="' + elem.childNodes[i].innerHTML + '" type="text"><input id="userPOIButton" value="Go" type="submit"> </form>';

        }
        if (hasClass(elem.childNodes[i], "hidden") !== null) {
          elem.childNodes[i].setAttribute("caption", "hidden");
        } else {
          elem.childNodes[i].setAttribute("caption", "");
        }
        if (elem.childNodes[i].attributes.getNamedItem("caption").value != "hidden") {
          classAdder = document.getElementById(elemID);
          addClass(classAdder, "visibleLayer");
        }
      }
    }
  }
  if (typeof xmlFile === 'undefined') {
    // Do Nothing for now
  } else {
    addXML(xmlFile);
  }
}


function userPOIFind(searchText) {
  document.getElementById("user").setAttribute("title", searchText);
  getCategories(0);
}

function findAddress(address, HTML) {
  if (HTML === undefined) {
    HTML = "<strong>" + address + "</strong>";
  }
  markerHTML = HTML;
  
  	var geocoder = new google.maps.Geocoder();
    geocoder.geocode( { 'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        map.setCenter(results[0].geometry.location);
   		addressSet = 1;
		startAddress = address;
		searchCenter = results[0].geometry.location;
		createMarker(searchCenter, 0, markerHTML, "pin");
		var trafficLayer = new google.maps.TrafficLayer();
		trafficLayer.setMap(map);
		    getCategories(0);
		if (mapExtra === true) {
			mapPost();
		}

	} else {
        alert("Geocode was not successful for the following reason: " + status);
      }
    });
	
}


function OnLoad() {
	setupAddress();
	mapDiv = document.getElementById(mapDivID);
	var myLatlng = new google.maps.LatLng(0,0);
	var myOptions = {
		zoom: zoomLevel,
		scrollwheel: false,
		disableDoubleClickZoom: true,
		center: myLatlng,
		mapTypeControl: true,
		mapTypeControlOptions: {
		  style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
		},
		zoomControl: true,
		zoomControlOptions: {
		  style: google.maps.ZoomControlStyle.SMALL
		},
		panControl: false,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	}
	map = new google.maps.Map(mapDiv, myOptions);

	infoBox();

	var geocoder = new google.maps.Geocoder();
    var address = startAddress;
    geocoder.geocode( { 'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        map.setCenter(results[0].geometry.location);
   		addressSet = 1;
		searchCenter = results[0].geometry.location;
        getCategories(1);
		createMarker(searchCenter, 0, markerHTML, "pin");
		var trafficLayer = new google.maps.TrafficLayer();
		trafficLayer.setMap(map);
	    google.maps.event.addListener(map, "dragend", function () {
			       getCategories(0);
	    });
		if (mapExtra === true) {
			mapPost();
		}
		} else {
        alert("Geocode was not successful for the following reason: " + status);
      }
    });

}


google.setOnLoadCallback(OnLoad);DateInput = (function($) { // Localise the $ function

function DateInput(el, opts) {
  if (typeof(opts) != "object") opts = {};
  $.extend(this, DateInput.DEFAULT_OPTS, opts);
  
  this.input = $(el);
  this.bindMethodsToObj("show", "hide", "hideIfClickOutside", "keydownHandler", "selectDate");
  
  this.build();
  this.selectDate();
  this.hide();
};
DateInput.DEFAULT_OPTS = {
  month_names: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
  short_month_names: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
  short_day_names: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  start_of_week: 1
};
DateInput.prototype = {
  build: function() {
    var monthNav = $('<p class="month_nav">' +
      '<span class="button prev" title="[Page-Up]">&#171;</span>' +
      ' <span class="month_name"></span> ' +
      '<span class="button next" title="[Page-Down]">&#187;</span>' +
      '</p>');
    this.monthNameSpan = $(".month_name", monthNav);
    $(".prev", monthNav).click(this.bindToObj(function() { this.moveMonthBy(-1); }));
    $(".next", monthNav).click(this.bindToObj(function() { this.moveMonthBy(1); }));
    
    var yearNav = $('<p class="year_nav">' +
      '<span class="button prev" title="[Ctrl+Page-Up]">&#171;</span>' +
      ' <span class="year_name"></span> ' +
      '<span class="button next" title="[Ctrl+Page-Down]">&#187;</span>' +
      '</p>');
    this.yearNameSpan = $(".year_name", yearNav);
    $(".prev", yearNav).click(this.bindToObj(function() { this.moveMonthBy(-12); }));
    $(".next", yearNav).click(this.bindToObj(function() { this.moveMonthBy(12); }));
    
    var nav = $('<div class="nav"></div>').append(monthNav, yearNav);
    
    var tableShell = "<table><thead><tr>";
    $(this.adjustDays(this.short_day_names)).each(function() {
      tableShell += "<th>" + this + "</th>";
    });
    tableShell += "</tr></thead><tbody></tbody></table>";
    
    this.dateSelector = this.rootLayers = $('<div class="date_selector"></div>').append(nav, tableShell).insertAfter(this.input);
    
    if ($.browser.msie && $.browser.version < 7) {
      // The ieframe is a hack which works around an IE <= 6 bug where absolutely positioned elements
      // appear behind select boxes. Putting an iframe over the top of the select box prevents this.
      this.ieframe = $('<iframe class="date_selector_ieframe" frameborder="0" src="#"></iframe>').insertBefore(this.dateSelector);
      this.rootLayers = this.rootLayers.add(this.ieframe);
      
      // IE 6 only does :hover on A elements
      $(".button", nav).mouseover(function() { $(this).addClass("hover") });
      $(".button", nav).mouseout(function() { $(this).removeClass("hover") });
    };
    
    this.tbody = $("tbody", this.dateSelector);
    
    this.input.change(this.bindToObj(function() { this.selectDate(); }));
    this.selectDate();
  },

  selectMonth: function(date) {
    var newMonth = new Date(date.getFullYear(), date.getMonth(), 1);
    
    if (!this.currentMonth || !(this.currentMonth.getFullYear() == newMonth.getFullYear() &&
                                this.currentMonth.getMonth() == newMonth.getMonth())) {
      // We have moved to a different month and so need to re-draw the table
      this.currentMonth = newMonth;
      
      // Work out the range of days we will draw
      var rangeStart = this.rangeStart(date), rangeEnd = this.rangeEnd(date);
      var numDays = this.daysBetween(rangeStart, rangeEnd);
      var dayCells = "";
      
      // Draw each of the days
      for (var i = 0; i <= numDays; i++) {
        var currentDay = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate() + i, 12, 00);
        
        if (this.isFirstDayOfWeek(currentDay)) dayCells += "<tr>";
        
        if (currentDay.getMonth() == date.getMonth()) {
          dayCells += '<td class="selectable_day" date="' + this.dateToString(currentDay) + '">' + currentDay.getDate() + '</td>';
        } else {
          dayCells += '<td class="unselected_month" date="' + this.dateToString(currentDay) + '">' + currentDay.getDate() + '</td>';
        };
        
        if (this.isLastDayOfWeek(currentDay)) dayCells += "</tr>";
      };
      this.tbody.empty().append(dayCells);
      
      // Write the month and year in the header
      this.monthNameSpan.empty().append(this.monthName(date));
      this.yearNameSpan.empty().append(this.currentMonth.getFullYear());
      
      $(".selectable_day", this.tbody).click(this.bindToObj(function(event) {
        this.changeInput($(event.target).attr("date"));
      }));
      
      $("td[date=" + this.dateToString(new Date()) + "]", this.tbody).addClass("today");
      
      $("td.selectable_day", this.tbody).mouseover(function() { $(this).addClass("hover") });
      $("td.selectable_day", this.tbody).mouseout(function() { $(this).removeClass("hover") });
    };
    
    $('.selected', this.tbody).removeClass("selected");
    $('td[date=' + this.selectedDateString + ']', this.tbody).addClass("selected");
  },
  
  // Select a particular date. If the date is not specified it is read from the input. If no date is
  // found then the current date is selected. The selectMonth() function is responsible for actually
  // selecting a particular date.
  selectDate: function(date) {
    if (typeof(date) == "undefined") {
      date = this.stringToDate(this.input.val());
    };
    if (!date) date = new Date();
    
    this.selectedDate = date;
    this.selectedDateString = this.dateToString(this.selectedDate);
    this.selectMonth(this.selectedDate);
  },
  
  // Write a date string to the input and hide. Trigger the change event so we know to update the
  // selectedDate.
  changeInput: function(dateString) {
    this.input.val(dateString).change();
    this.hide();
  },
  
  show: function() {
    this.rootLayers.css("display", "block");
    $([window, document.body]).click(this.hideIfClickOutside);
    this.input.unbind("focus", this.show);
    $(document.body).keydown(this.keydownHandler);
    this.setPosition();
  },
  
  hide: function() {
    this.rootLayers.css("display", "none");
    $([window, document.body]).unbind("click", this.hideIfClickOutside);
    this.input.focus(this.show);
    $(document.body).unbind("keydown", this.keydownHandler);
  },
  
  // We should hide the date selector if a click event happens outside of it
  hideIfClickOutside: function(event) {
    if (event.target != this.input[0] && !this.insideSelector(event)) {
      this.hide();
    };
  },
  
  // Returns true if the given event occurred inside the date selector
  insideSelector: function(event) {
    var offset = this.dateSelector.position();
    offset.right = offset.left + this.dateSelector.outerWidth();
    offset.bottom = offset.top + this.dateSelector.outerHeight();
    
    return event.pageY < offset.bottom &&
           event.pageY > offset.top &&
           event.pageX < offset.right &&
           event.pageX > offset.left;
  },
  
  // Respond to various different keyboard events
  keydownHandler: function(event) {
    switch (event.keyCode)
    {
      case 9: // tab
      case 27: // esc
        this.hide();
        return;
      break;
      case 13: // enter
        this.changeInput(this.selectedDateString);
      break;
      case 33: // page up
        this.moveDateMonthBy(event.ctrlKey ? -12 : -1);
      break;
      case 34: // page down
        this.moveDateMonthBy(event.ctrlKey ? 12 : 1);
      break;
      case 38: // up
        this.moveDateBy(-7);
      break;
      case 40: // down
        this.moveDateBy(7);
      break;
      case 37: // left
        this.moveDateBy(-1);
      break;
      case 39: // right
        this.moveDateBy(1);
      break;
      default:
        return;
    }
    event.preventDefault();
  },
  
  stringToDate: function(string) {
    var matches;
    if (matches = string.match(/^(\d{1,2}) ([^\s]+) (\d{4,4})$/)) {
      return new Date(matches[3], this.shortMonthNum(matches[2]), matches[1], 12, 00);
    } else {
      return null;
    };
  },
  
  dateToString: function(date) {
    return date.getDate() + " " + this.short_month_names[date.getMonth()] + " " + date.getFullYear();
  },
  
  setPosition: function() {
    var offset = this.input.offset();
    this.rootLayers.css({
      top: offset.top + this.input.outerHeight(),
      left: offset.left
    });
    
    if (this.ieframe) {
      this.ieframe.css({
        width: this.dateSelector.outerWidth(),
        height: this.dateSelector.outerHeight()
      });
    };
  },
  
  // Move the currently selected date by a particular number of days
  moveDateBy: function(amount) {
    var newDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth(), this.selectedDate.getDate() + amount);
    this.selectDate(newDate);
  },
  
  // Move the month of the currently selected date by a particular number of months. If we are moving
  // to a month which does not have enough days to represent the current day-of-month, then we 
  // default to the last day of the month.
  moveDateMonthBy: function(amount) {
    var newDate = new Date(this.selectedDate.getFullYear(), this.selectedDate.getMonth() + amount, this.selectedDate.getDate());
    if (newDate.getMonth() == this.selectedDate.getMonth() + amount + 1) {
      // We have moved too far. For instance 31st March + 1 month = 1st May, not 30th April
      newDate.setDate(0);
    };
    this.selectDate(newDate);
  },
  
  // Move the currently displayed month by a certain amount. This does *not* move the currently
  // selected date, so we end up viewing a month with no visibly selected date.
  moveMonthBy: function(amount) {
    var newMonth = new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() + amount, this.currentMonth.getDate());
    this.selectMonth(newMonth);
  },
  
  monthName: function(date) {
    return this.month_names[date.getMonth()];
  },
  
  // A hack to make "this" refer to this object instance when inside the given function
  bindToObj: function(fn) {
    var self = this;
    return function() { return fn.apply(self, arguments) };
  },
  
  // See above
  bindMethodsToObj: function() {
    for (var i = 0; i < arguments.length; i++) {
      this[arguments[i]] = this.bindToObj(this[arguments[i]]);
    };
  },
  
  // Finds out the array index of a particular value in that array
  indexFor: function(array, value) {
    for (var i = 0; i < array.length; i++) {
      if (value == array[i]) return i;
    };
  },
  
  // Finds the number of a given month name
  monthNum: function(month_name) {
    return this.indexFor(this.month_names, month_name);
  },
  
  // Finds the number of a given short month name
  shortMonthNum: function(month_name) {
    return this.indexFor(this.short_month_names, month_name);
  },
  
  // Finds the number of a given day name
  shortDayNum: function(day_name) {
    return this.indexFor(this.short_day_names, day_name);
  },
  
  // Works out the number of days between two dates
  daysBetween: function(start, end) {
    start = Date.UTC(start.getFullYear(), start.getMonth(), start.getDate());
    end = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
    return (end - start) / 86400000;
  },
  
  /*
  changeDayTo: Given a date, move along the date line in the given direction until we reach the
  desired day of week.
  
  The maths is a bit complex, here's an explanation.
  
  Think of a continuous repeating number line like:
  
  .. 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 ..
  
  We are essentially trying to find the difference between two numbers
  on the line in one direction (dictated by the sign of direction variable).
  Unfortunately Javascript's modulo operator works such that -5 % 7 = -5,
  instead of -5 % 7 = 2, so we need to only work with the positives.
  
  To find the difference between 1 and 4, going backwards, we can treat 1
  as (1 + 7) = 8, so the different is |8 - 4| = 4. If we don't cross the 
  boundary between 0 and 6, for instance to find the backwards difference
  between 5 and 2, |(5 + 7) - 2| = |12 - 2| = 10. And 10 % 7 = 3.
  
  Going forwards, to find the difference between 4 and 1, we again treat 1
  as (1 + 7) = 8, and the difference is |4 - 8| = 4. If we don't cross the
  boundary, the difference between 2 and 5 is |2 - (5 + 7)| = |2 - 12| = 10.
  And 10 % 7 = 3.
  
  Once we have the positive difference in either direction represented as a
  absolute value, we can multiply it by the direction variable to get the difference
  in the desired direction.
  
  We can condense the two methods into a single equation:
  
    backwardsDifference = direction * (|(currentDayNum + 7) - dayOfWeek| % 7)
                        = direction * (|currentDayNum - dayOfWeek + 7|  % 7)
    
     forwardsDifference = direction * (|currentDayNum - (dayOfWeek + 7)| % 7)
                        = direction * (|currentDayNum - dayOfWeek - 7| % 7)
    
    (The two equations now differ only by the +/- 7)
    
             difference = direction * (|currentDayNum - dayOfWeek - (direction * 7)| % 7)
  */
  changeDayTo: function(dayOfWeek, date, direction) {
    var difference = direction * (Math.abs(date.getDay() - dayOfWeek - (direction * 7)) % 7);
    return new Date(date.getFullYear(), date.getMonth(), date.getDate() + difference);
  },
  
  // Given a date, return the day at the start of the week *before* this month
  rangeStart: function(date) {
    return this.changeDayTo(this.start_of_week, new Date(date.getFullYear(), date.getMonth()), -1);
  },
  
  // Given a date, return the day at the end of the week *after* this month
  rangeEnd: function(date) {
    return this.changeDayTo((this.start_of_week - 1) % 7, new Date(date.getFullYear(), date.getMonth() + 1, 0), 1);
  },
  
  // Is the given date the first day of the week?
  isFirstDayOfWeek: function(date) {
    return date.getDay() == this.start_of_week;
  },
  
  // Is the given date the last day of the week?
  isLastDayOfWeek: function(date) {
    return date.getDay() == (this.start_of_week - 1) % 7;
  },
  
  // Adjust a given array of day names to begin with the configured start-of-week
  adjustDays: function(days) {
    var newDays = [];
    for (var i = 0; i < days.length; i++) {
      newDays[i] = days[(i + this.start_of_week) % 7];
    };
    return newDays;
  }
};

$.fn.date_input = function(opts) {
  return this.each(function() { new DateInput(this, opts); });
};
$.date_input = { initialize: function(opts) {
  $("input.date_input").date_input(opts);
} };

return DateInput;
})(jQuery); // End localisation of the $ function



/************************ alert js ******************************/

// jQuery Alert Dialogs Plugin
//
// Version 1.1
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 14 May 2009
//
// Visit http://abeautifulsite.net/notebook/87 for more information
//
// Usage:
//		jAlert( message, [title, callback] )
//		jConfirm( message, [title, callback] )
//		jPrompt( message, [value, title, callback] )
// 
// History:
//
//		1.00 - Released (29 December 2008)
//
//		1.01 - Fixed bug where unbinding would destroy all resize events
//
// License:
// 
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC. 
//
(function($) {
	
	$.alerts = {
		
		// These properties can be read/written by accessing $.alerts.propertyName from your scripts at any time
		
		verticalOffset: -75,                // vertical offset of the dialog from center screen, in pixels
		horizontalOffset: 0,                // horizontal offset of the dialog from center screen, in pixels/
		repositionOnResize: true,           // re-centers the dialog on window resize
		overlayOpacity: .01,                // transparency level of overlay
		overlayColor: '#FFF',               // base color of overlay
		draggable: true,                    // make the dialogs draggable (requires UI Draggables plugin)
		okButton: '&nbsp;OK&nbsp;',         // text for the OK button
		cancelButton: '&nbsp;Cancel&nbsp;', // text for the Cancel button
		dialogClass: null,                  // if specified, this class will be applied to all dialogs
		
		// Public methods
		
		alert: function(message, title, callback) {
			if( title == null ) title = 'Alert';
			$.alerts._show(title, message, null, 'alert', function(result) {
				if( callback ) callback(result);
			});
		},
		
		confirm: function(message, title, callback) {
			if( title == null ) title = 'Confirm';
			$.alerts._show(title, message, null, 'confirm', function(result) {
				if( callback ) callback(result);
			});
		},
			
		prompt: function(message, value, title, callback) {
			if( title == null ) title = 'Prompt';
			$.alerts._show(title, message, value, 'prompt', function(result) {
				if( callback ) callback(result);
			});
		},
		
		// Private methods
		
		_show: function(title, msg, value, type, callback) {
			
			$.alerts._hide();
			$.alerts._overlay('show');
			
			$("BODY").append(
			  '<div id="popup_container">' +
			    '<h1 id="popup_title"></h1>' +
			    '<div id="popup_content">' +
			      '<div id="popup_message"></div>' +
				'</div>' +
			  '</div>');
			
			if( $.alerts.dialogClass ) $("#popup_container").addClass($.alerts.dialogClass);
			
			// IE6 Fix
			var pos = ($.browser.msie && parseInt($.browser.version) <= 6 ) ? 'absolute' : 'fixed'; 
			
			$("#popup_container").css({
				position: pos,
				zIndex: 99999,
				padding: 0,
				margin: 0
			});
			
			$("#popup_title").text(title);
			$("#popup_content").addClass(type);
			$("#popup_message").text(msg);
			$("#popup_message").html( $("#popup_message").text().replace(/\n/g, '<br />') );
			
			$("#popup_container").css({
				minWidth: 300,
				maxWidth: 300
			});
			
			$.alerts._reposition();
			$.alerts._maintainPosition(true);
			
			switch( type ) {
				case 'alert':
					$("#popup_message").after('<div id="popup_panel"><input type="button" class="button red light" value="' + $.alerts.okButton + '" id="popup_ok" /></div>');
					$("#popup_ok").click( function() {
						$.alerts._hide();
						callback(true);
					});
					$("#popup_ok").focus().keypress( function(e) {
						if( e.keyCode == 13 || e.keyCode == 27 ) $("#popup_ok").trigger('click');
					});
				break;
				case 'confirm':
					$("#popup_message").after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /> <input type="button" value="' + $.alerts.cancelButton + '" id="popup_cancel" /></div>');
					$("#popup_ok").click( function() {
						$.alerts._hide();
						if( callback ) callback(true);
					});
					$("#popup_cancel").click( function() {
						$.alerts._hide();
						if( callback ) callback(false);
					});
					$("#popup_ok").focus();
					$("#popup_ok, #popup_cancel").keypress( function(e) {
						if( e.keyCode == 13 ) $("#popup_ok").trigger('click');
						if( e.keyCode == 27 ) $("#popup_cancel").trigger('click');
					});
				break;
				case 'prompt':
					$("#popup_message").append('<br /><input type="text" size="30" id="popup_prompt" />').after('<div id="popup_panel"><input type="button" value="' + $.alerts.okButton + '" id="popup_ok" /> <input type="button" value="' + $.alerts.cancelButton + '" id="popup_cancel" /></div>');
					$("#popup_prompt").width( $("#popup_message").width() );
					$("#popup_ok").click( function() {
						var val = $("#popup_prompt").val();
						$.alerts._hide();
						if( callback ) callback( val );
					});
					$("#popup_cancel").click( function() {
						$.alerts._hide();
						if( callback ) callback( null );
					});
					$("#popup_prompt, #popup_ok, #popup_cancel").keypress( function(e) {
						if( e.keyCode == 13 ) $("#popup_ok").trigger('click');
						if( e.keyCode == 27 ) $("#popup_cancel").trigger('click');
					});
					if( value ) $("#popup_prompt").val(value);
					$("#popup_prompt").focus().select();
				break;
			}
			
			// Make draggable
			if( $.alerts.draggable ) {
				try {
					$("#popup_container").draggable({ handle: $("#popup_title") });
					$("#popup_title").css({ cursor: 'move' });
				} catch(e) { /* requires jQuery UI draggables */ }
			}
		},
		
		_hide: function() {
			$("#popup_container").remove();
			$.alerts._overlay('hide');
			$.alerts._maintainPosition(false);
		},
		
		_overlay: function(status) {
			switch( status ) {
				case 'show':
					$.alerts._overlay('hide');
					$("BODY").append('<div id="popup_overlay"></div>');
					$("#popup_overlay").css({
						position: 'absolute',
						zIndex: 99998,
						top: '0px',
						left: '0px',
						width: '100%',
						height: $(document).height(),
						background: $.alerts.overlayColor,
						opacity: $.alerts.overlayOpacity
					});
				break;
				case 'hide':
					$("#popup_overlay").remove();
				break;
			}
		},
		
		_reposition: function() {
			var top = (($(window).height() / 2) - ($("#popup_container").outerHeight() / 2)) + $.alerts.verticalOffset;
			var left = (($(window).width() / 2) - ($("#popup_container").outerWidth() / 2)) + $.alerts.horizontalOffset;
			if( top < 0 ) top = 0;
			if( left < 0 ) left = 0;
			
			// IE6 fix
			if( $.browser.msie && parseInt($.browser.version) <= 6 ) top = top + $(window).scrollTop();
			
			$("#popup_container").css({
				top: top + 'px',
				left: left + 'px'
			});
			$("#popup_overlay").height( $(document).height() );
		},
		
		_maintainPosition: function(status) {
			if( $.alerts.repositionOnResize ) {
				switch(status) {
					case true:
						$(window).bind('resize', $.alerts._reposition);
					break;
					case false:
						$(window).unbind('resize', $.alerts._reposition);
					break;
				}
			}
		}
		
	}
	
	// Shortuct functions
	jAlert = function(message, title, callback) {
		$.alerts.alert(message, title, callback);
	}
	
	jConfirm = function(message, title, callback) {
		$.alerts.confirm(message, title, callback);
	};
		
	jPrompt = function(message, value, title, callback) {
		$.alerts.prompt(message, value, title, callback);
	};
	
})(jQuery);




/************************ validation js ******************************/




/*
    -------------------------------------------------------------------------
    JavaScript Form Validator (gen_validatorv4.js)
    Version 4.0
    Copyright (C) 2003-2011 JavaScript-Coder.com. All rights reserved.
    You can freely use this script in your Web pages.
    You may adapt this script for your own needs, provided these opening credit
    lines are kept intact.
        
    The Form validation script is distributed free from JavaScript-Coder.com
    For updates, please visit:
    http://www.javascript-coder.com/html-form/javascript-form-validation.phtml

    Questions & comments please send to form.val (at) javascript-coder.com
    -------------------------------------------------------------------------  
*/

function Validator(frmname)
{
    this.validate_on_killfocus = false;
    this.formobj = document.forms[frmname];
    if (!this.formobj)
    {
        alert("Error: couldnot get Form object " + frmname);
        return;
    }
    if (this.formobj.onsubmit)
    {
        this.formobj.old_onsubmit = this.formobj.onsubmit;
        this.formobj.onsubmit = null;
    }
    else
    {
        this.formobj.old_onsubmit = null;
    }
    this.formobj._sfm_form_name = frmname;

    this.formobj.onsubmit = form_submit_handler;
    this.addValidation = add_validation;

    this.formobj.addnlvalidations = new Array();
    this.addAddnlValidationFunction = add_addnl_vfunction;
    this.formobj.runAddnlValidations = run_addnl_validations;
    this.setAddnlValidationFunction = set_addnl_vfunction;//for backward compatibility


    this.clearAllValidations = clear_all_validations;
    this.focus_disable_validations = false;

    document.error_disp_handler = new sfm_ErrorDisplayHandler();

    this.EnableOnPageErrorDisplay = validator_enable_OPED;
    this.EnableOnPageErrorDisplaySingleBox = validator_enable_OPED_SB;

    this.show_errors_together = false;
    this.EnableMsgsTogether = sfm_enable_show_msgs_together;
    document.set_focus_onerror = true;
    this.EnableFocusOnError = sfm_validator_enable_focus;

    this.formobj.error_display_loc = 'right';
    this.SetMessageDisplayPos = sfm_validator_message_disp_pos;

    this.formobj.DisableValidations = sfm_disable_validations;
    this.formobj.validatorobj = this;
}


function sfm_validator_enable_focus(enable)
{
    document.set_focus_onerror = enable;
}

function add_addnl_vfunction()
{
    var proc =
    {
    };
    proc.func = arguments[0];
    proc.arguments = [];

    for (var i = 1; i < arguments.length; i++)
    {
        proc.arguments.push(arguments[i]);
    }
    this.formobj.addnlvalidations.push(proc);
}

function set_addnl_vfunction(functionname)
{
    if(functionname.constructor == String)
    {
        alert("Pass the function name like this: validator.setAddnlValidationFunction(DoCustomValidation)\n "+
            "rather than passing the function name as string");
        return;
    }
    this.addAddnlValidationFunction(functionname);
}

function run_addnl_validations()
{
    var ret = true;
    for (var f = 0; f < this.addnlvalidations.length; f++)
    {
        var proc = this.addnlvalidations[f];
        var args = proc.arguments || [];
        if (!proc.func.apply(null, args))
        {
            ret = false;
        }
    }
    return ret;
}

function sfm_set_focus(objInput)
{
    if (document.set_focus_onerror)
    {
        if (!objInput.disabled && objInput.type != 'hidden')
        {
            objInput.focus();
        }
    }
}

function sfm_disable_validations()
{
    if (this.old_onsubmit)
    {
        this.onsubmit = this.old_onsubmit;
    }
    else
    {
        this.onsubmit = null;
    }
}

function sfm_enable_show_msgs_together()
{
    this.show_errors_together = true;
    this.formobj.show_errors_together = true;
}

function sfm_validator_message_disp_pos(pos)
{
    this.formobj.error_display_loc = pos;
}

function clear_all_validations()
{
    for (var itr = 0; itr < this.formobj.elements.length; itr++)
    {
        this.formobj.elements[itr].validationset = null;
    }
}

function form_submit_handler()
{
    var bRet = true;
    document.error_disp_handler.clear_msgs();
    for (var itr = 0; itr < this.elements.length; itr++)
    {
        if (this.elements[itr].validationset && !this.elements[itr].validationset.validate())
        {
            bRet = false;
        }
        if (!bRet && !this.show_errors_together)
        {
            break;
        }
    }

    if (this.show_errors_together || bRet && !this.show_errors_together)
    {
        if (!this.runAddnlValidations())
        {
            bRet = false;
        }
    }
    if (!bRet)
    {
        document.error_disp_handler.FinalShowMsg();
        return false;
    }
    return true;
}

function add_validation(itemname, descriptor, errstr)
{
    var condition = null;
    if (arguments.length > 3)
    {
        condition = arguments[3];
    }
    if (!this.formobj)
    {
        alert("Error: The form object is not set properly");
        return;
    } //if
    var itemobj = this.formobj[itemname];

    if (itemobj.length && isNaN(itemobj.selectedIndex))
    //for radio button; don't do for 'select' item
    {
        itemobj = itemobj[0];
    }
    if (!itemobj)
    {
        alert("Error: Couldnot get the input object named: " + itemname);
        return;
    }
    if (true == this.validate_on_killfocus)
    {
        itemobj.onblur = handle_item_on_killfocus;
    }
    if (!itemobj.validationset)
    {
        itemobj.validationset = new ValidationSet(itemobj, this.show_errors_together);
    }
    itemobj.validationset.add(descriptor, errstr, condition);
    itemobj.validatorobj = this;
}

function handle_item_on_killfocus()
{
    if (this.validatorobj.focus_disable_validations == true)
    {
        /*  
        To avoid repeated looping message boxes
        */
        this.validatorobj.focus_disable_validations = false;
        return false;
    }

    if (null != this.validationset)
    {
        document.error_disp_handler.clear_msgs();
        if (false == this.validationset.validate())
        {
            document.error_disp_handler.FinalShowMsg();
            return false;
        }
    }
}

function validator_enable_OPED()
{
    document.error_disp_handler.EnableOnPageDisplay(false);
}

function validator_enable_OPED_SB()
{
    document.error_disp_handler.EnableOnPageDisplay(true);
}

function sfm_ErrorDisplayHandler()
{
    this.msgdisplay = new AlertMsgDisplayer();
    this.EnableOnPageDisplay = edh_EnableOnPageDisplay;
    this.ShowMsg = edh_ShowMsg;
    this.FinalShowMsg = edh_FinalShowMsg;
    this.all_msgs = new Array();
    this.clear_msgs = edh_clear_msgs;
}

function edh_clear_msgs()
{
    this.msgdisplay.clearmsg(this.all_msgs);
    this.all_msgs = new Array();
}

function edh_FinalShowMsg()
{
    if (this.all_msgs.length == 0)
    {
        return;
    }
    this.msgdisplay.showmsg(this.all_msgs);
}

function edh_EnableOnPageDisplay(single_box)
{
    if (true == single_box)
    {
        this.msgdisplay = new SingleBoxErrorDisplay();
    }
    else
    {
        this.msgdisplay = new DivMsgDisplayer();
    }
}

function edh_ShowMsg(msg, input_element)
{
    var objmsg = new Array();
    objmsg["input_element"] = input_element;
    objmsg["msg"] = msg;
    this.all_msgs.push(objmsg);
}

function AlertMsgDisplayer()
{
    this.showmsg = alert_showmsg;
    this.clearmsg = alert_clearmsg;
}

function alert_clearmsg(msgs)
{

}

function alert_showmsg(msgs)
{
    var whole_msg = "";
    var first_elmnt = null;
    for (var m = 0; m < msgs.length; m++)
    {
        if (null == first_elmnt)
        {
            first_elmnt = msgs[m]["input_element"];
        }
        whole_msg += msgs[m]["msg"] + "\n";
    }

    jAlert(whole_msg);

    if (null != first_elmnt)
    {
        sfm_set_focus(first_elmnt);
    }
}

function sfm_show_error_msg(msg, input_elmt)
{
    document.error_disp_handler.ShowMsg(msg, input_elmt);
}

function SingleBoxErrorDisplay()
{
    this.showmsg = sb_div_showmsg;
    this.clearmsg = sb_div_clearmsg;
}

function sb_div_clearmsg(msgs)
{
    var divname = form_error_div_name(msgs);
    sfm_show_div_msg(divname, "");
}

function sb_div_showmsg(msgs)
{
    var whole_msg = "<ul>\n";
    for (var m = 0; m < msgs.length; m++)
    {
        whole_msg += "<li>" + msgs[m]["msg"] + "</li>\n";
    }
    whole_msg += "</ul>";
    var divname = form_error_div_name(msgs);
    var anc_name = divname + "_loc";
    whole_msg = "<a name='" + anc_name + "' >" + whole_msg;

    sfm_show_div_msg(divname, whole_msg);

    window.location.hash = anc_name;
}

function form_error_div_name(msgs)
{
    var input_element = null;

    for (var m in msgs)
    {
        input_element = msgs[m]["input_element"];
        if (input_element)
        {
            break;
        }
    }

    var divname = "";
    if (input_element)
    {
        divname = input_element.form._sfm_form_name + "_errorloc";
    }

    return divname;
}

function sfm_show_div_msg(divname,msgstring)
{
   if(divname.length<=0) return false;

   if(document.layers)
   {
      divlayer = document.layers[divname];
        if(!divlayer){return;}
      divlayer.document.open();
      divlayer.document.write(msgstring);
      divlayer.document.close();
   }
   else
   if(document.all)
   {
      divlayer = document.all[divname];
        if(!divlayer){return;}
      divlayer.innerHTML=msgstring;
   }
   else
   if(document.getElementById)
   {
      divlayer = document.getElementById(divname);
        if(!divlayer){return;}
      divlayer.innerHTML =msgstring;
   }
   divlayer.style.visibility="visible";   
   return false;
}

function DivMsgDisplayer()
{
    this.showmsg = div_showmsg;
    this.clearmsg = div_clearmsg;
}

function div_clearmsg(msgs)
{
    for (var m in msgs)
    {
        var divname = element_div_name(msgs[m]["input_element"]);
        show_div_msg(divname, "");
    }
}

function element_div_name(input_element)
{
    var divname = input_element.form._sfm_form_name + "_" + input_element.name + "_errorloc";

    divname = divname.replace(/[\[\]]/gi, "");

    return divname;
}

function div_showmsg(msgs)
{
    var whole_msg;
    var first_elmnt = null;
    for (var m in msgs)
    {
        if (null == first_elmnt)
        {
            first_elmnt = msgs[m]["input_element"];
        }
        var divname = element_div_name(msgs[m]["input_element"]);
        show_div_msg(divname, msgs[m]["msg"]);
    }
    if (null != first_elmnt)
    {
        sfm_set_focus(first_elmnt);
    }
}

function show_div_msg(divname, msgstring)
{
    if (divname.length <= 0) return false;

    if (document.layers)
    {
        divlayer = document.layers[divname];
        if (!divlayer)
        {
            return;
        }
        divlayer.document.open();
        divlayer.document.write(msgstring);
        divlayer.document.close();
    }
    else if (document.all)
    {
        divlayer = document.all[divname];
        if (!divlayer)
        {
            return;
        }
        divlayer.innerHTML = msgstring;
    }
    else if (document.getElementById)
    {
        divlayer = document.getElementById(divname);
        if (!divlayer)
        {
            return;
        }
        divlayer.innerHTML = msgstring;
    }
    divlayer.style.visibility = "visible";
}

function ValidationDesc(inputitem, desc, error, condition)
{
    this.desc = desc;
    this.error = error;
    this.itemobj = inputitem;
    this.condition = condition;
    this.validate = vdesc_validate;
}

function vdesc_validate()
{
    if (this.condition != null)
    {
        if (!eval(this.condition))
        {
            return true;
        }
    }
    if (!validateInput(this.desc, this.itemobj, this.error))
    {
        this.itemobj.validatorobj.focus_disable_validations = true;
        sfm_set_focus(this.itemobj);
        return false;
    }

    return true;
}

function ValidationSet(inputitem, msgs_together)
{
    this.vSet = new Array();
    this.add = add_validationdesc;
    this.validate = vset_validate;
    this.itemobj = inputitem;
    this.msgs_together = msgs_together;
}

function add_validationdesc(desc, error, condition)
{
    this.vSet[this.vSet.length] =
    new ValidationDesc(this.itemobj, desc, error, condition);
}

function vset_validate()
{
    var bRet = true;
    for (var itr = 0; itr < this.vSet.length; itr++)
    {
        bRet = bRet && this.vSet[itr].validate();
        if (!bRet && !this.msgs_together)
        {
            break;
        }
    }
    return bRet;
}

/*  checks the validity of an email address entered 
*   returns true or false 
*/
function validateEmail(email)
{
    var splitted = email.match("^(.+)@(.+)$");
    if (splitted == null) return false;
    if (splitted[1] != null)
    {
        var regexp_user = /^\"?[\w-_\.]*\"?$/;
        if (splitted[1].match(regexp_user) == null) return false;
    }
    if (splitted[2] != null)
    {
        var regexp_domain = /^[\w-\.]*\.[A-Za-z]{2,4}$/;
        if (splitted[2].match(regexp_domain) == null)
        {
            var regexp_ip = /^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
            if (splitted[2].match(regexp_ip) == null) return false;
        } // if
        return true;
    }
    return false;
}

function TestComparison(objValue, strCompareElement, strvalidator, strError)
{
    var bRet = true;
    var objCompare = null;
    if (!objValue.form)
    {
        sfm_show_error_msg("Error: No Form object!", objValue);
        return false
    }
    objCompare = objValue.form.elements[strCompareElement];
    if (!objCompare)
    {
        sfm_show_error_msg("Error: Element with name" + strCompareElement + " not found !", objValue);
        return false;
    }

    var objval_value = objValue.value;
    var objcomp_value = objCompare.value;

    if (strvalidator != "eqelmnt" && strvalidator != "neelmnt")
    {
        objval_value = objval_value.replace(/\,/g, "");
        objcomp_value = objcomp_value.replace(/\,/g, "");

        if (isNaN(objval_value))
        {
            sfm_show_error_msg(objValue.name + ": Should be a number ", objValue);
            return false;
        } //if 
        if (isNaN(objcomp_value))
        {
            sfm_show_error_msg(objCompare.name + ": Should be a number ", objCompare);
            return false;
        } //if    
    } //if
    var cmpstr = "";
    switch (strvalidator)
    {
    case "eqelmnt":
        {
            if (objval_value != objcomp_value)
            {
                cmpstr = " should be equal to ";
                bRet = false;
            } //if
            break;
        } //case
    case "ltelmnt":
        {
            if (eval(objval_value) >= eval(objcomp_value))
            {
                cmpstr = " should be less than ";
                bRet = false;
            }
            break;
        } //case
    case "leelmnt":
        {
            if (eval(objval_value) > eval(objcomp_value))
            {
                cmpstr = " should be less than or equal to";
                bRet = false;
            }
            break;
        } //case     
    case "gtelmnt":
        {
            if (eval(objval_value) <= eval(objcomp_value))
            {
                cmpstr = " should be greater than";
                bRet = false;
            }
            break;
        } //case
    case "geelmnt":
        {
            if (eval(objval_value) < eval(objcomp_value))
            {
                cmpstr = " should be greater than or equal to";
                bRet = false;
            }
            break;
        } //case
    case "neelmnt":
        {
            if (objval_value.length > 0 && objcomp_value.length > 0 && objval_value == objcomp_value)
            {
                cmpstr = " should be different from ";
                bRet = false;
            } //if
            break;
        }
    } //switch
    if (bRet == false)
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + cmpstr + objCompare.name;
        } //if
        sfm_show_error_msg(strError, objValue);
    } //if
    return bRet;
}

function TestSelMin(objValue, strMinSel, strError)
{
    var bret = true;
    var objcheck = objValue.form.elements[objValue.name];
    var chkcount = 0;
    if (objcheck.length)
    {
        for (var c = 0; c < objcheck.length; c++)
        {
            if (objcheck[c].checked == "1")
            {
                chkcount++;
            } //if
        } //for
    }
    else
    {
        chkcount = (objcheck.checked == "1") ? 1 : 0;
    }
    var minsel = eval(strMinSel);
    if (chkcount < minsel)
    {
        if (!strError || strError.length == 0)
        {
            strError = "Please Select atleast" + minsel + " check boxes for" + objValue.name;
        } //if                                                               
        sfm_show_error_msg(strError, objValue);
        bret = false;
    }
    return bret;
}

function TestSelMax(objValue, strMaxSel, strError)
{
    var bret = true;
    var objcheck = objValue.form.elements[objValue.name];
    var chkcount = 0;
    if (objcheck.length)
    {
        for (var c = 0; c < objcheck.length; c++)
        {
            if (objcheck[c].checked == "1")
            {
                chkcount++;
            } //if
        } //for
    }
    else
    {
        chkcount = (objcheck.checked == "1") ? 1 : 0;
    }
    var maxsel = eval(strMaxSel);
    if (chkcount > maxsel)
    {
        if (!strError || strError.length == 0)
        {
            strError = "Please Select atmost " + maxsel + " check boxes for" + objValue.name;
        } //if                                                               
        sfm_show_error_msg(strError, objValue);
        bret = false;
    }
    return bret;
}

function IsCheckSelected(objValue, chkValue)
{
    var selected = false;
    var objcheck = objValue.form.elements[objValue.name];
    if (objcheck.length)
    {
        var idxchk = -1;
        for (var c = 0; c < objcheck.length; c++)
        {
            if (objcheck[c].value == chkValue)
            {
                idxchk = c;
                break;
            } //if
        } //for
        if (idxchk >= 0)
        {
            if (objcheck[idxchk].checked == "1")
            {
                selected = true;
            }
        } //if
    }
    else
    {
        if (objValue.checked == "1")
        {
            selected = true;
        } //if
    } //else  
    return selected;
}

function TestDontSelectChk(objValue, chkValue, strError)
{
    var pass = true;
    pass = IsCheckSelected(objValue, chkValue) ? false : true;

    if (pass == false)
    {
        if (!strError || strError.length == 0)
        {
            strError = "Can't Proceed as you selected " + objValue.name;
        } //if          
        sfm_show_error_msg(strError, objValue);

    }
    return pass;
}

function TestShouldSelectChk(objValue, chkValue, strError)
{
    var pass = true;

    pass = IsCheckSelected(objValue, chkValue) ? true : false;

    if (pass == false)
    {
        if (!strError || strError.length == 0)
        {
            strError = "You should select" + objValue.name;
        } //if          
        sfm_show_error_msg(strError, objValue);

    }
    return pass;
}

function TestRequiredInput(objValue, strError)
{
    var ret = true;
    if (VWZ_IsEmpty(objValue.value))
    {
        ret = false;
    } //if 
    else if (objValue.getcal && !objValue.getcal())
    {
        ret = false;
    }

    if (!ret)
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + " : Required Field";
        } //if 
        sfm_show_error_msg(strError, objValue);
    }
    return ret;
}

function TestFileExtension(objValue, cmdvalue, strError)
{
    var ret = false;
    var found = false;

    if (objValue.value.length <= 0)
    { //The 'required' validation is not done here
        return true;
    }

    var extns = cmdvalue.split(";");
    for (var i = 0; i < extns.length; i++)
    {
        ext = objValue.value.substr(objValue.value.length - extns[i].length, extns[i].length);
        ext = ext.toLowerCase();
        if (ext == extns[i])
        {
            found = true;
            break;
        }
    }
    if (!found)
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + " allowed file extensions are: " + cmdvalue;
        } //if 
        sfm_show_error_msg(strError, objValue);
        ret = false;
    }
    else
    {
        ret = true;
    }
    return ret;
}

function TestMaxLen(objValue, strMaxLen, strError)
{
    var ret = true;
    if (eval(objValue.value.length) > eval(strMaxLen))
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + " : " + strMaxLen + " characters maximum ";
        } //if 
        sfm_show_error_msg(strError, objValue);
        ret = false;
    } //if 
    return ret;
}

function TestMinLen(objValue, strMinLen, strError)
{
    var ret = true;
    if (eval(objValue.value.length) < eval(strMinLen))
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + " : " + strMinLen + " characters minimum  ";
        } //if               
        sfm_show_error_msg(strError, objValue);
        ret = false;
    } //if 
    return ret;
}

function TestInputType(objValue, strRegExp, strError, strDefaultError)
{
    var ret = true;

    var charpos = objValue.value.search(strRegExp);
    if (objValue.value.length > 0 && charpos >= 0)
    {
        if (!strError || strError.length == 0)
        {
            strError = strDefaultError;
        } //if 
        sfm_show_error_msg(strError, objValue);
        ret = false;
    } //if 
    return ret;
}

function TestEmail(objValue, strError)
{
    var ret = true;
    if (objValue.value.length > 0 && !validateEmail(objValue.value))
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + ": Enter a valid Email address ";
        } //if                                               
        sfm_show_error_msg(strError, objValue);
        ret = false;
    } //if 
    return ret;
}

function TestLessThan(objValue, strLessThan, strError)
{
    var ret = true;
    var obj_value = objValue.value.replace(/\,/g, "");
    strLessThan = strLessThan.replace(/\,/g, "");

    if (isNaN(obj_value))
    {
        sfm_show_error_msg(objValue.name + ": Should be a number ", objValue);
        ret = false;
    } //if 
    else if (eval(obj_value) >= eval(strLessThan))
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + " : value should be less than " + strLessThan;
        } //if               
        sfm_show_error_msg(strError, objValue);
        ret = false;
    } //if   
    return ret;
}

function TestGreaterThan(objValue, strGreaterThan, strError)
{
    var ret = true;
    var obj_value = objValue.value.replace(/\,/g, "");
    strGreaterThan = strGreaterThan.replace(/\,/g, "");

    if (isNaN(obj_value))
    {
        sfm_show_error_msg(objValue.name + ": Should be a number ", objValue);
        ret = false;
    } //if 
    else if (eval(obj_value) <= eval(strGreaterThan))
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + " : value should be greater than " + strGreaterThan;
        } //if               
        sfm_show_error_msg(strError, objValue);
        ret = false;
    } //if  
    return ret;
}

function TestRegExp(objValue, strRegExp, strError)
{
    var ret = true;
    if (objValue.value.length > 0 && !objValue.value.match(strRegExp))
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + ": Invalid characters found ";
        } //if                                                               
        sfm_show_error_msg(strError, objValue);
        ret = false;
    } //if 
    return ret;
}

function TestDontSelect(objValue, dont_sel_value, strError)
{
    var ret = true;
    if (objValue.value == null)
    {
        sfm_show_error_msg("Error: dontselect command for non-select Item", objValue);
        ret = false;
    }
    else if (objValue.value == dont_sel_value)
    {
        if (!strError || strError.length == 0)
        {
            strError = objValue.name + ": Please Select one option ";
        } //if                                                               
        sfm_show_error_msg(strError, objValue);
        ret = false;
    }
    return ret;
}

function TestSelectOneRadio(objValue, strError)
{
    var objradio = objValue.form.elements[objValue.name];
    var one_selected = false;
    for (var r = 0; r < objradio.length; r++)
    {
        if (objradio[r].checked == "1")
        {
            one_selected = true;
            break;
        }
    }
    if (false == one_selected)
    {
        if (!strError || strError.length == 0)
        {
            strError = "Please select one option from " + objValue.name;
        }
        sfm_show_error_msg(strError, objValue);
    }
    return one_selected;
}

function TestSelectRadio(objValue, cmdvalue, strError, testselect)
{
    var objradio = objValue.form.elements[objValue.name];
    var selected = false;

    for (var r = 0; r < objradio.length; r++)
    {
        if (objradio[r].value == cmdvalue && objradio[r].checked == "1")
        {
            selected = true;
            break;
        }
    }
    if (testselect == true && false == selected || testselect == false && true == selected)
    {
        sfm_show_error_msg(strError, objValue);
        return false;
    }
    return true;
}


//*  Checks each field in a form 


function validateInput(strValidateStr, objValue, strError)
{

    var ret = true;
    var epos = strValidateStr.search("=");
    var command = "";
    var cmdvalue = "";
    if (epos >= 0)
    {
        command = strValidateStr.substring(0, epos);
        cmdvalue = strValidateStr.substr(epos + 1);
    }
    else
    {
        command = strValidateStr;
    }

    switch (command)
    {
    case "req":
    case "required":
        {
            ret = TestRequiredInput(objValue, strError)
            break;
        }
    case "maxlength":
    case "maxlen":
        {
            ret = TestMaxLen(objValue, cmdvalue, strError)
            break;
        }
    case "minlength":
    case "minlen":
        {
            ret = TestMinLen(objValue, cmdvalue, strError)
            break;
        }
    case "alnum":
    case "alphanumeric":
        {
            ret = TestInputType(objValue, "[^A-Za-z0-9]", strError, objValue.name + ": Only alpha-numeric characters allowed ");
            break;
        }
    case "alnum_s":
    case "alphanumeric_space":
        {
            ret = TestInputType(objValue, "[^A-Za-z0-9\\s]", strError, objValue.name + ": Only alpha-numeric characters and space allowed ");
            break;
        }
    case "num":
    case "numeric":
    case "dec": 
    case "decimal": 
        {
            if (objValue.value.length > 0 && !objValue.value.match(/^[\-\+]?[\d\,]*\.?[\d]*$/))
            {
                sfm_show_error_msg(strError, objValue);
                ret = false;
            } //if 
            break;
        }
    case "alphabetic":
    case "alpha":
        {
            ret = TestInputType(objValue, "[^A-Za-z]", strError, objValue.name + ": Only alphabetic characters allowed ");
            break;
        }
    case "alphabetic_space":
    case "alpha_s":
        {
            ret = TestInputType(objValue, "[^A-Za-z\\s]", strError, objValue.name + ": Only alphabetic characters and space allowed ");
            break;
        }
    case "email":
        {
            ret = TestEmail(objValue, strError);
            break;
        }
    case "lt":
    case "lessthan":
        {
            ret = TestLessThan(objValue, cmdvalue, strError);
            break;
        }
    case "gt":
    case "greaterthan":
        {
            ret = TestGreaterThan(objValue, cmdvalue, strError);
            break;
        }
    case "regexp":
        {
            ret = TestRegExp(objValue, cmdvalue, strError);
            break;
        }
    case "dontselect":
        {
            ret = TestDontSelect(objValue, cmdvalue, strError)
            break;
        }
    case "dontselectchk":
        {
            ret = TestDontSelectChk(objValue, cmdvalue, strError)
            break;
        }
    case "shouldselchk":
        {
            ret = TestShouldSelectChk(objValue, cmdvalue, strError)
            break;
        }
    case "selmin":
        {
            ret = TestSelMin(objValue, cmdvalue, strError);
            break;
        }
    case "selmax":
        {
            ret = TestSelMax(objValue, cmdvalue, strError);
            break;
        }
    case "selone_radio":
    case "selone":
        {
            ret = TestSelectOneRadio(objValue, strError);
            break;
        }
    case "dontselectradio":
        {
            ret = TestSelectRadio(objValue, cmdvalue, strError, false);
            break;
        }
    case "selectradio":
        {
            ret = TestSelectRadio(objValue, cmdvalue, strError, true);
            break;
        }
        //Comparisons
    case "eqelmnt":
    case "ltelmnt":
    case "leelmnt":
    case "gtelmnt":
    case "geelmnt":
    case "neelmnt":
        {
            return TestComparison(objValue, cmdvalue, command, strError);
            break;
        }
    case "req_file":
        {
            ret = TestRequiredInput(objValue, strError);
            break;
        }
    case "file_extn":
        {
            ret = TestFileExtension(objValue, cmdvalue, strError);
            break;
        }

    } //switch 
    return ret;
}

function VWZ_IsListItemSelected(listname, value)
{
    for (var i = 0; i < listname.options.length; i++)
    {
        if (listname.options[i].selected == true && listname.options[i].value == value)
        {
            return true;
        }
    }
    return false;
}

function VWZ_IsChecked(objcheck, value)
{
    if (objcheck.length)
    {
        for (var c = 0; c < objcheck.length; c++)
        {
            if (objcheck[c].checked == "1" && objcheck[c].value == value)
            {
                return true;
            }
        }
    }
    else
    {
        if (objcheck.checked == "1")
        {
            return true;
        }
    }
    return false;
}

function sfm_str_trim(strIn)
{
    return strIn.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}

function VWZ_IsEmpty(value)
{
    value = sfm_str_trim(value);
    return (value.length) == 0 ? true : false;
}
/*
	Copyright (C) 2003-2011 JavaScript-Coder.com . All rights reserved.
*/

