/* THIS FILE COMBINES THE RESIZE SCRIPTS WITH THE SE HILITING so that we can do development on one file */

/* WISH LIST
Use the ID field to specify the preferred width of the figure, but to only take effect when floating.   */

/* rsz_c lists the CSS classes that are updated when the window is resized, and the threshold(s) that cause update. */
/* 

http://shrinksafe.dojotoolkit.org/

SCREEN SIZE AND WINDOW SIZE
Windows classic under XP: The screen internal width for 1024 is 996.  i.e. 28 pixels wasted for scrolling and frame.
Windows XP theme steals another pixel (i.e. 29) so the internal width is 995.
It seems reasonable to leave something like 40 pixels for the threshold.

Screen size 1024 is represented by threshold 990 below (i.e. wide figures float) with allowance of 34 pixels for windowing.
Screen size 1280 is represented by 1240 below.

1120 is width at which two boxes fit side-by-side in the index page.  
i.e. 900 pixels of content + 214 of padding (left nav and right pad) = 1114.
Three boxes side-by-side would be possible at 1350+220 = 1570, but
(a) There are currently very few visitors with screens that wide
(b) It makes sense to be more generous with the minimal box width at such large screen sizes.

It used to be that main became wide at 1120 (same as box) but the text is less than 50em wide at that point, and wide figures dont fit.
So, use a width that is closer to the next screen size of 1280 such that the text is 50em wide when the related pages
column pops up to the right.  Giving some margin as well suggests a threshold of 1240, which is 40 pixels shy of the 1280 screen size.
This also means that the wide figure does not need to stop floating (or it should never float) since the text never becomes narrower than
50em.
*/

/* 
Given that we are limiting the text to 50em width, there is no point in floating very wide figures, unless we can work out some way
to use the screen width without making the text wide - sort of figures that float to appear partially outside the text.
There does seem to be a way it can be done.
<div class="wide-figure-n" style="position:relative;left:100px;margin-left:-100px;">
moves the figure 100px to the right and releases the space for text (by means of negative margin).  Works in IE7 and Firefox.
Its a horrid hack and requires calculation of the amount to shift the figure based on the window size, which cannot really be
calculated when the text width is expressed in ems.
Was    [   'wide-figure', 990, 1350]

very-wide-figure never gets to float with text width set to 50em
 */
 /* 
 Classes listed in the array below are resized, but only on <div> objects.
 If the screen exceeds the nominated width, then the class name is set to ?-w, else to ?-n
 where ? is the class name and where the original class is ?-n or ?-w.
 
 Classes that are ?-h have automatic height adjustment applied to them when the screen width criteria is satisfied.
 The top margin is specified below.  Specifically applied to .r-o.  Magic height is applied if screen width > threshold for +ve threshold;
 for negative threshold, the test is screen width <= -threshold.
 
 Besides the classes listed below, the script has special handling for:
 .r-n/.r-w the related-layout block is only resized to -w if a .r-o block is found.
 ++ .r-o (related-outer) to detect whether or not to change the main block to wide mode or not
 .i-n/.i-w the inner main block is changed to -w if boxes are found inside it and if wide enough.
    Preferably, use the same width to trigger this change and also change to boxes themselves.
 ++ .b-n/.b-w boxes
 
 .j-n/.j-y When javascript is active, the className is changed from -n to -y. This is a one-way adjustment.
 
 ++: Classes that are recognised explicitly cannot be combined with other classes
 */
var rsz_c = [ 
    /*
    [   'screen', 500 ],
    [   'related', 1240 ],
    [   'box', 1120],
    [   'figure', 840 ],['f',840],
    [   'wide-figure', 990 ],['w',990 ]
    */
    [ 's',600],
    [ 'q',1060],
    [ 'r',1060],
    [ 'm',1060],
    [ 'i',1060],
    [ 'b',1060],
    [ 'f2',510 ],
    [ 'fb',530 ],
    [ 'f3',560 ],
    [ 'f4',610 ],
    [ 'f5',660 ],
    [ 'f6',710 ] /*,  Don't float wide figures because the text width is limited for readability
    [ 'f7',760 ],
    [ 'f8',810 ] */
    ];

