/* -------------------------------------------------------------------
    JavaScript Event Calendar
        By: Peter McBride
        Version: 1.0b
        Date: September 15, 2008
        
    Creates a configurable Event Calendar using JavaScript and CSS.
    Events may have links and may be applied to a specific date or
    week.
    
    Certain events may be restricted so that only specific viewer
    may see them, while other viewers see only "public" events.
    
    You may toggle visibility of restricted events using the query
    string in your URL, or by issuing a JavaScript command.
    
    A special "Admin" mode is enabled allowing certain viewers to 
    see ALL restricted events at once.
    
    This event calendar was designed to be used in higher educational
    institutions but is readily adaptable to other organizational
    needs.
    
    The Event Calendar uses the full HTML TABLE spec, including
    table captions, th and other "old school" methods instead of
    using pure CSS solutions. This was done to make the calendar
    easily customizable by a wider audience, and to allow easy
    styling by including any commonly-available CSS stylesheets
    that modify generic table data. Google "CSS Table formatting" 
    as there are several forums on this topic. Simply download
    one of their templates and include it after the EventCalendar.css
    stylesheet on your webpage.
    
    FULL DOCUMENTTION PENDING
        
---------------------------------------------------------------------*/


function EventCalendar(strTargetID){
    var $ = this;
    
    $.init = function(strTargetID){
    
        // This is where the event calendar will appear : It should be the ID of a div somewhere on your webpage.
        // Once the page is fully loaded, we'll look for that DIV and will place the calendar there, or you can 
        // leave this value blank and explicitly make a call to EventCalendar.draw() to create it on demand.
        $.TargetDiv = strTargetID;
        $.SpecialDay=1;	// 1=Sunday, 2=Monday, . . . 7=Saturday
        
        // Create the array of month names (used in various places). Array is one-based so first item is ignored.
        // This array can be overridden to localize your calendar... Janjuar, anyone?
        $.Months = (",January,February,March,April,May,June,July,August,September,October,November,December").split(",");


        // Initialize the range of the calendar to Jan - Dec of the current year.  Calls to DefineEvent( ) will change this
        // as needed; it is also possible to explicitly override the range before calling Calendar( ) from the HTML page.

        $.Today = new Date();
        $.FirstMonth=$.GetFullYear($.Today) * 100 + 1;
        $.LastMonth=$.FirstMonth + 11;
        $.Events = new Array;
        $.WeeklyEvents = new Array;
        $.HolidayEvents = new Array;
        $.CodeStr = "";
        $.QS = new Querystring();
        
        // The special events (CSS class identifiers) specified below will be displayed by default
        $.ShowSpecialEvent = $.QS.get("ShowRestricted","")

        $.YearMonth =  parseInt($.QS.get("yrmo"));
        
        // Don't do jack until we're actually done loading the page. If TargetDiv has been defined,
        // create an event listener to draw the calendar when it's fully loaded, otherwise do nothing
        // but wait for the page to call the draw() method:
        if($.TargetDiv !== 'undefined'){
            if (typeof window.addEventListener !== 'undefined')  {
                window.addEventListener('load', function() { $.DrawEventCalendar(); }, false);
            } else if (typeof window.attachEvent !== 'undefined') {
                window.attachEvent('onload', function() { $.DrawEventCalendar(); });
            }
        }

    }

    $.DefineEvent=function(nEventDate, strEventDescription, strEventLink, strCSSClass, strEventHoliday) {
	    var _tmp;
	    strCSSClass = (strCSSClass!=undefined)?strCSSClass:"";
	    // Build the HTML string for this event: image (optional), link (optional), and description
	    _tmp = "<div class='CalEvent " + strCSSClass +"'>";
    	
	    if ((strEventLink != "")&&(strEventLink != undefined)){
		    _tmp += '<a href="' + strEventLink + '">';
	    }
    	
	    _tmp += strEventDescription 
	    if ((strEventLink != "")&&(strEventLink != undefined)){
	        _tmp += '</a>';
        }
        _tmp += "</div>";

	    // If an event already exists for this date, append the new event to it.
	    if ($.Events[nEventDate]){
		    $.Events[nEventDate] +=  _tmp;
	    }else{
		    $.Events[nEventDate] = _tmp;
                  }

     // Defines the class for specified for a holiday event  --> defaults to DefaultHolidayEvent
        if (strEventHoliday != undefined)
        { 
	$.HolidayEvents[nEventDate] = " " + strEventHoliday;
        }
   

    // Adjust the minimum and maximum month & year to include this date
	    _tmp = Math.floor(nEventDate / 100);
	    if (_tmp < $.FirstMonth) $.FirstMonth = _tmp;
	    if (_tmp > $.LastMonth) $.LastMonth = _tmp;
    }

    $.DefineWeeklyEvent=function(nEventDate, strEventDescription, strEventLink, strCSSClass) {
        // nEventDate can be any day in the desired week, ie 20081001 = first week of rocktober
        
	    var _tmp;
	    strCSSClass = (strCSSClass!=undefined)?strCSSClass:"";

	    // Build the HTML string for this event: image (optional), link (optional), and description
	    _tmp = "<div class='CalEvent " + strCSSClass +"'>";
    	
	    if ((strEventLink != "")&&(strEventLink != undefined)){
		    _tmp += '<a href="' + strEventLink + '">';
	    }
    	
	    _tmp += strEventDescription 
	    if ((strEventLink != "")&&(strEventLink != undefined)){
	        _tmp += '</a>';
        }
        _tmp += "</div>";


	    // If an event already exists for this date, append the new event to it.
	    if ($.WeeklyEvents[nEventDate]){
		    $.WeeklyEvents[nEventDate] +=  _tmp;
	    } else {
		    $.WeeklyEvents[nEventDate] = _tmp;
        }
        
	    // Adjust the minimum and maximum month & year to include this date
	    _tmp = Math.floor(nEventDate / 100);
	    if (_tmp < $.FirstMonth) $.FirstMonth = _tmp;
	    if (_tmp > $.LastMonth) $.LastMonth = _tmp;
    	
	    //alert($.WeeklyEvents[nEventDate])
    }

    // Used to create "safe" callbacks for the global namespace. This allows multiple copies
    // of the Event Calendar to be used without fear of collision.
    $.RandomName=function(){
        var _rname="EvtCal$";
        for (var i = 0; i < 16; i++) {
            _rname += String.fromCharCode(Math.floor(Math.random() * 26) + 97);
        }
        return _rname;
    }


    $.makeElement=function(tgt,type,id,css,text){
            var _elem = document.createElement(type);
	        if(id){
	            _elem.id= id;
	        }    
	        if(css){
	            _elem.setAttribute("class", css); 
                _elem.setAttribute("className", css); 
            }
            if(text){
                _elem.appendChild(document.createTextNode(text))
            }
            if(tgt){
                tgt.appendChild(_elem)
            }
        return _elem;
    }
    
    
    $.DrawEventCalendar=function(strDefaultCSSIdentifier) {
   
        // By default, only "public" events are shown -those that are seen by every visitor to the page.
        // Certain visitors, however, will be allowed to see "restricted" events meant only for them. 
        // Students of the "ICS114" course, for example, will see all public events, but will also
        // want to see course-specific material that is hidden to other students.
        //
        // There are several ways to do this depending on when the desicion to show restricted events
        // is made. When the page is first drawn we can use the ShowRestricted query param:
        //    http://www.foo.com/EventCalendar.htm?ShowRestricted=ICS114
        //
        // After the Event Calendar is drawn we can call the draw() function  directly, supplying the argument:
        //    calendar.draw("ICS114");
        // Which redraws the calendar showing the new data.
        // 
        // The special imperative "admin" may be used as well, which toggles ALL restricted events on,eg:
        //    http://www.foo.com/EventCalendar.htm?ShowRestricted=admin  or  calendar.draw("admin");
        
        
        // By default, show no restricted events. However, if the global $.ShowSpecialEvent is defined by
        // the document's query string, use that, unless the draw() method is specifically told to use
        // something else, found in strDefaultCSSIdentifier:
        var _showSpecialEvent = $.ShowSpecialEvent;
        if(strDefaultCSSIdentifier !== undefined){
            _showSpecialEvent = strDefaultCSSIdentifier;
        }
    
        // This routine is the one which actually creates the calendar. If a DIV with the id equal to  $.TargetDiv 
        // has been defined and exists, it will be placed within there, otherwise it will be placed at the end of the <body> element.
        
	    var _curdy, _curmo, _year, mo, dy, _sDayOfWeek, _nYearMonth, bgn, lastday, jump;
	    var _arrWeekdays = ("Week,Sun,Mon,Tue,Wed,Thu,Fri,Sat").split(","); //Array is one-based.
	    
	    var _thispage = window.location.pathname;

	    // Save current day and month for comparison
	    _curdy = $.Today.getDate();
	    _curmo = $.Today.getMonth()+1;

	    // Default to current month and year
	    mo = _curmo;
	    _year = $.GetFullYear($.Today);
	    _nYearMonth = (_year * 100) + mo;

	    // If querystring parameter is present, get the month/year ("calendar.htm?yrmo=YYYYMM)
	    if($.YearMonth!=undefined){
	    
		    if (String($.YearMonth).length == 6) {
		        _nYearMonth=$.YearMonth;
			    mo = _nYearMonth % 100;
			    _year = (_nYearMonth - mo) / 100;
		    }
	    }
	    
	    //alert($.FirstMonth)
	    //alert($.LastMonth)

	    // Constrain to the range of months with events
	    if (_nYearMonth < $.FirstMonth) {
		    mo = $.FirstMonth % 100;
		    _year = ($.FirstMonth - mo) / 100;
		    _nYearMonth = $.FirstMonth;
	    }
	    if (_nYearMonth > $.LastMonth) {
		    mo = $.LastMonth % 100;
		    _year = ($.LastMonth - mo) / 100;
		    _nYearMonth = $.LastMonth;
	    }

	    // Create a date object for the first day of the desired month
	    bgn = new Date($.Months[mo] + " 1," + _year);
	    // Get the day-of-week of the first day, and the # days in the month
	    _sDayOfWeek = bgn.getDay();
	    lastday = $.NumDaysIn(mo,_year);
	    	    
	    	    
	    	    
	    // ---------------------------------------------------------------------
	    // Insert the calendar into the visible part of the page. We must 
	    // do this here instead of later on because of a bug with innerHTML
	    // in IE7. Clear any existing calendar that might be there already.
	    // ---------------------------------------------------------------------
		var _targetDiv;
		if($.TargetDiv){
		    _targetDiv = document.getElementById($.TargetDiv);
		    _targetDiv.innerHTML = "";
	    }

	    // ---------------------------------------------------------------------
	    // Create the calendar using DOM commands
	    // ---------------------------------------------------------------------
	    $.Calendar = $.makeElement(_targetDiv,"table",'Calendar', " Calendar Calendar"+_year+mo+" Calendar"+_year+" Calendar"+mo);
	    var _specialRestrictionTitle = ($.ShowSpecialEvent=="") ? "   " : " ["+$.ShowSpecialEvent+"]   ";
        var _calTitle = $.makeElement($.Calendar,"caption","","CalTitle",$.Months[mo]+" "+_year+" " + _specialRestrictionTitle);
        
	    // ---------------------------------------------------------------------
	    // For admins, create a popup menu showing all restricted events
	    // ---------------------------------------------------------------------
        if($.Courses!=undefined){
            var _RestrictedEventsPopup = $.makeElement(_calTitle,"select","RestrictedEventsPopup", $.ShowSpecialEvent);
            _RestrictedEventsPopup.onchange = function(){$.RestrictedEventsPopupHandler(this)}; 
            var _opt
            _opt = $.makeElement(_RestrictedEventsPopup,'option',false,false, "Show All");
            _opt.setAttribute('value', 'admin');
            _opt.selected = true;
            _opt = $.makeElement(_RestrictedEventsPopup,'option',false,false, "Show None");
            _opt.setAttribute('value', '');
            
            for (myClass in $.Courses){
                _opt = $.makeElement(_RestrictedEventsPopup,'option',false,false,$.Courses[myClass]);
                _opt.setAttribute('value',$.Courses[myClass]);
            }
        }
    	
    	var _thead = $.makeElement($.Calendar,'thead')	;
    	
    	// ---------------------------------------------------------------------
    	// Next/Prev Month Links
    	// ---------------------------------------------------------------------
    	_trow = $.makeElement(_thead,'tr',false,false,false);
        _th = $.makeElement(_trow,'th',false,false,false);
        _th.setAttribute("colSpan", "8");
        _th.setAttribute("align", "center");
        _td = $.makeElement(_th,'span',"PrevMonth",(_nYearMonth<=$.FirstMonth)?"Offlink":"ChangeDateLink",'<<< View '+$.Months[$.PrevMonth(mo)]);    
        _td.onclick = function(){
            $.YearMonth = parseInt($.PrevYearMonth(_nYearMonth));
            $.DrawEventCalendar();
        }
        _td = $.makeElement(_th,'span',false,false,' | ');    
        _td = $.makeElement(_th,'span',"NextMonth",(_nYearMonth>=$.LastMonth)?"Offlink":"ChangeDateLink",'View '+$.Months[$.NextMonth(mo)]+' >>>');    
        _td.onclick = function(){
            $.YearMonth = parseInt($.NextYearMonth(_nYearMonth));
            $.DrawEventCalendar();
        }

    	
    	var _theadrow = $.makeElement(_thead,'tr','','CalDayTitles',false);
    	var _theadrowth;
    	
    	
    	
	    for (var i=0;i<=7;i++){
	        _theadrowth = $.makeElement(_theadrow,'th','',"CalDayTitle CalDayTitle" + _arrWeekdays[i] ,_arrWeekdays[i]);
	        _theadrowth.setAttribute('width',"*");
	        _theadrowth.setAttribute('align',"CENTER");
	    }
	    
	    var _tbody = $.makeElement($.Calendar,'tbody','RestrictedEventSwitch','',false);
	    
	    var _trow = $.makeElement(_tbody,'tr',false,'CalWeek CalWeek1',false);
	    var _trowth = $.makeElement(_trow,'th','CalWeek1',false,false);
	    var _trowthdiv = $.makeElement(_trowth,'div',false,false,false);
	    
	    dy = 1;
	    // Special handling for the first week of the month
	    var _daycell
	    for (var i=1;i<=7;i++) {
		    // If the day is less than the day of the week determined to be the first day
		    // of the month, print a space in this cell of the table.
		    if (i <= _sDayOfWeek){
		        _daycell = $.makeElement(_trow,'td',false,'CalCell CalVoid'," ");
		        _daycell.setAttribute('align',"CENTER");
		    }
		    // Otherwise, write date and the event, if any, in this cell of the table.
		    else {
			    _daycell = $.ShowDate(_year,mo,dy,i,_curmo,_curdy, _arrWeekdays[i], 1 );
			    _trow.appendChild(_daycell)
			    dy++;
		    }
	    }
	    // Rest of the weeks . . .
	    var weeknum=1
	    while (dy <= lastday) {
		    weeknum++;
            var isOdd = (weeknum%2==0)?"odd":""
            _trow = $.makeElement(_tbody,'tr',false,'CalWeek CalWeek1' + weeknum + " " + isOdd,false);
            _trowth = $.makeElement(_trow,'th','CalWeek' + weeknum,false,false);
            _trowthdiv = $.makeElement(_trowth,'div',false,false,false);


		    for (var i=1;i<=7;i++) {
			    if (dy > lastday) {
			        _daycell = $.makeElement(_trow,'td',false,'CalCell CalVoid'," ");
			    } else {
				    _daycell = $.ShowDate(_year,mo,dy,i,_curmo,_curdy, _arrWeekdays[i], weeknum );
			        _trow.appendChild(_daycell);
			        dy++;
			    }
		    }
	    }
        var _tfoot = $.makeElement($.Calendar,'tfoot','classes','all',false);
        
        
    	// ---------------------------------------------------------------------
    	// Next/Prev Month Links
    	// ---------------------------------------------------------------------

		_trow = $.makeElement(_tfoot,'tr',false,false,false);
        _th = $.makeElement(_trow,'th',false,false,false);
        _th.setAttribute("colSpan", "8");
        _th.setAttribute("align", "center");
        _td = $.makeElement(_th,'span',"PrevMonth",(_nYearMonth<=$.FirstMonth)?"Offlink":"ChangeDateLink",'<<< View '+$.Months[$.PrevMonth(mo)]);    
        _td.onclick = function(){
            $.YearMonth = parseInt($.PrevYearMonth(_nYearMonth));
            $.DrawEventCalendar();
        }
        _td = $.makeElement(_th,'span',false,false,' | ');    
        _td = $.makeElement(_th,'span',"NextMonth",(_nYearMonth>=$.LastMonth)?"Offlink":"ChangeDateLink",'View '+$.Months[$.NextMonth(mo)]+' >>>');    
        _td.onclick = function(){
            $.YearMonth = parseInt($.NextYearMonth(_nYearMonth));
            $.DrawEventCalendar();
        }
        

	    _trow = $.makeElement(_tfoot,'tr',false,false,false);
        _th = $.makeElement(_trow,'th',false,false,false);
        _th.setAttribute("colSpan", "8");
        _th.setAttribute("align", "center");
        _th.setAttribute("valign", "middle");
		$.BuildSelectionList(_th, _nYearMonth, _thispage);

        $.ShowRestrictedEvent(_showSpecialEvent);
    }

    // Display a date in the appropriate color, with events (if there are any)

    $.ShowDate=function(nYear, mo, dy, _sDayOfWeek, currentmonth, currentday, daytitle, weeknum) {
	    var ind, HighlightEvent, _tmp;
        
        var _classes = 'CalCell CalDay CalDay' + daytitle;
	    HighlightEvent = true;
	    if (_sDayOfWeek == $.SpecialDay) {
		     _classes +=  (" CalSpecialDay");
		    HighlightEvent = false;
	    }
	    if ((mo == currentmonth) && (dy == currentday)) {
		    _classes +=  (" CalCurrentDay");
		    HighlightEvent = false;
	    }
	    ind = (((nYear * 100) + mo) * 100) + dy;
	    if ($.Events[ind]) {
		    _tmp = $.Events[ind];
		    if (HighlightEvent) {
			      _classes +=  (" CalEvents");
		    }
	    } else {
	        _tmp="&nbsp;&nbsp;";
	    }

    	    if ($.HolidayEvents[ind]!=undefined)
	    {
		_classes +=  ($.HolidayEvents[ind]);

	    }
	    if ($.WeeklyEvents[ind]) {
	        var targetCell = document.getElementById("CalWeek" + weeknum )
	        if(targetCell!=null){
	            targetCell.innerHTML += $.WeeklyEvents[ind];
	        }

        }
    	 var _daycell = $.makeElement(false, 'td', false, _classes, false);
    	 var _date = $.makeElement(_daycell,'div',false,'CalDate',dy);
    	 
        _daycell.innerHTML+=(_tmp);
	    return _daycell;
    }


    // Remaining routines are utilities used above

    $.NumDaysIn=function(mo,nYear) {
	    if (mo==4 || mo==6 || mo==9 || mo==11) return 30;
	    else if ((mo==2) && $.LeapYear(nYear)) return 29;
	    else if (mo==2) return 28;
	    else return 31;
    }

    $.LeapYear=function(nYear) {
	    if (((nYear % 4 == 0) && nYear % 100 != 0) || nYear % 400 == 0) return true;
	    else return false;
    }

    // fixes a Netscape 2 and 3 bug, not that thats ever going to happen!
    $.GetFullYear=function(d) { // d is a date object
	    var _yr;
	    _yr = d.getYear();
	    if (_yr < 1000){
	        _yr +=1900;
	    };
	    return _yr;
    }

    $.PrevMonth=function(mth) {
	    if (mth == 1) return 12;
	    else return (mth-1);
    }

    $.NextMonth=function(mth) {
	    if (mth == 12) return 1;
	    else return (mth+1);
    }

    $.PrevYearMonth=function(yrmth) {
	    if ((yrmth % 100) == 1) return ((yrmth-100)+11);
	    else return (yrmth-1);
    }

    $.NextYearMonth=function(yrmth) {
	    if ((yrmth % 100) == 12) return ((yrmth-11)+100);
	    else return (yrmth+1);
    }

    $.ChooseMonthPopupHandler=function(){
        var sel =  document.getElementById("JumpDatePopup").selectedIndex
        $.ShowYearMonth(document.getElementById("JumpDatePopup")[sel].value);
    }
    
    $.ShowYearMonth=function(yrmo){
        $.YearMonth = parseInt(yrmo)
        $.DrawEventCalendar();
    }
    
    $.BuildSelectionList=function(targ, current, thispage) {
	    var mo, _year, _nYearMonth;
        var _JumpDatePopup = $.makeElement(targ,"select","JumpDatePopup")
        _JumpDatePopup.onchange = function(){$.ChooseMonthPopupHandler(this)}; 
        var _opt
  
	    _nYearMonth = $.FirstMonth;
	    while (_nYearMonth <= $.LastMonth) {
		    mo = _nYearMonth % 100;
		    _year = (_nYearMonth - mo) / 100;
		   _opt = $.makeElement(_JumpDatePopup,'option',false,false,($.Months[mo]+" "+_year))
		    if (_nYearMonth == current){
		       _opt.selected = true;
		    }
           _opt.setAttribute('value',_nYearMonth)
 		   _nYearMonth = $.NextYearMonth(_nYearMonth);
	    }
    }
    

    $.RestrictedEventsPopupHandler=function(){
        var sel =  document.getElementById("RestrictedEventsPopup").selectedIndex
        $.ShowRestrictedEvent(document.getElementById("RestrictedEventsPopup")[sel].value);
    }
    
    $.ShowRestrictedEvent=function(strClass){
        // Currently can only display one specific class. Need to add functionaity to allow 
        // multiple splits using space char....
        var newClass = "show_" + strClass;
        var domObj = document.getElementById("RestrictedEventSwitch");
        domObj.setAttribute("class", newClass);
        domObj.setAttribute("className", newClass);
    }
   
    $.DefineCourses=function(strCourses){
        $.Courses = strCourses.split(",");
        for(myClass in  $.Courses){
            $.addCourse($.Courses[myClass])
        }
    }

    $.CreateCSS=function(_strSelector, _strDeclaration) {
        // test for IE
        var ua = navigator.userAgent.toLowerCase();
        var isIE = (/msie/.test(ua)) && !(/opera/.test(ua)) && (/win/.test(ua));

        // create the style node for all browsers
        var style_node = document.createElement("style");
        style_node.setAttribute("type", "text/css");
        style_node.setAttribute("media", "screen"); 

        // append a rule for good browsers
        if (!isIE) style_node.appendChild(document.createTextNode(_strSelector + " {" + _strDeclaration + "}"));

        // append the style node
        document.getElementsByTagName("head")[0].appendChild(style_node);

        // use alternative methods for IE
        if (isIE && document.styleSheets && document.styleSheets.length > 0) {
                var last_style_node = document.styleSheets[document.styleSheets.length - 1];
                if (typeof(last_style_node.addRule) == "object") last_style_node.addRule(_strSelector, _strDeclaration);
        }
    }
 

    $.addCourse=function(strCourseName) {
        if (!document.styleSheets) return;
        var _arrCSS = new Array();
        if (document.styleSheets[0].cssRules)  // Standards Compliant
        {
           _arrCSS = document.styleSheets[0].cssRules;
        }
        else
        {         
           _arrCSS = document.styleSheets[0].rules;  // IE 
        }

        // defaualt is to turn off any course-specific info... 
        var _strSelector = "." + strCourseName;
        var _strDeclaration = "display: none;";
        $.CreateCSS(_strSelector, _strDeclaration);

        // ...unless we precede it somewhere with the css class ".show_(whatever)", which turns it on.
        // A popup controls this switch-class(es), or... 
        var _strSelector2 = ".show_" + strCourseName + " ." + strCourseName; 
        var _strDeclaration2 = "display: block;";
        $.CreateCSS(_strSelector2, _strDeclaration2);

        // ... you can manually create a class called .admin which turns *all* courses on. /\
        // Just add it anywhre on the page where the RestrictedEvents inherit from ... html, body, calanedar etc.
        var _strSelector3 = ".show_admin ." + strCourseName; 
        var _strDeclaration3 = "display: block;";
        $.CreateCSS(_strSelector3, _strDeclaration3);
            
    }
    Querystring=function(qs) { // optionally pass a querystring to parse
	    this.params = {};
    	
	    if (qs == null) qs = location.search.substring(1, location.search.length);
	    if (qs.length == 0) return;

	    qs = qs.replace(/\+/g, ' ');
	    var args = qs.split('&'); // parse out name/value pairs separated via &
    	
        // split out each name=value pair
	    for (var i = 0; i < args.length; i++) {
		    var pair = args[i].split('=');
		    var name = decodeURIComponent(pair[0]);
    		
		    var value = (pair.length==2)
			    ? decodeURIComponent(pair[1])
			    : name;
    		
		    this.params[name] = value;
	    }
    }

    Querystring.prototype.get = function(key, default_) {
	    var value = this.params[key];
	    return (value != null) ? value : default_;
    }

    Querystring.prototype.contains = function(key) {
	    var value = this.params[key];
	    return (value != null);
    }

    $.init(strTargetID);
}