/*************************************************************************
  This code is from Dynamic Web Coding 
  at http://www.dyn-web.com/
  Copyright 2003 by Sharon Paine 
  See Terms of Use at http://www.dyn-web.com/bus/terms.html
  Permission granted to use this code 
  as long as this entire notice is included.
*************************************************************************/

dw_sizeFont = {
  sizeUnit: "px",  // Unit of measurement for body font-size 
  bodyOnly: false,  // change body font-size rule only (set true if you use %'s or em's in any font-size spec's)
  incAmount: 2,    // amount to increment/decrement per click of buttons
  maxSize: 30,     // maximun size for body font (number or null)
  minSize: 9,      // minimum size for body font (number or null)
    
  // button text (buttons generated below in code)
  // put empty strings here to place linked text/images in sizer div yourself
  increaseBtn: "Increase",
  decreaseBtn: "Decrease",
  
  skipList:  [],  // holds optional selector text list to leave untouched (can add items here or just before call to init)
  rulesList: [],   // to hold style rules that have font-size setting  
  controlList: [],  // selector text list to set min/max sizes on (populated using setControls)
  
  // check for selectorText support below
  standards: [document.getElementById, document.styleSheets, document.createElement, typeof document.body != "undefined" && typeof document.body.setAttribute != "undefined"],

  setControls: function (sel,mn,mx) {
    this.controlList[this.controlList.length] = arguments;
  },

  // called from dw_sizeFont.adjust 
  // checks controlList items, returns true if rule sent is in controlList, false if not
  // handles sizing of controlList items here too
  handleControlList: function (rule, n) {   
    var cl = this.controlList; 
    for (var i=0; i<cl.length; i++) {  
      if ( rule.selectorText.match( new RegExp("\\b" + cl[i][0] + "\\b", "i") ) ) {
        // check sizes against min/max values set for this item
        // also check to keep in synch with other values 
        if (n > 0) {
          if ( parseFloat(rule.style.fontSize) + n <= cl[i][2] 
            && ( parseFloat(rule.style.fontSize) + n ) - parseFloat( this.bodyRule.style.fontSize ) <= cl[i][3] )
              rule.style.fontSize = parseFloat(rule.style.fontSize) + n + this.sizeUnit;
          else rule.style.fontSize = cl[i][2] + this.sizeUnit;
        } else if (n < 0) {
          if ( parseFloat(rule.style.fontSize) + n >= cl[i][1] 
            && ( parseFloat(rule.style.fontSize) + n ) - parseFloat( this.bodyRule.style.fontSize ) >= cl[i][3] )
              rule.style.fontSize = parseFloat(rule.style.fontSize) + n + this.sizeUnit;
        }
        return true;
      } 
    }
    return false;
  },
  
  init: function () {
    var rules = []; // temporary storage
    var i, j;
    
    for ( i=0; i<this.standards.length; i++ ) {
      if ( !this.standards[i] ) return;
    }

    // loop through all the style sheets and collect their rules
    for ( i=0; i<document.styleSheets.length; i++ ) {
      if (document.styleSheets[i].rules) {
        rules.push( document.styleSheets[i].rules );
      } else if (document.styleSheets[i].cssRules) { 
        rules.push( document.styleSheets[i].cssRules );
        // check if cssRule is import, if so get its rules too 
        for (j=0; j<rules[i].length; j++) {
          if ( rules[i][j].type == 3 ) // type 3 is @import rule
            rules.push( rules[i][j].styleSheet.cssRules );
        }
      }
  
      if (document.styleSheets[i].imports) {  // get ie imports
        for (j=0; j<document.styleSheets[i].imports.length; j++) 
          rules.push( document.styleSheets[i].imports[j].rules );
      }
      
    } // end loop through styleSheets array 
    
    // send each style sheet's rules for further processing and storage in rulesList
    for ( i=0; i<rules.length; i++ ) {
      this.holdSizeRules( rules[i] );
    }    
    
    // add buttons or just display sizediv
    var sizediv = document.getElementById("sizer");
    if (!sizediv) { alert("Don't forget the sizer div!"); return; }
    if ( this.increaseBtn ) {
      var frm = sizediv.appendChild( document.createElement("FORM") );
      var incbtn = frm.appendChild( document.createElement("BUTTON") );
      var decbtn = frm.appendChild( document.createElement("BUTTON") );
      incbtn.appendChild( document.createTextNode(dw_sizeFont.increaseBtn) );
      decbtn.appendChild( document.createTextNode(dw_sizeFont.decreaseBtn) );
      incbtn.setAttribute( "id", "inc");  decbtn.setAttribute( "id", "dec");
      incbtn.setAttribute( "accessKey", "i");  decbtn.setAttribute( "accessKey", "r");
      incbtn.onclick = this.adjust;  decbtn.onclick = this.adjust;
      sizediv.style.display = "block";
    } else sizediv.style.display = "block";

    // check if size passed in url, if so set cookie
    if (window.location.search) 
      setCookie( "fontSize", window.location.search.slice(1), null, "/" );
    
    // cookie set? if so, use difference between body font-size and cookie value to adjust.
    // also check for bodyRule to avoid error if no support for selectorText
    if ( getCookie("fontSize") && dw_sizeFont.bodyRule ) 
      this.adjust( parseFloat( getCookie("fontSize") ) - parseFloat(dw_sizeFont.bodyRule.style.fontSize) );

    // onunload, set cookie
    window.onunload = function() {
      var expDate = new Date();
  		expDate.setMonth( expDate.getMonth() + 6 );
      setCookie( "fontSize", dw_sizeFont.bodyRule.style.fontSize, expDate, "/" );
    }
  
  },
  
  // called from init, passed each style sheet's rules
  // hold the ones that have font-size rules if they are not in the skipList
  holdSizeRules: function (rules) {
    var i, j;
    rulesCheck:
    for ( i=0; i<rules.length; i++) {
      if ( rules[i].style && rules[i].style.fontSize ) { 
        // earliest opportunity to check support for selectorText
        if ( !rules[i].selectorText ) { document.getElementById("sizer").style.display = "none"; return; }
        
        if ( rules[i].selectorText.match( new RegExp("\\bbody\\b", "i") ) ) {
          dw_sizeFont.bodyRule = rules[i]; // hold body rule for use with cookies

          // if only adjusting size of body font, hold its rule and return
          if ( this.bodyOnly ) {  
            this.rulesList.push(rules[i]);
            return;
          }
        }
        
        // check skipList 
        for ( j=0; j<this.skipList.length; j++) {
          if ( rules[i].selectorText.match( new RegExp("\\b" + this.skipList[j] + "\\b", "i") ) ) 
            continue rulesCheck;
        }
        this.rulesList.push(rules[i]);

        // for controlList, hold size relative to body font-size 
        // (to keep in synch with other sizes on adjustment)
        for ( j=0; j<this.controlList.length; j++) {
          if ( rules[i].selectorText.match( new RegExp("\\b" + this.controlList[j][0] + "\\b", "i") ) ) 
            this.controlList[j][3] = parseFloat(rules[i].style.fontSize) - parseFloat(dw_sizeFont.bodyRule.style.fontSize);
        }
      }
    }  
  
  },
  
  // manages font size changes, called onload if cookie set, and onclick of buttons/links
  // lets handleControlList check for and manage controlled selectors (controlList items)
  adjust: function (n) {
    if ( typeof n != "number" ) // if called onclick and buttons generated, no arg passed
      n = dw_sizeFont.incAmount * ( (this.id == "inc")? 1: -1 );
    
    // check against max/minSize
    if ( dw_sizeFont.maxSize ) {
      if ( n > 0 && parseFloat(dw_sizeFont.bodyRule.style.fontSize) + n > dw_sizeFont.maxSize )
        return false;
    }
    if ( dw_sizeFont.minSize ) {
      if ( n < 0 && parseFloat(dw_sizeFont.bodyRule.style.fontSize) + n < dw_sizeFont.minSize )
        return false;
    }
    
    // shorten ref's (this keyword here depends on caller)
    var unit = dw_sizeFont.sizeUnit;  
    var rules = dw_sizeFont.rulesList;  
    for (var i=0; i<rules.length; i++) {
      if ( parseFloat(rules[i].style.fontSize) + n > 0 ) { // triggers error if decrease to < 0
        // check if rule member of controlList, if so it's sizing is handled there and returns true
        if ( !dw_sizeFont.handleControlList( rules[i], n ) )
          rules[i].style.fontSize = parseFloat( rules[i].style.fontSize) + n + unit;
      }
    }
    return false; // so no form submission message
  }
  
}  

// for browsers that don't support array push method
// from 13th parallel ( www.13thparallel.org )
// push appends new elements to an array, and returns the new length
if (Array.prototype && !Array.prototype.push) {
	Array.prototype.push = function() {
		for (var i=0; i<arguments.length; i++) this[this.length] = arguments[i];
		return this.length;
	};
}