// Warning: It seems that variables that are not declared are GLOBAL.
function rsz_wh()
{
  w = 1024;
  h = 600;
  if (typeof(document.width) == 'number') 
  {
      //Non-IE
      // Includes adjustment for width of the scroll bar
      // but note that the scroll bar is not present when setting the
      // width of images that are near the top of the page, so the
      // dynamic addition of the scroll bar affects image size.
      w = document.width;
      h = document.height;
  }
  if (typeof(window.innerWidth) == 'number') 
  {
      //Non-IE
      v = window.innerWidth;
      i = window.innerHeight;
      if (v < w) { w = v; }
      if (i < h) { h = i; }
  } else if (document.documentElement && document.documentElement.clientWidth) 
  {
      //IE 6+ in 'standards compliant mode'
      w = document.documentElement.clientWidth;
      h = document.documentElement.clientHeight;
  } else if (document.body && document.body.clientWidth) 
  {
      //IE 4 compatible
      w = document.body.clientWidth;
      h = document.body.clientHeight;
  }
  return new Array(w,h);
}

// Responds to screen size by changing classes on divs.
// The classes to change are recognised by ending in -n or -w
// Optimisation for future:
//   Existence of r-o passed as a parameter.
//   main-inner-n -> main-inner-w performed by sitebuilder.
function rsz() {
  // The top margin
  tm = 110;
  // First get width and height of the current page.
  wh = rsz_wh();
  w = wh[0];
  h = wh[1];
  
  // Debugging display
  /*
  y = document.getElementById('d');
  if (y)
  { y.firstChild.nodeValue = 'Width: '+w+' Height: '+h; }
  */

  // Find and process all the div tags in the document
  x = document.getElementsByTagName('div');
  l = x.length;
  for (i = 0; i < l; i++)
  {   
    // Extract the className of the div object.
    cn = x[i].className;
    c0 = cn;
    // Process each class in the list in turn and build a return result.
    r = '';
    while (cn.length > 0)
    {
      p = cn.indexOf(' ');
      if (p >= 0)
      { c = cn.substr(0,p);
        cn = cn.substr(p+1); // Rest of the string
      }
      else
      { c = cn;
        cn = '';
      }
      cl = c.length;
      
      if (r.length > 0)
      { r = r + ' '; } // Another class is being processed.

      t = 10000; // Default threshold
      if (c.indexOf('-') == cl-2)
      {
        n = c.substr(0,cl-2);

        // Look for a known class
        for (j = 0; j < rsz_c.length; j++)
        { 
          if (rsz_c[j][0] == n)
          {   
            t = rsz_c[j][1];
            // Previously we supported -x as well as -w:
            //if (rsz_c[j].length > 2)
            //{ t2 = rsz_c[j][2]; }
          }
        }
      }
      
      // If the class name ends in -n or -w then adjust it
      if (c.indexOf('-n') == cl-2 || c.indexOf('-w') == cl-2 /* || c.indexOf('-x') == cl-2 */)
      {   
        // Find the window width that decides on the class ID
        d = c.substr(cl-1); // Last character.
        // n = c.substr(0,cl-2); // n is set above.
        
        // Special handling for the related block - it only resizes if related-outer block exists.
        // When the related-n block resizes to related-w it means that the related pages should pop up,
        // and then the related block is narrow to allow for the related pages, so if the related
        // pages do not pop up on the right, then we dont want to change the related block.
        f = 1;
        if (/* n == 'related' || */ n == 'r')
        {
          f = 0;
          for (j = 0; j < l; j++)
          {   
            cc = x[j].className;
            // If f remains 0 (i.e. the related block is not found) then the class will always be -n
            if (/* cc == 'related-outer' || */ cc == 'r-o')
            { f = 1; }
          }
        }
          
        // Special handling for the main-inner block - it only resizes to -w if any box-n or box-w classes are inside.
        // This could be implemented in sitebuilder by changing the class during code generation, but for now this is easier.
        // The point is that main-inner-n is limited to 50em but main-inner-w is full width.
        if (/* n == 'main-inner' || */ n == 'i')
        {
          f = 0;
          for (j = 0; j < l; j++)
          {   
            cc = x[j].className;
            if (/* cc == 'box-n' || cc == 'box-w' || */ cc == 'b-n' || cc == 'b-w')
            { f = 1; }
          }
        }
        
        // Look for parameter in the id field
        // No longer supported
        //s = x[i].id; 
        //a = s.indexOf('(');
        //b = s.indexOf(')');
        //if (b > a && a >= 0)
        //{ t = s.substr(a+1,b-a-1); }
        
        // t is the threshold
        // f has to be true to allow it to go wide
        if (w > t && f)
        { d = "w"; }
        else
        { d = "n"; }
            
        // Special handling for the javascript active block.  Change -n to -y.
        if (n == 'j')
        { d = 'y'; }
        
        //alert(c);
        
        c = c.substr(0,cl-1) + d; 
      }
      
      // Related-outer .r-o has height set here.  Magic height.
      if (c == 'r-o' || c.indexOf("-h") == cl-2)
      {
        // n = c.substr(0,cl-2); // n is set above.
        // mt = x[i].style.marginTop;
        // l = mt.length;
        // k = 10;
        // if (mt.substr(l-2) == "px")
        // {
        //   k = parseInt(mt.substr(0,l-2));
        // }
        // k = h-k;
        k = h - tm; // Fixed top margin in this script.
        if (k <= 50) { k = 50; }
        if ((t > 0 && w > t) || (t < 0 && w <= -t))
        { x[i].style.height = ""+k+"px"; }
        else
        { x[i].style.height = ""; } // Unspecified height when screen width criteria not met
        // It is NOT a good idea to set the marginTop explicitly as it overrides CSS
        //x[i].style.marginTop = tm;
      }
      r = r + c;
    }
    
    // Change the class, but only if it is a change
    // (efficiency may be the reason - changes will trigger refresh of the display)
    if (r != c0)
    { x[i].className = r; }
  }
}

