web/wp-content/plugins/calendar/javascript.js
branchwordpress
changeset 112 fb7cd02b9848
parent 111 6b96085291d7
child 123 561aa6d282f6
equal deleted inserted replaced
111:6b96085291d7 112:fb7cd02b9848
     1 // ===================================================================
       
     2 // Author: Matt Kruse <matt@mattkruse.com>
       
     3 // WWW: http://www.mattkruse.com/
       
     4 //
       
     5 // NOTICE: You may use this code for any purpose, commercial or
       
     6 // private, without any further permission from the author. You may
       
     7 // remove this notice from your final code if you wish, however it is
       
     8 // appreciated by the author if at least my web site address is kept.
       
     9 //
       
    10 // You may *NOT* re-distribute this code in any way except through its
       
    11 // use. That means, you can include it in your product, or your web
       
    12 // site, or any other form where the code is actually being used. You
       
    13 // may not put the plain javascript up on your site for download or
       
    14 // include it in your javascript libraries for download. 
       
    15 // If you wish to share this code with others, please just point them
       
    16 // to the URL instead.
       
    17 // Please DO NOT link directly to my .js files from your site. Copy
       
    18 // the files to your server and use them there. Thank you.
       
    19 // ===================================================================
       
    20 
       
    21 
       
    22 /* SOURCE FILE: AnchorPosition.js */
       
    23 
       
    24 /* 
       
    25 AnchorPosition.js
       
    26 Author: Matt Kruse
       
    27 Last modified: 10/11/02
       
    28 
       
    29 DESCRIPTION: These functions find the position of an <A> tag in a document,
       
    30 so other elements can be positioned relative to it.
       
    31 
       
    32 COMPATABILITY: Netscape 4.x,6.x,Mozilla, IE 5.x,6.x on Windows. Some small
       
    33 positioning errors - usually with Window positioning - occur on the 
       
    34 Macintosh platform.
       
    35 
       
    36 FUNCTIONS:
       
    37 getAnchorPosition(anchorname)
       
    38   Returns an Object() having .x and .y properties of the pixel coordinates
       
    39   of the upper-left corner of the anchor. Position is relative to the PAGE.
       
    40 
       
    41 getAnchorWindowPosition(anchorname)
       
    42   Returns an Object() having .x and .y properties of the pixel coordinates
       
    43   of the upper-left corner of the anchor, relative to the WHOLE SCREEN.
       
    44 
       
    45 NOTES:
       
    46 
       
    47 1) For popping up separate browser windows, use getAnchorWindowPosition. 
       
    48    Otherwise, use getAnchorPosition
       
    49 
       
    50 2) Your anchor tag MUST contain both NAME and ID attributes which are the 
       
    51    same. For example:
       
    52    <A NAME="test" ID="test"> </A>
       
    53 
       
    54 3) There must be at least a space between <A> </A> for IE5.5 to see the 
       
    55    anchor tag correctly. Do not do <A></A> with no space.
       
    56 */ 
       
    57 
       
    58 // getAnchorPosition(anchorname)
       
    59 //   This function returns an object having .x and .y properties which are the coordinates
       
    60 //   of the named anchor, relative to the page.
       
    61 function getAnchorPosition(anchorname) {
       
    62 	// This function will return an Object with x and y properties
       
    63 	var useWindow=false;
       
    64 	var coordinates=new Object();
       
    65 	var x=0,y=0;
       
    66 	// Browser capability sniffing
       
    67 	var use_gebi=false, use_css=false, use_layers=false;
       
    68 	if (document.getElementById) { use_gebi=true; }
       
    69 	else if (document.all) { use_css=true; }
       
    70 	else if (document.layers) { use_layers=true; }
       
    71 	// Logic to find position
       
    72  	if (use_gebi && document.all) {
       
    73 		x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
       
    74 		y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
       
    75 		}
       
    76 	else if (use_gebi) {
       
    77 		var o=document.getElementById(anchorname);
       
    78 		x=AnchorPosition_getPageOffsetLeft(o);
       
    79 		y=AnchorPosition_getPageOffsetTop(o);
       
    80 		}
       
    81  	else if (use_css) {
       
    82 		x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);
       
    83 		y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);
       
    84 		}
       
    85 	else if (use_layers) {
       
    86 		var found=0;
       
    87 		for (var i=0; i<document.anchors.length; i++) {
       
    88 			if (document.anchors[i].name==anchorname) { found=1; break; }
       
    89 			}
       
    90 		if (found==0) {
       
    91 			coordinates.x=0; coordinates.y=0; return coordinates;
       
    92 			}
       
    93 		x=document.anchors[i].x;
       
    94 		y=document.anchors[i].y;
       
    95 		}
       
    96 	else {
       
    97 		coordinates.x=0; coordinates.y=0; return coordinates;
       
    98 		}
       
    99 	coordinates.x=x;
       
   100 	coordinates.y=y;
       
   101 	return coordinates;
       
   102 	}
       
   103 
       
   104 // getAnchorWindowPosition(anchorname)
       
   105 //   This function returns an object having .x and .y properties which are the coordinates
       
   106 //   of the named anchor, relative to the window
       
   107 function getAnchorWindowPosition(anchorname) {
       
   108 	var coordinates=getAnchorPosition(anchorname);
       
   109 	var x=0;
       
   110 	var y=0;
       
   111 	if (document.getElementById) {
       
   112 		if (isNaN(window.screenX)) {
       
   113 			x=coordinates.x-document.body.scrollLeft+window.screenLeft;
       
   114 			y=coordinates.y-document.body.scrollTop+window.screenTop;
       
   115 			}
       
   116 		else {
       
   117 			x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
       
   118 			y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
       
   119 			}
       
   120 		}
       
   121 	else if (document.all) {
       
   122 		x=coordinates.x-document.body.scrollLeft+window.screenLeft;
       
   123 		y=coordinates.y-document.body.scrollTop+window.screenTop;
       
   124 		}
       
   125 	else if (document.layers) {
       
   126 		x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;
       
   127 		y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;
       
   128 		}
       
   129 	coordinates.x=x;
       
   130 	coordinates.y=y;
       
   131 	return coordinates;
       
   132 	}
       
   133 
       
   134 // Functions for IE to get position of an object
       
   135 function AnchorPosition_getPageOffsetLeft (el) {
       
   136 	var ol=el.offsetLeft;
       
   137 	while ((el=el.offsetParent) != null) { ol += el.offsetLeft; }
       
   138 	return ol;
       
   139 	}
       
   140 function AnchorPosition_getWindowOffsetLeft (el) {
       
   141 	return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;
       
   142 	}	
       
   143 function AnchorPosition_getPageOffsetTop (el) {
       
   144 	var ot=el.offsetTop;
       
   145 	while((el=el.offsetParent) != null) { ot += el.offsetTop; }
       
   146 	return ot;
       
   147 	}
       
   148 function AnchorPosition_getWindowOffsetTop (el) {
       
   149 	return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;
       
   150 	}
       
   151 
       
   152 /* SOURCE FILE: date.js */
       
   153 
       
   154 // HISTORY
       
   155 // ------------------------------------------------------------------
       
   156 // May 17, 2003: Fixed bug in parseDate() for dates <1970
       
   157 // March 11, 2003: Added parseDate() function
       
   158 // March 11, 2003: Added "NNN" formatting option. Doesn't match up
       
   159 //                 perfectly with SimpleDateFormat formats, but 
       
   160 //                 backwards-compatability was required.
       
   161 
       
   162 // ------------------------------------------------------------------
       
   163 // These functions use the same 'format' strings as the 
       
   164 // java.text.SimpleDateFormat class, with minor exceptions.
       
   165 // The format string consists of the following abbreviations:
       
   166 // 
       
   167 // Field        | Full Form          | Short Form
       
   168 // -------------+--------------------+-----------------------
       
   169 // Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
       
   170 // Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
       
   171 //              | NNN (abbr.)        |
       
   172 // Day of Month | dd (2 digits)      | d (1 or 2 digits)
       
   173 // Day of Week  | EE (name)          | E (abbr)
       
   174 // Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
       
   175 // Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
       
   176 // Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
       
   177 // Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
       
   178 // Minute       | mm (2 digits)      | m (1 or 2 digits)
       
   179 // Second       | ss (2 digits)      | s (1 or 2 digits)
       
   180 // AM/PM        | a                  |
       
   181 //
       
   182 // NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
       
   183 // Examples:
       
   184 //  "MMM d, y" matches: January 01, 2000
       
   185 //                      Dec 1, 1900
       
   186 //                      Nov 20, 00
       
   187 //  "M/d/yy"   matches: 01/20/00
       
   188 //                      9/2/00
       
   189 //  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
       
   190 // ------------------------------------------------------------------
       
   191 
       
   192 var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
       
   193 var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
       
   194 function LZ(x) {return(x<0||x>9?"":"0")+x}
       
   195 
       
   196 // ------------------------------------------------------------------
       
   197 // isDate ( date_string, format_string )
       
   198 // Returns true if date string matches format of format string and
       
   199 // is a valid date. Else returns false.
       
   200 // It is recommended that you trim whitespace around the value before
       
   201 // passing it to this function, as whitespace is NOT ignored!
       
   202 // ------------------------------------------------------------------
       
   203 function isDate(val,format) {
       
   204 	var date=getDateFromFormat(val,format);
       
   205 	if (date==0) { return false; }
       
   206 	return true;
       
   207 	}
       
   208 
       
   209 // -------------------------------------------------------------------
       
   210 // compareDates(date1,date1format,date2,date2format)
       
   211 //   Compare two date strings to see which is greater.
       
   212 //   Returns:
       
   213 //   1 if date1 is greater than date2
       
   214 //   0 if date2 is greater than date1 of if they are the same
       
   215 //  -1 if either of the dates is in an invalid format
       
   216 // -------------------------------------------------------------------
       
   217 function compareDates(date1,dateformat1,date2,dateformat2) {
       
   218 	var d1=getDateFromFormat(date1,dateformat1);
       
   219 	var d2=getDateFromFormat(date2,dateformat2);
       
   220 	if (d1==0 || d2==0) {
       
   221 		return -1;
       
   222 		}
       
   223 	else if (d1 > d2) {
       
   224 		return 1;
       
   225 		}
       
   226 	return 0;
       
   227 	}
       
   228 
       
   229 // ------------------------------------------------------------------
       
   230 // formatDate (date_object, format)
       
   231 // Returns a date in the output format specified.
       
   232 // The format string uses the same abbreviations as in getDateFromFormat()
       
   233 // ------------------------------------------------------------------
       
   234 function formatDate(date,format) {
       
   235 	format=format+"";
       
   236 	var result="";
       
   237 	var i_format=0;
       
   238 	var c="";
       
   239 	var token="";
       
   240 	var y=date.getYear()+"";
       
   241 	var M=date.getMonth()+1;
       
   242 	var d=date.getDate();
       
   243 	var E=date.getDay();
       
   244 	var H=date.getHours();
       
   245 	var m=date.getMinutes();
       
   246 	var s=date.getSeconds();
       
   247 	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
       
   248 	// Convert real date parts into formatted versions
       
   249 	var value=new Object();
       
   250 	if (y.length < 4) {y=""+(y-0+1900);}
       
   251 	value["y"]=""+y;
       
   252 	value["yyyy"]=y;
       
   253 	value["yy"]=y.substring(2,4);
       
   254 	value["M"]=M;
       
   255 	value["MM"]=LZ(M);
       
   256 	value["MMM"]=MONTH_NAMES[M-1];
       
   257 	value["NNN"]=MONTH_NAMES[M+11];
       
   258 	value["d"]=d;
       
   259 	value["dd"]=LZ(d);
       
   260 	value["E"]=DAY_NAMES[E+7];
       
   261 	value["EE"]=DAY_NAMES[E];
       
   262 	value["H"]=H;
       
   263 	value["HH"]=LZ(H);
       
   264 	if (H==0){value["h"]=12;}
       
   265 	else if (H>12){value["h"]=H-12;}
       
   266 	else {value["h"]=H;}
       
   267 	value["hh"]=LZ(value["h"]);
       
   268 	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
       
   269 	value["k"]=H+1;
       
   270 	value["KK"]=LZ(value["K"]);
       
   271 	value["kk"]=LZ(value["k"]);
       
   272 	if (H > 11) { value["a"]="PM"; }
       
   273 	else { value["a"]="AM"; }
       
   274 	value["m"]=m;
       
   275 	value["mm"]=LZ(m);
       
   276 	value["s"]=s;
       
   277 	value["ss"]=LZ(s);
       
   278 	while (i_format < format.length) {
       
   279 		c=format.charAt(i_format);
       
   280 		token="";
       
   281 		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
       
   282 			token += format.charAt(i_format++);
       
   283 			}
       
   284 		if (value[token] != null) { result=result + value[token]; }
       
   285 		else { result=result + token; }
       
   286 		}
       
   287 	return result;
       
   288 	}
       
   289 	
       
   290 // ------------------------------------------------------------------
       
   291 // Utility functions for parsing in getDateFromFormat()
       
   292 // ------------------------------------------------------------------
       
   293 function _isInteger(val) {
       
   294 	var digits="1234567890";
       
   295 	for (var i=0; i < val.length; i++) {
       
   296 		if (digits.indexOf(val.charAt(i))==-1) { return false; }
       
   297 		}
       
   298 	return true;
       
   299 	}
       
   300 function _getInt(str,i,minlength,maxlength) {
       
   301 	for (var x=maxlength; x>=minlength; x--) {
       
   302 		var token=str.substring(i,i+x);
       
   303 		if (token.length < minlength) { return null; }
       
   304 		if (_isInteger(token)) { return token; }
       
   305 		}
       
   306 	return null;
       
   307 	}
       
   308 	
       
   309 // ------------------------------------------------------------------
       
   310 // getDateFromFormat( date_string , format_string )
       
   311 //
       
   312 // This function takes a date string and a format string. It matches
       
   313 // If the date string matches the format string, it returns the 
       
   314 // getTime() of the date. If it does not match, it returns 0.
       
   315 // ------------------------------------------------------------------
       
   316 function getDateFromFormat(val,format) {
       
   317 	val=val+"";
       
   318 	format=format+"";
       
   319 	var i_val=0;
       
   320 	var i_format=0;
       
   321 	var c="";
       
   322 	var token="";
       
   323 	var token2="";
       
   324 	var x,y;
       
   325 	var now=new Date();
       
   326 	var year=now.getYear();
       
   327 	var month=now.getMonth()+1;
       
   328 	var date=1;
       
   329 	var hh=now.getHours();
       
   330 	var mm=now.getMinutes();
       
   331 	var ss=now.getSeconds();
       
   332 	var ampm="";
       
   333 	
       
   334 	while (i_format < format.length) {
       
   335 		// Get next token from format string
       
   336 		c=format.charAt(i_format);
       
   337 		token="";
       
   338 		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
       
   339 			token += format.charAt(i_format++);
       
   340 			}
       
   341 		// Extract contents of value based on format token
       
   342 		if (token=="yyyy" || token=="yy" || token=="y") {
       
   343 			if (token=="yyyy") { x=4;y=4; }
       
   344 			if (token=="yy")   { x=2;y=2; }
       
   345 			if (token=="y")    { x=2;y=4; }
       
   346 			year=_getInt(val,i_val,x,y);
       
   347 			if (year==null) { return 0; }
       
   348 			i_val += year.length;
       
   349 			if (year.length==2) {
       
   350 				if (year > 70) { year=1900+(year-0); }
       
   351 				else { year=2000+(year-0); }
       
   352 				}
       
   353 			}
       
   354 		else if (token=="MMM"||token=="NNN"){
       
   355 			month=0;
       
   356 			for (var i=0; i<MONTH_NAMES.length; i++) {
       
   357 				var month_name=MONTH_NAMES[i];
       
   358 				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
       
   359 					if (token=="MMM"||(token=="NNN"&&i>11)) {
       
   360 						month=i+1;
       
   361 						if (month>12) { month -= 12; }
       
   362 						i_val += month_name.length;
       
   363 						break;
       
   364 						}
       
   365 					}
       
   366 				}
       
   367 			if ((month < 1)||(month>12)){return 0;}
       
   368 			}
       
   369 		else if (token=="EE"||token=="E"){
       
   370 			for (var i=0; i<DAY_NAMES.length; i++) {
       
   371 				var day_name=DAY_NAMES[i];
       
   372 				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
       
   373 					i_val += day_name.length;
       
   374 					break;
       
   375 					}
       
   376 				}
       
   377 			}
       
   378 		else if (token=="MM"||token=="M") {
       
   379 			month=_getInt(val,i_val,token.length,2);
       
   380 			if(month==null||(month<1)||(month>12)){return 0;}
       
   381 			i_val+=month.length;}
       
   382 		else if (token=="dd"||token=="d") {
       
   383 			date=_getInt(val,i_val,token.length,2);
       
   384 			if(date==null||(date<1)||(date>31)){return 0;}
       
   385 			i_val+=date.length;}
       
   386 		else if (token=="hh"||token=="h") {
       
   387 			hh=_getInt(val,i_val,token.length,2);
       
   388 			if(hh==null||(hh<1)||(hh>12)){return 0;}
       
   389 			i_val+=hh.length;}
       
   390 		else if (token=="HH"||token=="H") {
       
   391 			hh=_getInt(val,i_val,token.length,2);
       
   392 			if(hh==null||(hh<0)||(hh>23)){return 0;}
       
   393 			i_val+=hh.length;}
       
   394 		else if (token=="KK"||token=="K") {
       
   395 			hh=_getInt(val,i_val,token.length,2);
       
   396 			if(hh==null||(hh<0)||(hh>11)){return 0;}
       
   397 			i_val+=hh.length;}
       
   398 		else if (token=="kk"||token=="k") {
       
   399 			hh=_getInt(val,i_val,token.length,2);
       
   400 			if(hh==null||(hh<1)||(hh>24)){return 0;}
       
   401 			i_val+=hh.length;hh--;}
       
   402 		else if (token=="mm"||token=="m") {
       
   403 			mm=_getInt(val,i_val,token.length,2);
       
   404 			if(mm==null||(mm<0)||(mm>59)){return 0;}
       
   405 			i_val+=mm.length;}
       
   406 		else if (token=="ss"||token=="s") {
       
   407 			ss=_getInt(val,i_val,token.length,2);
       
   408 			if(ss==null||(ss<0)||(ss>59)){return 0;}
       
   409 			i_val+=ss.length;}
       
   410 		else if (token=="a") {
       
   411 			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
       
   412 			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
       
   413 			else {return 0;}
       
   414 			i_val+=2;}
       
   415 		else {
       
   416 			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
       
   417 			else {i_val+=token.length;}
       
   418 			}
       
   419 		}
       
   420 	// If there are any trailing characters left in the value, it doesn't match
       
   421 	if (i_val != val.length) { return 0; }
       
   422 	// Is date valid for month?
       
   423 	if (month==2) {
       
   424 		// Check for leap year
       
   425 		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
       
   426 			if (date > 29){ return 0; }
       
   427 			}
       
   428 		else { if (date > 28) { return 0; } }
       
   429 		}
       
   430 	if ((month==4)||(month==6)||(month==9)||(month==11)) {
       
   431 		if (date > 30) { return 0; }
       
   432 		}
       
   433 	// Correct hours value
       
   434 	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
       
   435 	else if (hh>11 && ampm=="AM") { hh-=12; }
       
   436 	var newdate=new Date(year,month-1,date,hh,mm,ss);
       
   437 	return newdate.getTime();
       
   438 	}
       
   439 
       
   440 // ------------------------------------------------------------------
       
   441 // parseDate( date_string [, prefer_euro_format] )
       
   442 //
       
   443 // This function takes a date string and tries to match it to a
       
   444 // number of possible date formats to get the value. It will try to
       
   445 // match against the following international formats, in this order:
       
   446 // y-M-d   MMM d, y   MMM d,y   y-MMM-d   d-MMM-y  MMM d
       
   447 // M/d/y   M-d-y      M.d.y     MMM-d     M/d      M-d
       
   448 // d/M/y   d-M-y      d.M.y     d-MMM     d/M      d-M
       
   449 // A second argument may be passed to instruct the method to search
       
   450 // for formats like d/M/y (european format) before M/d/y (American).
       
   451 // Returns a Date object or null if no patterns match.
       
   452 // ------------------------------------------------------------------
       
   453 function parseDate(val) {
       
   454 	var preferEuro=(arguments.length==2)?arguments[1]:false;
       
   455 	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
       
   456 	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
       
   457 	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
       
   458 	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
       
   459 	var d=null;
       
   460 	for (var i=0; i<checkList.length; i++) {
       
   461 		var l=window[checkList[i]];
       
   462 		for (var j=0; j<l.length; j++) {
       
   463 			d=getDateFromFormat(val,l[j]);
       
   464 			if (d!=0) { return new Date(d); }
       
   465 			}
       
   466 		}
       
   467 	return null;
       
   468 	}
       
   469 
       
   470 /* SOURCE FILE: PopupWindow.js */
       
   471 
       
   472 /* 
       
   473 PopupWindow.js
       
   474 Author: Matt Kruse
       
   475 Last modified: 02/16/04
       
   476 
       
   477 DESCRIPTION: This object allows you to easily and quickly popup a window
       
   478 in a certain place. The window can either be a DIV or a separate browser
       
   479 window.
       
   480 
       
   481 COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
       
   482 positioning errors - usually with Window positioning - occur on the 
       
   483 Macintosh platform. Due to bugs in Netscape 4.x, populating the popup 
       
   484 window with <STYLE> tags may cause errors.
       
   485 
       
   486 USAGE:
       
   487 // Create an object for a WINDOW popup
       
   488 var win = new PopupWindow(); 
       
   489 
       
   490 // Create an object for a DIV window using the DIV named 'mydiv'
       
   491 var win = new PopupWindow('mydiv'); 
       
   492 
       
   493 // Set the window to automatically hide itself when the user clicks 
       
   494 // anywhere else on the page except the popup
       
   495 win.autoHide(); 
       
   496 
       
   497 // Show the window relative to the anchor name passed in
       
   498 win.showPopup(anchorname);
       
   499 
       
   500 // Hide the popup
       
   501 win.hidePopup();
       
   502 
       
   503 // Set the size of the popup window (only applies to WINDOW popups
       
   504 win.setSize(width,height);
       
   505 
       
   506 // Populate the contents of the popup window that will be shown. If you 
       
   507 // change the contents while it is displayed, you will need to refresh()
       
   508 win.populate(string);
       
   509 
       
   510 // set the URL of the window, rather than populating its contents
       
   511 // manually
       
   512 win.setUrl("http://www.site.com/");
       
   513 
       
   514 // Refresh the contents of the popup
       
   515 win.refresh();
       
   516 
       
   517 // Specify how many pixels to the right of the anchor the popup will appear
       
   518 win.offsetX = 50;
       
   519 
       
   520 // Specify how many pixels below the anchor the popup will appear
       
   521 win.offsetY = 100;
       
   522 
       
   523 NOTES:
       
   524 1) Requires the functions in AnchorPosition.js
       
   525 
       
   526 2) Your anchor tag MUST contain both NAME and ID attributes which are the 
       
   527    same. For example:
       
   528    <A NAME="test" ID="test"> </A>
       
   529 
       
   530 3) There must be at least a space between <A> </A> for IE5.5 to see the 
       
   531    anchor tag correctly. Do not do <A></A> with no space.
       
   532 
       
   533 4) When a PopupWindow object is created, a handler for 'onmouseup' is
       
   534    attached to any event handler you may have already defined. Do NOT define
       
   535    an event handler for 'onmouseup' after you define a PopupWindow object or
       
   536    the autoHide() will not work correctly.
       
   537 */ 
       
   538 
       
   539 // Set the position of the popup window based on the anchor
       
   540 function PopupWindow_getXYPosition(anchorname) {
       
   541 	var coordinates;
       
   542 	if (this.type == "WINDOW") {
       
   543 		coordinates = getAnchorWindowPosition(anchorname);
       
   544 		}
       
   545 	else {
       
   546 		coordinates = getAnchorPosition(anchorname);
       
   547 		}
       
   548 	this.x = coordinates.x;
       
   549 	this.y = coordinates.y;
       
   550 	}
       
   551 // Set width/height of DIV/popup window
       
   552 function PopupWindow_setSize(width,height) {
       
   553 	this.width = width;
       
   554 	this.height = height;
       
   555 	}
       
   556 // Fill the window with contents
       
   557 function PopupWindow_populate(contents) {
       
   558 	this.contents = contents;
       
   559 	this.populated = false;
       
   560 	}
       
   561 // Set the URL to go to
       
   562 function PopupWindow_setUrl(url) {
       
   563 	this.url = url;
       
   564 	}
       
   565 // Set the window popup properties
       
   566 function PopupWindow_setWindowProperties(props) {
       
   567 	this.windowProperties = props;
       
   568 	}
       
   569 // Refresh the displayed contents of the popup
       
   570 function PopupWindow_refresh() {
       
   571 	if (this.divName != null) {
       
   572 		// refresh the DIV object
       
   573 		if (this.use_gebi) {
       
   574 			document.getElementById(this.divName).innerHTML = this.contents;
       
   575 			}
       
   576 		else if (this.use_css) { 
       
   577 			document.all[this.divName].innerHTML = this.contents;
       
   578 			}
       
   579 		else if (this.use_layers) { 
       
   580 			var d = document.layers[this.divName]; 
       
   581 			d.document.open();
       
   582 			d.document.writeln(this.contents);
       
   583 			d.document.close();
       
   584 			}
       
   585 		}
       
   586 	else {
       
   587 		if (this.popupWindow != null && !this.popupWindow.closed) {
       
   588 			if (this.url!="") {
       
   589 				this.popupWindow.location.href=this.url;
       
   590 				}
       
   591 			else {
       
   592 				this.popupWindow.document.open();
       
   593 				this.popupWindow.document.writeln(this.contents);
       
   594 				this.popupWindow.document.close();
       
   595 			}
       
   596 			this.popupWindow.focus();
       
   597 			}
       
   598 		}
       
   599 	}
       
   600 // Position and show the popup, relative to an anchor object
       
   601 function PopupWindow_showPopup(anchorname) {
       
   602 	this.getXYPosition(anchorname);
       
   603 	this.x += this.offsetX;
       
   604 	this.y += this.offsetY;
       
   605 	if (!this.populated && (this.contents != "")) {
       
   606 		this.populated = true;
       
   607 		this.refresh();
       
   608 		}
       
   609 	if (this.divName != null) {
       
   610 		// Show the DIV object
       
   611 		if (this.use_gebi) {
       
   612 			document.getElementById(this.divName).style.left = this.x + "px";
       
   613 			document.getElementById(this.divName).style.top = this.y + "px";
       
   614 			document.getElementById(this.divName).style.visibility = "visible";
       
   615 			}
       
   616 		else if (this.use_css) {
       
   617 			document.all[this.divName].style.left = this.x;
       
   618 			document.all[this.divName].style.top = this.y;
       
   619 			document.all[this.divName].style.visibility = "visible";
       
   620 			}
       
   621 		else if (this.use_layers) {
       
   622 			document.layers[this.divName].left = this.x;
       
   623 			document.layers[this.divName].top = this.y;
       
   624 			document.layers[this.divName].visibility = "visible";
       
   625 			}
       
   626 		}
       
   627 	else {
       
   628 		if (this.popupWindow == null || this.popupWindow.closed) {
       
   629 			// If the popup window will go off-screen, move it so it doesn't
       
   630 			if (this.x<0) { this.x=0; }
       
   631 			if (this.y<0) { this.y=0; }
       
   632 			if (screen && screen.availHeight) {
       
   633 				if ((this.y + this.height) > screen.availHeight) {
       
   634 					this.y = screen.availHeight - this.height;
       
   635 					}
       
   636 				}
       
   637 			if (screen && screen.availWidth) {
       
   638 				if ((this.x + this.width) > screen.availWidth) {
       
   639 					this.x = screen.availWidth - this.width;
       
   640 					}
       
   641 				}
       
   642 			var avoidAboutBlank = window.opera || ( document.layers && !navigator.mimeTypes['*'] ) || navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled );
       
   643 			this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");
       
   644 			}
       
   645 		this.refresh();
       
   646 		}
       
   647 	}
       
   648 // Hide the popup
       
   649 function PopupWindow_hidePopup() {
       
   650 	if (this.divName != null) {
       
   651 		if (this.use_gebi) {
       
   652 			document.getElementById(this.divName).style.visibility = "hidden";
       
   653 			}
       
   654 		else if (this.use_css) {
       
   655 			document.all[this.divName].style.visibility = "hidden";
       
   656 			}
       
   657 		else if (this.use_layers) {
       
   658 			document.layers[this.divName].visibility = "hidden";
       
   659 			}
       
   660 		}
       
   661 	else {
       
   662 		if (this.popupWindow && !this.popupWindow.closed) {
       
   663 			this.popupWindow.close();
       
   664 			this.popupWindow = null;
       
   665 			}
       
   666 		}
       
   667 	}
       
   668 // Pass an event and return whether or not it was the popup DIV that was clicked
       
   669 function PopupWindow_isClicked(e) {
       
   670 	if (this.divName != null) {
       
   671 		if (this.use_layers) {
       
   672 			var clickX = e.pageX;
       
   673 			var clickY = e.pageY;
       
   674 			var t = document.layers[this.divName];
       
   675 			if ((clickX > t.left) && (clickX < t.left+t.clip.width) && (clickY > t.top) && (clickY < t.top+t.clip.height)) {
       
   676 				return true;
       
   677 				}
       
   678 			else { return false; }
       
   679 			}
       
   680 		else if (document.all) { // Need to hard-code this to trap IE for error-handling
       
   681 			var t = window.event.srcElement;
       
   682 			while (t.parentElement != null) {
       
   683 				if (t.id==this.divName) {
       
   684 					return true;
       
   685 					}
       
   686 				t = t.parentElement;
       
   687 				}
       
   688 			return false;
       
   689 			}
       
   690 		else if (this.use_gebi && e) {
       
   691 			var t = e.originalTarget;
       
   692 			while (t.parentNode != null) {
       
   693 				if (t.id==this.divName) {
       
   694 					return true;
       
   695 					}
       
   696 				t = t.parentNode;
       
   697 				}
       
   698 			return false;
       
   699 			}
       
   700 		return false;
       
   701 		}
       
   702 	return false;
       
   703 	}
       
   704 
       
   705 // Check an onMouseDown event to see if we should hide
       
   706 function PopupWindow_hideIfNotClicked(e) {
       
   707 	if (this.autoHideEnabled && !this.isClicked(e)) {
       
   708 		this.hidePopup();
       
   709 		}
       
   710 	}
       
   711 // Call this to make the DIV disable automatically when mouse is clicked outside it
       
   712 function PopupWindow_autoHide() {
       
   713 	this.autoHideEnabled = true;
       
   714 	}
       
   715 // This global function checks all PopupWindow objects onmouseup to see if they should be hidden
       
   716 function PopupWindow_hidePopupWindows(e) {
       
   717 	for (var i=0; i<popupWindowObjects.length; i++) {
       
   718 		if (popupWindowObjects[i] != null) {
       
   719 			var p = popupWindowObjects[i];
       
   720 			p.hideIfNotClicked(e);
       
   721 			}
       
   722 		}
       
   723 	}
       
   724 // Run this immediately to attach the event listener
       
   725 function PopupWindow_attachListener() {
       
   726 	if (document.layers) {
       
   727 		document.captureEvents(Event.MOUSEUP);
       
   728 		}
       
   729 	window.popupWindowOldEventListener = document.onmouseup;
       
   730 	if (window.popupWindowOldEventListener != null) {
       
   731 		document.onmouseup = new Function("window.popupWindowOldEventListener(); PopupWindow_hidePopupWindows();");
       
   732 		}
       
   733 	else {
       
   734 		document.onmouseup = PopupWindow_hidePopupWindows;
       
   735 		}
       
   736 	}
       
   737 // CONSTRUCTOR for the PopupWindow object
       
   738 // Pass it a DIV name to use a DHTML popup, otherwise will default to window popup
       
   739 function PopupWindow() {
       
   740 	if (!window.popupWindowIndex) { window.popupWindowIndex = 0; }
       
   741 	if (!window.popupWindowObjects) { window.popupWindowObjects = new Array(); }
       
   742 	if (!window.listenerAttached) {
       
   743 		window.listenerAttached = true;
       
   744 		PopupWindow_attachListener();
       
   745 		}
       
   746 	this.index = popupWindowIndex++;
       
   747 	popupWindowObjects[this.index] = this;
       
   748 	this.divName = null;
       
   749 	this.popupWindow = null;
       
   750 	this.width=0;
       
   751 	this.height=0;
       
   752 	this.populated = false;
       
   753 	this.visible = false;
       
   754 	this.autoHideEnabled = false;
       
   755 	
       
   756 	this.contents = "";
       
   757 	this.url="";
       
   758 	this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";
       
   759 	if (arguments.length>0) {
       
   760 		this.type="DIV";
       
   761 		this.divName = arguments[0];
       
   762 		}
       
   763 	else {
       
   764 		this.type="WINDOW";
       
   765 		}
       
   766 	this.use_gebi = false;
       
   767 	this.use_css = false;
       
   768 	this.use_layers = false;
       
   769 	if (document.getElementById) { this.use_gebi = true; }
       
   770 	else if (document.all) { this.use_css = true; }
       
   771 	else if (document.layers) { this.use_layers = true; }
       
   772 	else { this.type = "WINDOW"; }
       
   773 	this.offsetX = 0;
       
   774 	this.offsetY = 0;
       
   775 	// Method mappings
       
   776 	this.getXYPosition = PopupWindow_getXYPosition;
       
   777 	this.populate = PopupWindow_populate;
       
   778 	this.setUrl = PopupWindow_setUrl;
       
   779 	this.setWindowProperties = PopupWindow_setWindowProperties;
       
   780 	this.refresh = PopupWindow_refresh;
       
   781 	this.showPopup = PopupWindow_showPopup;
       
   782 	this.hidePopup = PopupWindow_hidePopup;
       
   783 	this.setSize = PopupWindow_setSize;
       
   784 	this.isClicked = PopupWindow_isClicked;
       
   785 	this.autoHide = PopupWindow_autoHide;
       
   786 	this.hideIfNotClicked = PopupWindow_hideIfNotClicked;
       
   787 	}
       
   788 
       
   789 /* SOURCE FILE: CalendarPopup.js */
       
   790 
       
   791 // HISTORY
       
   792 // ------------------------------------------------------------------
       
   793 // Feb 7, 2005: Fixed a CSS styles to use px unit
       
   794 // March 29, 2004: Added check in select() method for the form field
       
   795 //      being disabled. If it is, just return and don't do anything.
       
   796 // March 24, 2004: Fixed bug - when month name and abbreviations were
       
   797 //      changed, date format still used original values.
       
   798 // January 26, 2004: Added support for drop-down month and year
       
   799 //      navigation (Thanks to Chris Reid for the idea)
       
   800 // September 22, 2003: Fixed a minor problem in YEAR calendar with
       
   801 //      CSS prefix.
       
   802 // August 19, 2003: Renamed the function to get styles, and made it
       
   803 //      work correctly without an object reference
       
   804 // August 18, 2003: Changed showYearNavigation and 
       
   805 //      showYearNavigationInput to optionally take an argument of
       
   806 //      true or false
       
   807 // July 31, 2003: Added text input option for year navigation.
       
   808 //      Added a per-calendar CSS prefix option to optionally use 
       
   809 //      different styles for different calendars.
       
   810 // July 29, 2003: Fixed bug causing the Today link to be clickable 
       
   811 //      even though today falls in a disabled date range.
       
   812 //      Changed formatting to use pure CSS, allowing greater control
       
   813 //      over look-and-feel options.
       
   814 // June 11, 2003: Fixed bug causing the Today link to be unselectable
       
   815 //      under certain cases when some days of week are disabled
       
   816 // March 14, 2003: Added ability to disable individual dates or date
       
   817 //      ranges, display as light gray and strike-through
       
   818 // March 14, 2003: Removed dependency on graypixel.gif and instead 
       
   819 ///     use table border coloring
       
   820 // March 12, 2003: Modified showCalendar() function to allow optional
       
   821 //      start-date parameter
       
   822 // March 11, 2003: Modified select() function to allow optional
       
   823 //      start-date parameter
       
   824 /* 
       
   825 DESCRIPTION: This object implements a popup calendar to allow the user to
       
   826 select a date, month, quarter, or year.
       
   827 
       
   828 COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
       
   829 positioning errors - usually with Window positioning - occur on the 
       
   830 Macintosh platform.
       
   831 The calendar can be modified to work for any location in the world by 
       
   832 changing which weekday is displayed as the first column, changing the month
       
   833 names, and changing the column headers for each day.
       
   834 
       
   835 USAGE:
       
   836 // Create a new CalendarPopup object of type WINDOW
       
   837 var cal = new CalendarPopup(); 
       
   838 
       
   839 // Create a new CalendarPopup object of type DIV using the DIV named 'mydiv'
       
   840 var cal = new CalendarPopup('mydiv'); 
       
   841 
       
   842 // Easy method to link the popup calendar with an input box. 
       
   843 cal.select(inputObject, anchorname, dateFormat);
       
   844 // Same method, but passing a default date other than the field's current value
       
   845 cal.select(inputObject, anchorname, dateFormat, '01/02/2000');
       
   846 // This is an example call to the popup calendar from a link to populate an 
       
   847 // input box. Note that to use this, date.js must also be included!!
       
   848 <A HREF="#" onClick="cal.select(document.forms[0].date,'anchorname','MM/dd/yyyy'); return false;">Select</A>
       
   849 
       
   850 // Set the type of date select to be used. By default it is 'date'.
       
   851 cal.setDisplayType(type);
       
   852 
       
   853 // When a date, month, quarter, or year is clicked, a function is called and
       
   854 // passed the details. You must write this function, and tell the calendar
       
   855 // popup what the function name is.
       
   856 // Function to be called for 'date' select receives y, m, d
       
   857 cal.setReturnFunction(functionname);
       
   858 // Function to be called for 'month' select receives y, m
       
   859 cal.setReturnMonthFunction(functionname);
       
   860 // Function to be called for 'quarter' select receives y, q
       
   861 cal.setReturnQuarterFunction(functionname);
       
   862 // Function to be called for 'year' select receives y
       
   863 cal.setReturnYearFunction(functionname);
       
   864 
       
   865 // Show the calendar relative to a given anchor
       
   866 cal.showCalendar(anchorname);
       
   867 
       
   868 // Hide the calendar. The calendar is set to autoHide automatically
       
   869 cal.hideCalendar();
       
   870 
       
   871 // Set the month names to be used. Default are English month names
       
   872 cal.setMonthNames("January","February","March",...);
       
   873 
       
   874 // Set the month abbreviations to be used. Default are English month abbreviations
       
   875 cal.setMonthAbbreviations("Jan","Feb","Mar",...);
       
   876 
       
   877 // Show navigation for changing by the year, not just one month at a time
       
   878 cal.showYearNavigation();
       
   879 
       
   880 // Show month and year dropdowns, for quicker selection of month of dates
       
   881 cal.showNavigationDropdowns();
       
   882 
       
   883 // Set the text to be used above each day column. The days start with 
       
   884 // sunday regardless of the value of WeekStartDay
       
   885 cal.setDayHeaders("S","M","T",...);
       
   886 
       
   887 // Set the day for the first column in the calendar grid. By default this
       
   888 // is Sunday (0) but it may be changed to fit the conventions of other
       
   889 // countries.
       
   890 cal.setWeekStartDay(1); // week is Monday - Sunday
       
   891 
       
   892 // Set the weekdays which should be disabled in the 'date' select popup. You can
       
   893 // then allow someone to only select week end dates, or Tuedays, for example
       
   894 cal.setDisabledWeekDays(0,1); // To disable selecting the 1st or 2nd days of the week
       
   895 
       
   896 // Selectively disable individual days or date ranges. Disabled days will not
       
   897 // be clickable, and show as strike-through text on current browsers.
       
   898 // Date format is any format recognized by parseDate() in date.js
       
   899 // Pass a single date to disable:
       
   900 cal.addDisabledDates("2003-01-01");
       
   901 // Pass null as the first parameter to mean "anything up to and including" the
       
   902 // passed date:
       
   903 cal.addDisabledDates(null, "01/02/03");
       
   904 // Pass null as the second parameter to mean "including the passed date and
       
   905 // anything after it:
       
   906 cal.addDisabledDates("Jan 01, 2003", null);
       
   907 // Pass two dates to disable all dates inbetween and including the two
       
   908 cal.addDisabledDates("January 01, 2003", "Dec 31, 2003");
       
   909 
       
   910 // When the 'year' select is displayed, set the number of years back from the 
       
   911 // current year to start listing years. Default is 2.
       
   912 // This is also used for year drop-down, to decide how many years +/- to display
       
   913 cal.setYearSelectStartOffset(2);
       
   914 
       
   915 // Text for the word "Today" appearing on the calendar
       
   916 cal.setTodayText("Today");
       
   917 
       
   918 // The calendar uses CSS classes for formatting. If you want your calendar to
       
   919 // have unique styles, you can set the prefix that will be added to all the
       
   920 // classes in the output.
       
   921 // For example, normal output may have this:
       
   922 //     <SPAN CLASS="cpTodayTextDisabled">Today<SPAN>
       
   923 // But if you set the prefix like this:
       
   924 cal.setCssPrefix("Test");
       
   925 // The output will then look like:
       
   926 //     <SPAN CLASS="TestcpTodayTextDisabled">Today<SPAN>
       
   927 // And you can define that style somewhere in your page.
       
   928 
       
   929 // When using Year navigation, you can make the year be an input box, so
       
   930 // the user can manually change it and jump to any year
       
   931 cal.showYearNavigationInput();
       
   932 
       
   933 // Set the calendar offset to be different than the default. By default it
       
   934 // will appear just below and to the right of the anchorname. So if you have
       
   935 // a text box where the date will go and and anchor immediately after the
       
   936 // text box, the calendar will display immediately under the text box.
       
   937 cal.offsetX = 20;
       
   938 cal.offsetY = 20;
       
   939 
       
   940 NOTES:
       
   941 1) Requires the functions in AnchorPosition.js and PopupWindow.js
       
   942 
       
   943 2) Your anchor tag MUST contain both NAME and ID attributes which are the 
       
   944    same. For example:
       
   945    <A NAME="test" ID="test"> </A>
       
   946 
       
   947 3) There must be at least a space between <A> </A> for IE5.5 to see the 
       
   948    anchor tag correctly. Do not do <A></A> with no space.
       
   949 
       
   950 4) When a CalendarPopup object is created, a handler for 'onmouseup' is
       
   951    attached to any event handler you may have already defined. Do NOT define
       
   952    an event handler for 'onmouseup' after you define a CalendarPopup object 
       
   953    or the autoHide() will not work correctly.
       
   954    
       
   955 5) The calendar popup display uses style sheets to make it look nice.
       
   956 
       
   957 */ 
       
   958 
       
   959 // CONSTRUCTOR for the CalendarPopup Object
       
   960 function CalendarPopup() {
       
   961 	var c;
       
   962 	if (arguments.length>0) {
       
   963 		c = new PopupWindow(arguments[0]);
       
   964 		}
       
   965 	else {
       
   966 		c = new PopupWindow();
       
   967 		c.setSize(150,175);
       
   968 		}
       
   969 	c.offsetX = -152;
       
   970 	c.offsetY = 25;
       
   971 	c.autoHide();
       
   972 	// Calendar-specific properties
       
   973 	c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
       
   974 	c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
       
   975 	c.dayHeaders = new Array("S","M","T","W","T","F","S");
       
   976 	c.returnFunction = "CP_tmpReturnFunction";
       
   977 	c.returnMonthFunction = "CP_tmpReturnMonthFunction";
       
   978 	c.returnQuarterFunction = "CP_tmpReturnQuarterFunction";
       
   979 	c.returnYearFunction = "CP_tmpReturnYearFunction";
       
   980 	c.weekStartDay = 0;
       
   981 	c.isShowYearNavigation = false;
       
   982 	c.displayType = "date";
       
   983 	c.disabledWeekDays = new Object();
       
   984 	c.disabledDatesExpression = "";
       
   985 	c.yearSelectStartOffset = 2;
       
   986 	c.currentDate = null;
       
   987 	c.todayText="Today";
       
   988 	c.cssPrefix="";
       
   989 	c.isShowNavigationDropdowns=false;
       
   990 	c.isShowYearNavigationInput=false;
       
   991 	window.CP_calendarObject = null;
       
   992 	window.CP_targetInput = null;
       
   993 	window.CP_dateFormat = "MM/dd/yyyy";
       
   994 	// Method mappings
       
   995 	c.copyMonthNamesToWindow = CP_copyMonthNamesToWindow;
       
   996 	c.setReturnFunction = CP_setReturnFunction;
       
   997 	c.setReturnMonthFunction = CP_setReturnMonthFunction;
       
   998 	c.setReturnQuarterFunction = CP_setReturnQuarterFunction;
       
   999 	c.setReturnYearFunction = CP_setReturnYearFunction;
       
  1000 	c.setMonthNames = CP_setMonthNames;
       
  1001 	c.setMonthAbbreviations = CP_setMonthAbbreviations;
       
  1002 	c.setDayHeaders = CP_setDayHeaders;
       
  1003 	c.setWeekStartDay = CP_setWeekStartDay;
       
  1004 	c.setDisplayType = CP_setDisplayType;
       
  1005 	c.setDisabledWeekDays = CP_setDisabledWeekDays;
       
  1006 	c.addDisabledDates = CP_addDisabledDates;
       
  1007 	c.setYearSelectStartOffset = CP_setYearSelectStartOffset;
       
  1008 	c.setTodayText = CP_setTodayText;
       
  1009 	c.showYearNavigation = CP_showYearNavigation;
       
  1010 	c.showCalendar = CP_showCalendar;
       
  1011 	c.hideCalendar = CP_hideCalendar;
       
  1012 	c.getStyles = getCalendarStyles;
       
  1013 	c.refreshCalendar = CP_refreshCalendar;
       
  1014 	c.getCalendar = CP_getCalendar;
       
  1015 	c.select = CP_select;
       
  1016 	c.setCssPrefix = CP_setCssPrefix;
       
  1017 	c.showNavigationDropdowns = CP_showNavigationDropdowns;
       
  1018 	c.showYearNavigationInput = CP_showYearNavigationInput;
       
  1019 	c.copyMonthNamesToWindow();
       
  1020 	// Return the object
       
  1021 	return c;
       
  1022 	}
       
  1023 function CP_copyMonthNamesToWindow() {
       
  1024 	// Copy these values over to the date.js 
       
  1025 	if (typeof(window.MONTH_NAMES)!="undefined" && window.MONTH_NAMES!=null) {
       
  1026 		window.MONTH_NAMES = new Array();
       
  1027 		for (var i=0; i<this.monthNames.length; i++) {
       
  1028 			window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthNames[i];
       
  1029 		}
       
  1030 		for (var i=0; i<this.monthAbbreviations.length; i++) {
       
  1031 			window.MONTH_NAMES[window.MONTH_NAMES.length] = this.monthAbbreviations[i];
       
  1032 		}
       
  1033 	}
       
  1034 }
       
  1035 // Temporary default functions to be called when items clicked, so no error is thrown
       
  1036 function CP_tmpReturnFunction(y,m,d) { 
       
  1037 	if (window.CP_targetInput!=null) {
       
  1038 		var dt = new Date(y,m-1,d,0,0,0);
       
  1039 		if (window.CP_calendarObject!=null) { window.CP_calendarObject.copyMonthNamesToWindow(); }
       
  1040 		window.CP_targetInput.value = formatDate(dt,window.CP_dateFormat);
       
  1041 		// Kieran - fixed issue	with end date not becoming begin date after begin date is set
       
  1042 		if (CP_targetInput.name == 'event_begin') {
       
  1043 			document.forms['quoteform'].event_end.value = formatDate(dt,window.CP_dateFormat);
       
  1044                 }
       
  1045 		}
       
  1046 	else {
       
  1047 		alert('Use setReturnFunction() to define which function will get the clicked results!'); 
       
  1048 		}
       
  1049 	}
       
  1050 function CP_tmpReturnMonthFunction(y,m) { 
       
  1051 	alert('Use setReturnMonthFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , month='+m); 
       
  1052 	}
       
  1053 function CP_tmpReturnQuarterFunction(y,q) { 
       
  1054 	alert('Use setReturnQuarterFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , quarter='+q); 
       
  1055 	}
       
  1056 function CP_tmpReturnYearFunction(y) { 
       
  1057 	alert('Use setReturnYearFunction() to define which function will get the clicked results!\nYou clicked: year='+y); 
       
  1058 	}
       
  1059 
       
  1060 // Set the name of the functions to call to get the clicked item
       
  1061 function CP_setReturnFunction(name) { this.returnFunction = name; }
       
  1062 function CP_setReturnMonthFunction(name) { this.returnMonthFunction = name; }
       
  1063 function CP_setReturnQuarterFunction(name) { this.returnQuarterFunction = name; }
       
  1064 function CP_setReturnYearFunction(name) { this.returnYearFunction = name; }
       
  1065 
       
  1066 // Over-ride the built-in month names
       
  1067 function CP_setMonthNames() {
       
  1068 	for (var i=0; i<arguments.length; i++) { this.monthNames[i] = arguments[i]; }
       
  1069 	this.copyMonthNamesToWindow();
       
  1070 	}
       
  1071 
       
  1072 // Over-ride the built-in month abbreviations
       
  1073 function CP_setMonthAbbreviations() {
       
  1074 	for (var i=0; i<arguments.length; i++) { this.monthAbbreviations[i] = arguments[i]; }
       
  1075 	this.copyMonthNamesToWindow();
       
  1076 	}
       
  1077 
       
  1078 // Over-ride the built-in column headers for each day
       
  1079 function CP_setDayHeaders() {
       
  1080 	for (var i=0; i<arguments.length; i++) { this.dayHeaders[i] = arguments[i]; }
       
  1081 	}
       
  1082 
       
  1083 // Set the day of the week (0-7) that the calendar display starts on
       
  1084 // This is for countries other than the US whose calendar displays start on Monday(1), for example
       
  1085 function CP_setWeekStartDay(day) { this.weekStartDay = day; }
       
  1086 
       
  1087 // Show next/last year navigation links
       
  1088 function CP_showYearNavigation() { this.isShowYearNavigation = (arguments.length>0)?arguments[0]:true; }
       
  1089 
       
  1090 // Which type of calendar to display
       
  1091 function CP_setDisplayType(type) {
       
  1092 	if (type!="date"&&type!="week-end"&&type!="month"&&type!="quarter"&&type!="year") { alert("Invalid display type! Must be one of: date,week-end,month,quarter,year"); return false; }
       
  1093 	this.displayType=type;
       
  1094 	}
       
  1095 
       
  1096 // How many years back to start by default for year display
       
  1097 function CP_setYearSelectStartOffset(num) { this.yearSelectStartOffset=num; }
       
  1098 
       
  1099 // Set which weekdays should not be clickable
       
  1100 function CP_setDisabledWeekDays() {
       
  1101 	this.disabledWeekDays = new Object();
       
  1102 	for (var i=0; i<arguments.length; i++) { this.disabledWeekDays[arguments[i]] = true; }
       
  1103 	}
       
  1104 	
       
  1105 // Disable individual dates or ranges
       
  1106 // Builds an internal logical test which is run via eval() for efficiency
       
  1107 function CP_addDisabledDates(start, end) {
       
  1108 	if (arguments.length==1) { end=start; }
       
  1109 	if (start==null && end==null) { return; }
       
  1110 	if (this.disabledDatesExpression!="") { this.disabledDatesExpression+= "||"; }
       
  1111 	if (start!=null) { start = parseDate(start); start=""+start.getFullYear()+LZ(start.getMonth()+1)+LZ(start.getDate());}
       
  1112 	if (end!=null) { end=parseDate(end); end=""+end.getFullYear()+LZ(end.getMonth()+1)+LZ(end.getDate());}
       
  1113 	if (start==null) { this.disabledDatesExpression+="(ds<="+end+")"; }
       
  1114 	else if (end  ==null) { this.disabledDatesExpression+="(ds>="+start+")"; }
       
  1115 	else { this.disabledDatesExpression+="(ds>="+start+"&&ds<="+end+")"; }
       
  1116 	}
       
  1117 	
       
  1118 // Set the text to use for the "Today" link
       
  1119 function CP_setTodayText(text) {
       
  1120 	this.todayText = text;
       
  1121 	}
       
  1122 
       
  1123 // Set the prefix to be added to all CSS classes when writing output
       
  1124 function CP_setCssPrefix(val) { 
       
  1125 	this.cssPrefix = val; 
       
  1126 	}
       
  1127 
       
  1128 // Show the navigation as an dropdowns that can be manually changed
       
  1129 function CP_showNavigationDropdowns() { this.isShowNavigationDropdowns = (arguments.length>0)?arguments[0]:true; }
       
  1130 
       
  1131 // Show the year navigation as an input box that can be manually changed
       
  1132 function CP_showYearNavigationInput() { this.isShowYearNavigationInput = (arguments.length>0)?arguments[0]:true; }
       
  1133 
       
  1134 // Hide a calendar object
       
  1135 function CP_hideCalendar() {
       
  1136 	if (arguments.length > 0) { window.popupWindowObjects[arguments[0]].hidePopup(); }
       
  1137 	else { this.hidePopup(); }
       
  1138 	}
       
  1139 
       
  1140 // Refresh the contents of the calendar display
       
  1141 function CP_refreshCalendar(index) {
       
  1142 	var calObject = window.popupWindowObjects[index];
       
  1143 	if (arguments.length>1) { 
       
  1144 		calObject.populate(calObject.getCalendar(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]));
       
  1145 		}
       
  1146 	else {
       
  1147 		calObject.populate(calObject.getCalendar());
       
  1148 		}
       
  1149 	calObject.refresh();
       
  1150 	}
       
  1151 
       
  1152 // Populate the calendar and display it
       
  1153 function CP_showCalendar(anchorname) {
       
  1154 	if (arguments.length>1) {
       
  1155 		if (arguments[1]==null||arguments[1]=="") {
       
  1156 			this.currentDate=new Date();
       
  1157 			}
       
  1158 		else {
       
  1159 			this.currentDate=new Date(parseDate(arguments[1]));
       
  1160 			}
       
  1161 		}
       
  1162 	this.populate(this.getCalendar());
       
  1163 	this.showPopup(anchorname);
       
  1164 	}
       
  1165 
       
  1166 // Simple method to interface popup calendar with a text-entry box
       
  1167 function CP_select(inputobj, linkname, format) {
       
  1168 	var selectedDate=(arguments.length>3)?arguments[3]:null;
       
  1169 	if (!window.getDateFromFormat) {
       
  1170 		alert("calendar.select: To use this method you must also include 'date.js' for date formatting");
       
  1171 		return;
       
  1172 		}
       
  1173 	if (this.displayType!="date"&&this.displayType!="week-end") {
       
  1174 		alert("calendar.select: This function can only be used with displayType 'date' or 'week-end'");
       
  1175 		return;
       
  1176 		}
       
  1177 	if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") { 
       
  1178 		alert("calendar.select: Input object passed is not a valid form input object"); 
       
  1179 		window.CP_targetInput=null;
       
  1180 		return;
       
  1181 		}
       
  1182 	if (inputobj.disabled) { return; } // Can't use calendar input on disabled form input!
       
  1183 	window.CP_targetInput = inputobj;
       
  1184 	window.CP_calendarObject = this;
       
  1185 	this.currentDate=null;
       
  1186 	var time=0;
       
  1187 	if (selectedDate!=null) {
       
  1188 		time = getDateFromFormat(selectedDate,format)
       
  1189 		}
       
  1190 	else if (inputobj.value!="") {
       
  1191 		time = getDateFromFormat(inputobj.value,format);
       
  1192 		}
       
  1193 	if (selectedDate!=null || inputobj.value!="") {
       
  1194 		if (time==0) { this.currentDate=null; }
       
  1195 		else { this.currentDate=new Date(time); }
       
  1196 		}
       
  1197 	window.CP_dateFormat = format;
       
  1198 	this.showCalendar(linkname);
       
  1199 	}
       
  1200 	
       
  1201 // Get style block needed to display the calendar correctly
       
  1202 function getCalendarStyles() {
       
  1203 	var result = "";
       
  1204 	var p = "";
       
  1205 	if (this!=null && typeof(this.cssPrefix)!="undefined" && this.cssPrefix!=null && this.cssPrefix!="") { p=this.cssPrefix; }
       
  1206 	result += "<STYLE>\n";
       
  1207 	result += "."+p+"cpYearNavigation,."+p+"cpMonthNavigation { background-color:#C0C0C0; text-align:center; vertical-align:center; text-decoration:none; color:#000000; font-weight:bold; }\n";
       
  1208 	result += "."+p+"cpDayColumnHeader, ."+p+"cpYearNavigation,."+p+"cpMonthNavigation,."+p+"cpCurrentMonthDate,."+p+"cpCurrentMonthDateDisabled,."+p+"cpOtherMonthDate,."+p+"cpOtherMonthDateDisabled,."+p+"cpCurrentDate,."+p+"cpCurrentDateDisabled,."+p+"cpTodayText,."+p+"cpTodayTextDisabled,."+p+"cpText { font-family:arial; font-size:8pt; }\n";
       
  1209 	result += "TD."+p+"cpDayColumnHeader { text-align:right; border:solid thin #C0C0C0;border-width:0px 0px 1px 0px; }\n";
       
  1210 	result += "."+p+"cpCurrentMonthDate, ."+p+"cpOtherMonthDate, ."+p+"cpCurrentDate  { text-align:right; text-decoration:none; }\n";
       
  1211 	result += "."+p+"cpCurrentMonthDateDisabled, ."+p+"cpOtherMonthDateDisabled, ."+p+"cpCurrentDateDisabled { color:#D0D0D0; text-align:right; text-decoration:line-through; }\n";
       
  1212 	result += "."+p+"cpCurrentMonthDate, .cpCurrentDate { color:#000000; }\n";
       
  1213 	result += "."+p+"cpOtherMonthDate { color:#808080; }\n";
       
  1214 	result += "TD."+p+"cpCurrentDate { color:white; background-color: #C0C0C0; border-width:1px; border:solid thin #800000; }\n";
       
  1215 	result += "TD."+p+"cpCurrentDateDisabled { border-width:1px; border:solid thin #FFAAAA; }\n";
       
  1216 	result += "TD."+p+"cpTodayText, TD."+p+"cpTodayTextDisabled { border:solid thin #C0C0C0; border-width:1px 0px 0px 0px;}\n";
       
  1217 	result += "A."+p+"cpTodayText, SPAN."+p+"cpTodayTextDisabled { height:20px; }\n";
       
  1218 	result += "A."+p+"cpTodayText { color:black; }\n";
       
  1219 	result += "."+p+"cpTodayTextDisabled { color:#D0D0D0; }\n";
       
  1220 	result += "."+p+"cpBorder { border:solid thin #808080; }\n";
       
  1221 	result += "</STYLE>\n";
       
  1222 	return result;
       
  1223 	}
       
  1224 
       
  1225 // Return a string containing all the calendar code to be displayed
       
  1226 function CP_getCalendar() {
       
  1227 	var now = new Date();
       
  1228 	// Reference to window
       
  1229 	if (this.type == "WINDOW") { var windowref = "window.opener."; }
       
  1230 	else { var windowref = ""; }
       
  1231 	var result = "";
       
  1232 	// If POPUP, write entire HTML document
       
  1233 	if (this.type == "WINDOW") {
       
  1234 		result += "<HTML><HEAD><TITLE>Calendar</TITLE>"+this.getStyles()+"</HEAD><BODY MARGINWIDTH=0 MARGINHEIGHT=0 TOPMARGIN=0 RIGHTMARGIN=0 LEFTMARGIN=0>\n";
       
  1235 		result += '<CENTER><TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>\n';
       
  1236 		}
       
  1237 	else {
       
  1238 		result += '<TABLE CLASS="'+this.cssPrefix+'cpBorder" WIDTH=144 BORDER=1 BORDERWIDTH=1 CELLSPACING=0 CELLPADDING=1>\n';
       
  1239 		result += '<TR><TD ALIGN=CENTER>\n';
       
  1240 		result += '<CENTER>\n';
       
  1241 		}
       
  1242 	// Code for DATE display (default)
       
  1243 	// -------------------------------
       
  1244 	if (this.displayType=="date" || this.displayType=="week-end") {
       
  1245 		if (this.currentDate==null) { this.currentDate = now; }
       
  1246 		if (arguments.length > 0) { var month = arguments[0]; }
       
  1247 			else { var month = this.currentDate.getMonth()+1; }
       
  1248 		if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1]; }
       
  1249 			else { var year = this.currentDate.getFullYear(); }
       
  1250 		var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
       
  1251 		if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) {
       
  1252 			daysinmonth[2] = 29;
       
  1253 			}
       
  1254 		var current_month = new Date(year,month-1,1);
       
  1255 		var display_year = year;
       
  1256 		var display_month = month;
       
  1257 		var display_date = 1;
       
  1258 		var weekday= current_month.getDay();
       
  1259 		var offset = 0;
       
  1260 		
       
  1261 		offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;
       
  1262 		if (offset > 0) {
       
  1263 			display_month--;
       
  1264 			if (display_month < 1) { display_month = 12; display_year--; }
       
  1265 			display_date = daysinmonth[display_month]-offset+1;
       
  1266 			}
       
  1267 		var next_month = month+1;
       
  1268 		var next_month_year = year;
       
  1269 		if (next_month > 12) { next_month=1; next_month_year++; }
       
  1270 		var last_month = month-1;
       
  1271 		var last_month_year = year;
       
  1272 		if (last_month < 1) { last_month=12; last_month_year--; }
       
  1273 		var date_class;
       
  1274 		if (this.type!="WINDOW") {
       
  1275 			result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
       
  1276 			}
       
  1277 		result += '<TR>\n';
       
  1278 		var refresh = windowref+'CP_refreshCalendar';
       
  1279 		var refreshLink = 'javascript:' + refresh;
       
  1280 		if (this.isShowNavigationDropdowns) {
       
  1281 			result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="78" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpMonthNavigation" name="cpMonth" onChange="'+refresh+'('+this.index+',this.options[this.selectedIndex].value-0,'+(year-0)+');">';
       
  1282 			for( var monthCounter=1; monthCounter<=12; monthCounter++ ) {
       
  1283 				var selected = (monthCounter==month) ? 'SELECTED' : '';
       
  1284 				result += '<option value="'+monthCounter+'" '+selected+'>'+this.monthNames[monthCounter-1]+'</option>';
       
  1285 				}
       
  1286 			result += '</select></TD>';
       
  1287 			result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';
       
  1288 
       
  1289 			result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="56" COLSPAN="3"><select CLASS="'+this.cssPrefix+'cpYearNavigation" name="cpYear" onChange="'+refresh+'('+this.index+','+month+',this.options[this.selectedIndex].value-0);">';
       
  1290 			for( var yearCounter=year-this.yearSelectStartOffset; yearCounter<=year+this.yearSelectStartOffset; yearCounter++ ) {
       
  1291 				var selected = (yearCounter==year) ? 'SELECTED' : '';
       
  1292 				result += '<option value="'+yearCounter+'" '+selected+'>'+yearCounter+'</option>';
       
  1293 				}
       
  1294 			result += '</select></TD>';
       
  1295 			}
       
  1296 		else {
       
  1297 			if (this.isShowYearNavigation) {
       
  1298 				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;</A></TD>';
       
  1299 				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="58"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+'</SPAN></TD>';
       
  1300 				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;</A></TD>';
       
  1301 				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="10">&nbsp;</TD>';
       
  1302 
       
  1303 				result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year-1)+');">&lt;</A></TD>';
       
  1304 				if (this.isShowYearNavigationInput) {
       
  1305 					result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><INPUT NAME="cpYear" CLASS="'+this.cssPrefix+'cpYearNavigation" SIZE="4" MAXLENGTH="4" VALUE="'+year+'" onBlur="'+refresh+'('+this.index+','+month+',this.value-0);"></TD>';
       
  1306 					}
       
  1307 				else {
       
  1308 					result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="36"><SPAN CLASS="'+this.cssPrefix+'cpYearNavigation">'+year+'</SPAN></TD>';
       
  1309 					}
       
  1310 				result += '<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="10"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="'+refreshLink+'('+this.index+','+month+','+(year+1)+');">&gt;</A></TD>';
       
  1311 				}
       
  1312 			else {
       
  1313 				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+last_month+','+last_month_year+');">&lt;&lt;</A></TD>\n';
       
  1314 				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="100"><SPAN CLASS="'+this.cssPrefix+'cpMonthNavigation">'+this.monthNames[month-1]+' '+year+'</SPAN></TD>\n';
       
  1315 				result += '<TD CLASS="'+this.cssPrefix+'cpMonthNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpMonthNavigation" HREF="'+refreshLink+'('+this.index+','+next_month+','+next_month_year+');">&gt;&gt;</A></TD>\n';
       
  1316 				}
       
  1317 			}
       
  1318 		result += '</TR></TABLE>\n';
       
  1319 		result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=0 CELLPADDING=1 ALIGN=CENTER>\n';
       
  1320 		result += '<TR>\n';
       
  1321 		for (var j=0; j<7; j++) {
       
  1322 
       
  1323 			result += '<TD CLASS="'+this.cssPrefix+'cpDayColumnHeader" WIDTH="14%"><SPAN CLASS="'+this.cssPrefix+'cpDayColumnHeader">'+this.dayHeaders[(this.weekStartDay+j)%7]+'</TD>\n';
       
  1324 			}
       
  1325 		result += '</TR>\n';
       
  1326 		for (var row=1; row<=6; row++) {
       
  1327 			result += '<TR>\n';
       
  1328 			for (var col=1; col<=7; col++) {
       
  1329 				var disabled=false;
       
  1330 				if (this.disabledDatesExpression!="") {
       
  1331 					var ds=""+display_year+LZ(display_month)+LZ(display_date);
       
  1332 					eval("disabled=("+this.disabledDatesExpression+")");
       
  1333 					}
       
  1334 				var dateClass = "";
       
  1335 				if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) {
       
  1336 					dateClass = "cpCurrentDate";
       
  1337 					}
       
  1338 				else if (display_month == month) {
       
  1339 					dateClass = "cpCurrentMonthDate";
       
  1340 					}
       
  1341 				else {
       
  1342 					dateClass = "cpOtherMonthDate";
       
  1343 					}
       
  1344 				if (disabled || this.disabledWeekDays[col-1]) {
       
  1345 					result += '	<TD CLASS="'+this.cssPrefix+dateClass+'"><SPAN CLASS="'+this.cssPrefix+dateClass+'Disabled">'+display_date+'</SPAN></TD>\n';
       
  1346 					}
       
  1347 				else {
       
  1348 					var selected_date = display_date;
       
  1349 					var selected_month = display_month;
       
  1350 					var selected_year = display_year;
       
  1351 					if (this.displayType=="week-end") {
       
  1352 						var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0);
       
  1353 						d.setDate(d.getDate() + (7-col));
       
  1354 						selected_year = d.getYear();
       
  1355 						if (selected_year < 1000) { selected_year += 1900; }
       
  1356 						selected_month = d.getMonth()+1;
       
  1357 						selected_date = d.getDate();
       
  1358 						}
       
  1359 					result += '	<TD CLASS="'+this.cssPrefix+dateClass+'"><A HREF="javascript:'+windowref+this.returnFunction+'('+selected_year+','+selected_month+','+selected_date+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+this.cssPrefix+dateClass+'">'+display_date+'</A></TD>\n';
       
  1360 					}
       
  1361 				display_date++;
       
  1362 				if (display_date > daysinmonth[display_month]) {
       
  1363 					display_date=1;
       
  1364 					display_month++;
       
  1365 					}
       
  1366 				if (display_month > 12) {
       
  1367 					display_month=1;
       
  1368 					display_year++;
       
  1369 					}
       
  1370 				}
       
  1371 			result += '</TR>';
       
  1372 			}
       
  1373 		var current_weekday = now.getDay() - this.weekStartDay;
       
  1374 		if (current_weekday < 0) {
       
  1375 			current_weekday += 7;
       
  1376 			}
       
  1377 		result += '<TR>\n';
       
  1378 		result += '	<TD COLSPAN=7 ALIGN=CENTER CLASS="'+this.cssPrefix+'cpTodayText">\n';
       
  1379 		if (this.disabledDatesExpression!="") {
       
  1380 			var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());
       
  1381 			eval("disabled=("+this.disabledDatesExpression+")");
       
  1382 			}
       
  1383 		if (disabled || this.disabledWeekDays[current_weekday+1]) {
       
  1384 			result += '		<SPAN CLASS="'+this.cssPrefix+'cpTodayTextDisabled">'+this.todayText+'</SPAN>\n';
       
  1385 			}
       
  1386 		else {
       
  1387 			result += '		<A CLASS="'+this.cssPrefix+'cpTodayText" HREF="javascript:'+windowref+this.returnFunction+'(\''+now.getFullYear()+'\',\''+(now.getMonth()+1)+'\',\''+now.getDate()+'\');'+windowref+'CP_hideCalendar(\''+this.index+'\');">'+this.todayText+'</A>\n';
       
  1388 			}
       
  1389 		result += '		<BR>\n';
       
  1390 		result += '	</TD></TR></TABLE></CENTER></TD></TR></TABLE>\n';
       
  1391 	}
       
  1392 
       
  1393 	// Code common for MONTH, QUARTER, YEAR
       
  1394 	// ------------------------------------
       
  1395 	if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") {
       
  1396 		if (arguments.length > 0) { var year = arguments[0]; }
       
  1397 		else { 
       
  1398 			if (this.displayType=="year") {	var year = now.getFullYear()-this.yearSelectStartOffset; }
       
  1399 			else { var year = now.getFullYear(); }
       
  1400 			}
       
  1401 		if (this.displayType!="year" && this.isShowYearNavigation) {
       
  1402 			result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
       
  1403 			result += '<TR>\n';
       
  1404 			result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-1)+');">&lt;&lt;</A></TD>\n';
       
  1405 			result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="100">'+year+'</TD>\n';
       
  1406 			result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="22"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+1)+');">&gt;&gt;</A></TD>\n';
       
  1407 			result += '</TR></TABLE>\n';
       
  1408 			}
       
  1409 		}
       
  1410 		
       
  1411 	// Code for MONTH display 
       
  1412 	// ----------------------
       
  1413 	if (this.displayType=="month") {
       
  1414 		// If POPUP, write entire HTML document
       
  1415 		result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
       
  1416 		for (var i=0; i<4; i++) {
       
  1417 			result += '<TR>';
       
  1418 			for (var j=0; j<3; j++) {
       
  1419 				var monthindex = ((i*3)+j);
       
  1420 				result += '<TD WIDTH=33% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnMonthFunction+'('+year+','+(monthindex+1)+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+this.monthAbbreviations[monthindex]+'</A></TD>';
       
  1421 				}
       
  1422 			result += '</TR>';
       
  1423 			}
       
  1424 		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
       
  1425 		}
       
  1426 	
       
  1427 	// Code for QUARTER display
       
  1428 	// ------------------------
       
  1429 	if (this.displayType=="quarter") {
       
  1430 		result += '<BR><TABLE WIDTH=120 BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER>\n';
       
  1431 		for (var i=0; i<2; i++) {
       
  1432 			result += '<TR>';
       
  1433 			for (var j=0; j<2; j++) {
       
  1434 				var quarter = ((i*2)+j+1);
       
  1435 				result += '<TD WIDTH=50% ALIGN=CENTER><BR><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnQuarterFunction+'('+year+','+quarter+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">Q'+quarter+'</A><BR><BR></TD>';
       
  1436 				}
       
  1437 			result += '</TR>';
       
  1438 			}
       
  1439 		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
       
  1440 		}
       
  1441 
       
  1442 	// Code for YEAR display
       
  1443 	// ---------------------
       
  1444 	if (this.displayType=="year") {
       
  1445 		var yearColumnSize = 4;
       
  1446 		result += "<TABLE WIDTH=144 BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
       
  1447 		result += '<TR>\n';
       
  1448 		result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year-(yearColumnSize*2))+');">&lt;&lt;</A></TD>\n';
       
  1449 		result += '	<TD CLASS="'+this.cssPrefix+'cpYearNavigation" WIDTH="50%"><A CLASS="'+this.cssPrefix+'cpYearNavigation" HREF="javascript:'+windowref+'CP_refreshCalendar('+this.index+','+(year+(yearColumnSize*2))+');">&gt;&gt;</A></TD>\n';
       
  1450 		result += '</TR></TABLE>\n';
       
  1451 		result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
       
  1452 		for (var i=0; i<yearColumnSize; i++) {
       
  1453 			for (var j=0; j<2; j++) {
       
  1454 				var currentyear = year+(j*yearColumnSize)+i;
       
  1455 				result += '<TD WIDTH=50% ALIGN=CENTER><A CLASS="'+this.cssPrefix+'cpText" HREF="javascript:'+windowref+this.returnYearFunction+'('+currentyear+');'+windowref+'CP_hideCalendar(\''+this.index+'\');" CLASS="'+date_class+'">'+currentyear+'</A></TD>';
       
  1456 				}
       
  1457 			result += '</TR>';
       
  1458 			}
       
  1459 		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
       
  1460 		}
       
  1461 	// Common
       
  1462 	if (this.type == "WINDOW") {
       
  1463 		result += "</BODY></HTML>\n";
       
  1464 		}
       
  1465 	return result;
       
  1466 	}
       
  1467