/*
There seems to be a bug in IE7:

If you set the image height in an image then you cannot access the image objects
in DOM properly after that - I think the height attributes of all images gets
broken.

This suggests that the way to handle small size images for handheld devices
is, unfortunately, to load smaller sized images using a page with smaller sizes
set.  This means that you may as well redirect the user to a collection of pages
specifically designed for handheld devices.

Firefox works with the following javascript code.
*/
/*
function rsz_i()
{
    //hh = new Array();
	w = rsz_w () - 6;
    // Find and process all the img tags in the document
    // Problem is: when you change one of the image tags (by changing its dimensions)
    // then it seems you cannot access other tags.
    // Hack: after making a change, set up the array of tags again.
    done = 0;
    while (done == 0)
    {
    x = document.getElementsByTagName('img');
    l = x.length;
    //alert(l);
    //for (i = 0; i < l; i++)
    //{	hh[i] = x[i].height;
	//	alert(hh[i]);
    //}
    done = 1;
    alert('start');
    for (i = 0; i < l; i++)
    {   
		// Resize images that are natively too wide for the screen space available.
		// This is intended only for very narrow screens, so we take the screen width,
		// subtract a small constant and then limit the image width to that amount.
		// Now, a problem is dynamic window size resizing.
		// In order to support the situation where the window is made really narrow and
		// then made wide again, we would have to know what the original dimensions
		// of the image were.  We could store that information in the object
		// perhaps, but for now we just ignore that problem and only resize images
		// at the start, so there is no response to window resize events.
		//alert(i);
		iw = x[i].width;
		//alert(iw);
		ih = x[i].height;
		//alert(ih);
		// Strange fact in IE7:
		// setting the height of image 1 makes attempt to read the height of image
		// 2 fail.
		if (iw > w)
		{
			alert(x[i].src)
			h = Math.round(ih * w/ iw);
			//alert(h);
			x[i].width = w;
			//alert(w);
			x[i].height = h;
			//alert(i);
			//x = document.getElementsByTagName('img');
			done = 0;
			break;
		}
		//alert('next');
		//alert(i);
		//alert(l);
	}
	}
}
*/
function rszim(n,a,c,iw,ih,pw)
{
	// n: Image file name
	// a: Alt text
	// c: class name
	// iw: Width
	// ih: Height
	// pw: Proportion of screen width limit (normally 1)
	
	// In narrow screen mode we have padding on the content and margins around the images.
	// The image margin is 2px and the padding is 3px so the combined space potentially required
	// is 10px.  Leave 14 for errors (makes it work in IE7 - see timber-features.html).
	wh = rsz_wh();
  w = wh[0]-14;
	if (c.length > 0)
		c = ' class="'+c+'"'
	if (iw > w * pw)
	{
		r = w * pw / iw;
		ih = Math.round(ih * r);
		iw = Math.round(iw * r);
		// Previously had option to download full size image on click, but this overrides other anchor
		// and does not seem appropriate for handheld device.
		//document.write('<a href="'+n+'"><img width="'+iw+'" height="'+ih+'" alt="Click to view full size image: '+a+'" src="'+n+'"'+c+' /></a>')
	}
	document.write('<img width="'+iw+'" height="'+ih+'" alt="'+a+'" src="'+n+'"'+c+' />')
}
function rsz_start()
{
  window.onresize=rsz;
  rsz();
  //rsz_i();
}



/* se_hilite_compress_src.js: manually compressed before applying dojo shrinksafe */

/**
 * Safe shrinking: http://alex.dojotoolkit.org/shrinksafe/
 *
 * Search Engine Keyword Highlight (http://fucoder.com/code/se-hilite/)
 *
 * This module can be imported by any HTML page, and it would analyse the
 * referrer for search engine keywords, and then highlight those keywords on
 * the page, by wrapping them around <span class="hilite">...</span> tags.
 * Document can then define styles else where to provide visual feedbacks.
 *
 * Usage:
 *
 *   In HTML. Add the following line towards the end of the document.
 *
 *     <script type="text/javascript" src="se_hilite.js"></script>
 *
 *   In CSS, define the following style:
 *
 *     .hilite { background-color: #ff0; }
 *
 *   If Hl.style_name_suffix is true, then define the follow styles:
 *
 *     .hilite1 { background-color: #ff0; }
 *     .hilite2 { background-color: #f0f; }
 *     .hilite3 { background-color: #0ff; }
 *     .hilite4 ...
 *
 * @author Scott Yang <http://scott.yang.id.au/>
 * @version 1.5
 */

// Configuration:
Hl = {
    /**
     * Element ID to be highlighted. If set, then only content inside this DOM
     * element will be highlighted, otherwise everything inside document.body
     * will be searched.
     */
    /* ei: 'content', /* elementid */
    
    /**
     * Whether we are matching an exact word. For example, searching for
     * "highlight" will only match "highlight" but not "highlighting" if exact
     * is set to true.
     */
    /* exact: true, */

    /**
     * Maximum number of DOM nodes to test, before handing the control back to
     * the GUI thread. This prevents locking up the UI when parsing and
     * replacing inside a large document.
     */
    /* max_nodes: 1000, */

    /**
     * Whether to automatically hilite a section of the HTML document, by
     * binding the "Hl.hilite()" to window.onload() event. If this
     * attribute is set to false, you can still manually trigger the hilite by
     * calling Hl.hilite() in Javascript after document has been fully
     * loaded.
     */
    /* onload: true, */

    /**
     * Name of the style to be used. Default to 'hilite'.
     */
    /* style_name: 'hilite', */
    
    /**
     * Whether to use different style names for different search keywords by
     * appending a number starting from 1, i.e. hilite1, hilite2, etc.
     */
    /* style_name_suffix: false,  /* LGCH */

    /**
     * Set it to override the document.referrer string. Used for debugging
     * only.
     */
    /* debug_referrer: '' */
};

Hl.sg = [ /* search_engines */
    ['google\\.', 'q'],                             // Google
    ['search\\.yahoo\\.', 'p'],                     // Yahoo
    ['search\\.msn\\.', 'q'],                       // MSN
    ['search\\.live\\.', 'query'],                  // MSN Live
    ['search\\.aol\\.', 'userQuery'],               // AOL
    ['ask\\.com', 'q'],                             // Ask.com
    ['altavista\\.', 'q'],                          // AltaVista
    ['feedster\\.', 'q'],                           // Feedster
    ['search\\.lycos\\.', 'q'],                     // Lycos
    ['alltheweb\\.', 'q'],                          // AllTheWeb
    ['technorati\\.com/search/([^\\?/]+)', 1],      // Technorati
    ['dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)', 1, true] // DogPile
    
    // Use this to hilite zoom search because it saves downloading more JS.
    ,['hameyvision\\..*zoom_query', 'zoom_query'] // Zoom on my site.  Referrer based so better to use zoom highlighting capability.
];

/**
 * Decode the referrer string and return a list of search keywords.
 */
Hl.dR = function(referrer) { /* decodeReferrer */
    /* var */ query = null;
    /* var */ regex = new RegExp('');

    for (/* var */ i = 0; i < Hl.sg.length; i ++) {
        /* var */ se = Hl.sg[i];
        regex.compile('^http://(www\\.)?' + se[0], 'i');
        /* var */ match = referrer.match(regex);
        if (match) {
            /* var result; */
            if (isNaN(se[1])) {
                result = Hl.dQ(referrer, se[1]);
            } else {
                result = match[se[1] + 1];
            }
            if (result) {
                result = decodeURIComponent(result);
                // XXX: DogPile's URI requires decoding twice.
                if (se.length > 2 && se[2])
                    result = decodeURIComponent(result);
                result = result.replace(/\'|"/g, '');
                result = result.split(/[\s,\+\.]+/);
                return result;
            }
            break;
        }
    }
    return null;
};

Hl.dQ = function(referrer, match) { /* decodeReferrerQS */
    /* var */ idx = referrer.indexOf('?');
    /* var  idx2; */
    if (idx >= 0) {
        /* var */ qs = new String(referrer.substring(idx + 1));
        idx  = 0;
        idx2 = 0;
        while ((idx >= 0) && ((idx2 = qs.indexOf('=', idx)) >= 0)) {
            /* var key, val; */
            key = qs.substring(idx, idx2);
            idx = qs.indexOf('&', idx2) + 1;
            if (key == match) {
                if (idx <= 0) {
                    return qs.substring(idx2+1);
                } else {
                    return qs.substring(idx2+1, idx - 1);
                }
            }
            // I am claiming credit for the following 'bug fix' but it should not be necessary given condition of the while loop
            /* LGCH */
            if (idx <= 0)
				break;
        }
    }
    return null;
};

/**
 * Highlight a DOM element with a list of keywords.
 */
Hl.hE = function(elm, query) { /* hiliteElement */
    if (!query || elm.childNodes.length == 0)
	return;

    /* var */ qre = new Array();
    for (/* var */ i = 0; i < query.length; i ++) {
        query[i] = query[i].toLowerCase();
        /* exact option.
         * 
        if (Hl.exact) */
            qre.push('\\b'+query[i]+'\\b');
        /* else
            qre.push(query[i]); */
    }

    qre = new RegExp(qre.join("|"), "i");

    /* var */ stylemapper = {};
    for (/* var */ i = 0; i < query.length; i ++) {
        /* if (Hl.style_name_suffix)
            stylemapper[query[i]] = Hl.style_name+(i+1);
        else */
            stylemapper[query[i]] = /* Hl.style_name */ 'hl';
    }

    /* var */ textproc = function(node) {
        /* var */ match = qre.exec(node.data);
        if (match) {
            /* var */ val = match[0];
            /* var */ k = '';
            /* var */ node2 = node.splitText(match.index);
            /* var */ node3 = node2.splitText(val.length);
            /* var */ span = node.ownerDocument.createElement('SPAN');
            node.parentNode.replaceChild(span, node2);
            span.className = stylemapper[val.toLowerCase()];
            span.appendChild(node2);
            return span;
        } else {
            return node;
        }
    };
    Hl.wE(elm.childNodes[0], 1, textproc);
};

/**
 * Highlight a HTML document using keywords extracted from document.referrer.
 * This is the main function to be called to perform search engine highlight
 * on a document.
 *
 * Currently it would check for DOM element 'content', element 'container' and
 * then document.body in that order, so it only highlights appropriate section
 * on WordPress and Movable Type pages.
 */
Hl.hl = function() {
    // If 'debug_referrer' then we will use that as our referrer string
    // instead.
    /* var */ q = /* Hl.debug_referrer ? Hl.debug_referrer : */ document.referrer;
    /* var */ e = null;
    //alert('Hl start');
    q = Hl.dR(q);
    if (q && ((/* Hl.ei && */
               (e = document.getElementById(/* Hl.ei */'content'))) || 
              (e = document.body)))
    {
	Hl.hE(e, q);
	//alert('hl.hE end');
    }
};

Hl.wE = function(node, depth, textproc) { /* walkElements */
    /* var */ skipre = /^(script|style|textarea)/i;
    /* var */ count = 0;
    while (node && depth > 0) {
        count ++;
        if (count >= /* Hl.max_nodes */ 1000) {
			/* If we have processed enough nodes, set a 50ms timer to start more processing
			 * and stop for now */
            /* var */ handler = function() {
                Hl.wE(node, depth, textproc);
            };
            setTimeout(handler, 50);
            return;
        }

        if (node.nodeType == 1) { // ELEMENT_NODE
            if (!skipre.test(node.tagName) && node.childNodes.length > 0) {
                node = node.childNodes[0];
                depth ++;
                continue;
            }
        } else if (node.nodeType == 3) { // TEXT_NODE
            node = textproc(node);
        }

        if (node.nextSibling) {
            node = node.nextSibling;
        } else {
            while (depth > 0) {
                node = node.parentNode;
                depth --;
                if (node.nextSibling) {
                    node = node.nextSibling;
                    break;
                }
            }
        }
    }
};

