﻿
//var everIncrementing

function $(id)
{
	return document.getElementById(id);
}

getAbsoluteRootUrl = function() {
    var res = window.location.href;
    var pos1 = res.indexOf('//') + 2;
    pos1 = res.indexOf('/', pos1);
    res = res.substring(0, pos1);
    //alert ('res ' + res);
    return res;
}

function GetWindowWidth()
{
	var width =
		document.documentElement && document.documentElement.clientWidth ||
		document.body && document.body.clientWidth ||
		document.body && document.body.parentNode && document.body.parentNode.clientWidth ||
		0;
		
	return width;
}

function GetWindowHeight()
{
    var height =
		document.documentElement && document.documentElement.clientHeight ||
		document.body && document.body.clientHeight ||
  		document.body && document.body.parentNode && document.body.parentNode.clientHeight ||
  		0;
  		
  	return height;
}

function getIEVersion() 
{ 
  var userAgent = window.navigator.userAgent; 
  var MSIEPos = userAgent.indexOf("MSIE"); 
  return (MSIEPos > 0 ? parseInt(userAgent.substring(MSIEPos+5,  userAgent.indexOf(".",  MSIEPos))) : 0); 
} 

function setOpacity(el, opacity) {
  // IE/Win
    //alert ('setOpacity');
    if (el && el.style) {
        
        // perhaps do browser sniffing.
        
        el.style.filter = "alpha(opacity:" + (opacity * 100) + ")";
        
        //alert ('el.style.filter ' + el.style.filter);
        
        // Safari<1.2, Konqueror
        el.style.KHTMLOpacity = opacity;

        // Older Mozilla and Firefox
        el.style.MozOpacity = opacity;

        // Safari 1.2, newer Firefox and Mozilla, CSS3
        el.style.opacity = opacity;
        //alert ('el.style.opacity ' + el.style.opacity);
    }
}

String.prototype.stripSpaces = function( ){ return this.replace( /\s/g, "" ); };

var Class = function(options) {
    this.options = options;
    this.init();
}
var p = Class.prototype;
//p.init = function(depth) {
//    //alert ('p.init');
//    if (!depth && depth != 0) this.init(0);
//    
//    this.superInit(depth);
//    
//    // perhaps need a function to get the current initMe?
//    
//    this.initMe();
//}

p.initMe = function() {
    
}

chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
function randomString(length) {
	//var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
	var res = '';
	for (var i=0; i<length; i++) {
		var rnum = Math.floor(Math.random() * chars.length);
		res += chars.substring(rnum,rnum+1);
	}
	return res;
}

uniqueGeneratedValues = new Object();
// maybe not such a good idea to get these for callbacks - perhaps a more efficient system would save on memory.
// or just have a counter of numbers.

/// Callback
// Maybe not needed - or change call. Do not need so many params.
function Callback(callingObject, functionName) {
    this.callingObject = callingObject;
    this.functionName = functionName;

}

var p = Callback.prototype;
p.call = function(param1, param2 , param3) {
    if ((param1 != null) && (param2 != null) && (param3 != null)) {
        //alert ('callback 3 params');
        if (this.callingObject[this.functionName]) this.callingObject[this.functionName](param1, param2, param3);
    } else {
        if ((param1 != null) && (param2 != null)) {
            if (this.callingObject[this.functionName]) this.callingObject[this.functionName](param1, param2);
        } else {
            if (param1 != null) {
                if (this.callingObject[this.functionName]) this.callingObject[this.functionName](param1);
            } else {
                if (this.callingObject[this.functionName]) this.callingObject[this.functionName]();
            }
        }
    }
}

EventRaiser = function() {
    this.init();
}
var p = EventRaiser.prototype;
p.init = function() {
    this.listeners = new Object();
}

// each callback has a unique callback ID?
//  may be quite effective - automatically gets generated.

p.addListener = function(listenerCallback, eventName) {
    if (!this.listeners[eventName]) {
        //this.listeners[eventName] = new Array();
    }
}
p.removeListener = function(listenerCallback, eventName) {
    
}
p.raiseEvent = function(eventName) {
    
}

findPosX = function(obj)
  {
    var curleft = 0;
    if(obj.offsetParent)
        while(1) 
        {
          curleft += obj.offsetLeft;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.x)
        curleft += obj.x;
    return curleft;
  }

  findPosY = function(obj)
  {
    var curtop = 0;
    if(obj.offsetParent)
        while(1)
        {
          curtop += obj.offsetTop;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.y)
        curtop += obj.y;
    return curtop;
  }

findPos = function(obj) {
	var curleft = curtop = 0;
    if (obj.offsetParent) {
        do {
	        curleft += obj.offsetLeft;
	        curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
    }
    return [curleft,curtop];
}

var posX = 0;
var posY = 0;
draggingEl = null;

//document.onmousemove = mouseMove;
doDrag = null;
document.onmousemove = function(e) {
	if (!e) var e = window.event;
	//var e = window.event;
	if (e.pageX || e.pageY) 	{
		posX = e.pageX;
		posY = e.pageY;
		if (doDrag) doDrag();
	}
	else if (e.clientX || e.clientY) {
	    //alert ('document.documentElement.scrollLeft ' + document.documentElement.scrollLeft);
		//alert ('document.body.clientLeft ' + document.body.clientLeft);
		if (document.body) {
		    
		    var clX = e.clientX;
		    var dbsl = document.body.scrollLeft;
		    var ddesl = document.documentElement.scrollLeft;
    		
		    posX = clX + dbsl + ddesl;
		    posY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
		    if (doDrag) doDrag(0);
		}
	}
    //alert ('posX: ' + posX + ', posY: ' + posY);
}

var mousePos;
function mouseMove(ev){
	ev           = ev || window.event;
	mousePos = mouseCoords(ev);
	
	doDrag();
	// if something is being dragged, move it.
}

function mouseCoords(ev){
	if(ev.pageX || ev.pageY){
		return {x:ev.pageX, y:ev.pageY};
	}
	return {
		//x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
		//y:ev.clientY + document.body.scrollTop  - document.body.clientTop
		x:ev.clientX + document.body.scrollLeft,
		y:ev.clientY + document.body.scrollTop
	};
}

function getPosition(e){
	var left = 0;
	var top  = 0;

	while (e.offsetParent){
		left += e.offsetLeft;
		top  += e.offsetTop;
		e     = e.offsetParent;
	}

	left += e.offsetLeft;
	top  += e.offsetTop;

	return {x:left, y:top};
}

function findPosX(obj)
  {
    var curleft = 0;
    if(obj.offsetParent)
        while(1) 
        {
          curleft += obj.offsetLeft;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.x)
        curleft += obj.x;
    return curleft;
  }

  function findPosY(obj)
  {
    var curtop = 0;
    if(obj.offsetParent)
        while(1)
        {
          curtop += obj.offsetTop;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.y)
        curtop += obj.y;
    return curtop;
  }

function findPos(obj) {
	var curleft = curtop = 0;
    if (obj.offsetParent) {
        do {
	        curleft += obj.offsetLeft;
	        curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
    }
    return [curleft,curtop];
}

// set the CSS Class
//p.setClass = function(className) {
//    setClass(this.div, className);
//}

p.setVisibility = function(visible) {
    if (visible) {
        this.div.style.display = 'block';
    } else {
        this.div.style.display = 'none';
    }
}
p.show = function() {
    //alert ('show residential');
    this.setVisibility(true);
}
p.hide = function() {
    this.setVisibility(false);
}

function isIE() {
 if(document.all) return true;
 return false;
} 

var cUID = 0;
UID = function() {
    return 'obj' + cUID;
    cUID++;
}

nE = function(tagName) {
    var r = cE(tagName);
    return r;
}

nD = function(innerHTML, className) {
    var r = nE('div');
    if (innerHTML) r.innerHTML = innerHTML;
    if (className) setClass(r, className);
    return r;
}
cE = function(t) {
    return document.createElement(t);
}

//sLbl.innerHTML = 'I want to use the same address for both contact and billing.';

setClass = function(el, className) { 
    //el.setAttribute('class', className); 
    //el.setAttribute('className', className); 
    el.cssClass = className; 
    el.className = className; 
} 

toPx = function(value) {
    return value + 'px';
}

function clearSelection() { 
    var sel ; 
    if(document.selection && document.selection.empty) { 
      document.selection.empty() ; 
    } else if(window.getSelection) { 
      sel=window.getSelection(); 
      if(sel && sel.removeAllRanges) 
        sel.removeAllRanges() ; 
    }
}

// function to get the element size;

getElSize = function(el) {
    
}

// need the Ajax call stuff.

SoapRequest = function(url, methodName, xmlNamespace) {
    this.url = url;
    this.methodName = methodName;
    this.xmlNamespace = xmlNamespace;
    this.initSoapRequest();
}
var p = SoapRequest.prototype;
p.initSoapRequest = function() {
    this.params = new Array();
}

p.send = function(/* Callback */ callback, errorCallback, callbackParam) {
    //alert ('send');
    //alert ('callback ' + callback);
    //alert ('errorCallback ' + errorCallback);
    SoapRequest.send(this, callback, errorCallback, callbackParam);
    
}
SoapRequest.send = function(soapRequest, callback, errorCallback, callbackParam) {
    //alert ('sent');
    //alert ('errorCallback ' + errorCallback);
    var xs = soapRequest.toXmlStr();
    var hr = createXMLHttp();
    //hr.open('post', 'Sessions.asmx', true);
    //alert ('soapRequest.url ' + soapRequest.url);
    //alert ('soapRequest.methodName ' + soapRequest.methodName);
    
    hr.open('post', soapRequest.url, true);
    hr.setRequestHeader('Content-Type', 'text/xml');
    hr.setRequestHeader('Content-Length', xs.length);
    //hr.setRequestHeader('SOAPAction', 'Hitachi.Next.Web.Serivces/MoveSection');
    hr.setRequestHeader('SOAPAction', soapRequest.methodName);
    hr.send(xs);
    
    hr.onreadystatechange = function() {
        //alert ('hr.readyState ' + hr.readyState);
        //alert ('hr.status ' + hr.status);
        if (hr.readyState == 4) {
            //alert ('errorCallback ' + errorCallback);
            //alert ('hr.status ' + hr.status);
            
            if (hr.status == 200) {
                var rx = hr.responseXML;
                //alert ('callbackParam ' + callbackParam.mediaID);
                //callback.call(hr.responseXML, callbackParam);
                
                // maybe better to call a callback within a specific object context.
                
                // the callback may include callback params.
                
                if (callback.caller && callback.functionName) {
                    //alert ('callback.caller && callback.functionName');
                    if (callback.callbackParam) {
                        //alert ('callback.callbackParam');
                        callback.caller[callback.functionName](hr.responseXML, callback.callbackParam);
                    } else {
                        callback.caller[callback.functionName](hr.responseXML, callbackParam);
                    }
                } else {
                    //alert ('!(callback.caller && callback.functionName)');
                    callback(hr.responseXML, callbackParam);
                }
            } else {
                
//                if (hr.status == 500) {
//                    // internal server error
//                    // call the error callback.
//                    //alert ('there has been an error');
//                    if (errorCallback) errorCallback(hr.responseXML, hr.status);
//                }
//                if (hr.status == 400) {
//                    if (errorCallback) errorCallback(hr.responseXML, hr.status);
//                }
//                if (hr.status == 404) {
//                    //alert ('404');
//                    if (errorCallback) errorCallback(hr.responseXML, hr.status);
//                }
                if (errorCallback) errorCallback(hr.responseXML, hr.status);
                
            }
            
            //alert ('hr.status ' + hr.status);
            //var rx2 = hr.dds.dw;
            //alert ('rx ' + rx);
            
        }
    }
}

p.addNewParam = function(name, value) {
    return this.addParam(new SoapRequest.Param(name, value));
}
p.addNewXmlParam = function(xml) {
    return this.addParam(new SoapRequest.XmlParam(xml));
}
p.addParam = function(param) {
    this.params.push(param);
    return param;
}

p.toXmlStr = function() {
    var res =  '<?xml version="1.0" encoding="utf-8"?>';
    res = res = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">';
    res = res + '<soap:Body>';
    //alert ('this.methodName ' + this.methodName);
    
    if (this.xmlNamespace) {
        res = res + '<' + this.methodName + ' xmlns="' + this.xmlNamespace + '">';
    } else {
        res = res + '<' + this.methodName + ' >';
    }
    
    for (var c = 0; c < this.params.length; c++) {
        res = res + this.params[c].toXmlStr();
    }
    res = res + '</' + this.methodName + '>';
    res = res + '</soap:Body>';
    res = res + '</soap:Envelope>';
    return res;
}

p._type = 'SoapRequest';

//// Maybe this will he hooked into XML schema validation functionality.
SoapRequest.Param = function(name, value) {
    this.name = name;
    this.value = value;
}
var p = SoapRequest.Param.prototype;

p.toXmlStr = function() {
    var res = '<' + this.name + '>' + this.value + '</' + this.name + '>';
    return res;
}

p._type = 'SoapRequest.Param';

createXMLHttp = function() {
    if (typeof XMLHttpRequest != "undefined") {
        return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      var aVersions = [ "MSXML2.XMLHttp.5.0",
        "MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0",
        "MSXML2.XMLHttp","Microsoft.XMLHttp"
      ];

      for (var i = 0; i < aVersions.length; i++) {
        try {
            var oXmlHttp = new ActiveXObject(aVersions[i]);
            return oXmlHttp;
        } catch (oError) {
            //Do nothing
        }
      }
    }
    throw new Error("XMLHttp object could not be created.");
}

getPaddingHeight = function(div) {
    var paddingTop = 0;
    var paddingBottom = 0;
    
    if (div.currentStyle){
        //alert ("section.div.currentStyle['paddingLeft'] " + section.div.currentStyle['paddingLeft']);
        paddingTop = toInt(div.currentStyle['paddingTop']);
        paddingBottom = toInt(div.currentStyle['paddingBottom']);
    }
    
    if (window.getComputedStyle) {
        //alert ("window.getComputedStyle(section.div, '').getPropertyValue('padding-left') " + window.getComputedStyle(section.div, '').getPropertyValue('padding-left'));
        paddingTop = toInt(window.getComputedStyle(div, '').getPropertyValue('padding-top'));
        paddingBottom = toInt(window.getComputedStyle(div, '').getPropertyValue('padding-bottom'));
    }
    return paddingTop + paddingBottom;
}

getBorderHeight = function(div) {
    var borderTop = 0;
    var borderBottom = 0;
    
    if (div.currentStyle){
        //alert ("div.currentStyle['borderTop'] " + div.currentStyle['borderTop']);
        borderTop = toInt(div.currentStyle['borderTop']);
        borderBottom = toInt(div.currentStyle['borderBottom']);
    }
    
    if (window.getComputedStyle) {
        //alert ("window.getComputedStyle(div, '').getPropertyValue('border-top') " + window.getComputedStyle(div, '').getPropertyValue('border-left'));
        borderTop = toInt(window.getComputedStyle(div, '').getPropertyValue('border-top'));
        borderBottom = toInt(window.getComputedStyle(div, '').getPropertyValue('border-bottom'));
    }
    return borderTop + borderBottom;
}

getFloat = function(div) {
    var res;
    if (div.currentStyle){
        //alert ("div.currentStyle['borderTop'] " + div.currentStyle['borderTop']);
        res = div.currentStyle['styleFloat'];
    }
    
    if (window.getComputedStyle) {
        //alert ("window.getComputedStyle(div, '').getPropertyValue('border-top') " + window.getComputedStyle(div, '').getPropertyValue('border-left'));
        res = window.getComputedStyle(div, '').getPropertyValue('float');
    }
    return res;
}
setFloat = function(div, cssFloat) {
    div.style.cssFloat = cssFloat;
    div.style.styleFloat = cssFloat;
}

//toggleTemplateSelector = function(imgToggler) {
//    var divTemplateSelector = imgToggler.parentNode;
//    if (divTemplateSelector.isExpanded == false) {
//    
//    } else {
//        expandDiv(divTemplateSelector);
//    }
//}

getChildNodeById = function(node, id) {
    var found = false;
    var c = 0;
    while (!found && c < node.childNodes.length) {
        //alert ('node.childNodes[c].id ' + node.childNodes[c].id);
        if (node.childNodes[c].id == id) found = node.childNodes[c];
        c++;
    }
    //if (found) return 
    //alert ('found ' + found);
    return found;
}

// getDescendedElementBy...
// gets the first node found at or below the given node
getElementByCssClass = function(node, cssClass) {
    var foundCssClass = getElClassName(node);
    if (foundCssClass == cssClass) {
        //alert('foundCssClass ' + foundCssClass);
        //alert('cssClass ' + cssClass);
        return node;
    }
    
    var res;
    var c = 0;
    while (!res && c < node.childNodes.length) {
        res = getElementByCssClass(node.childNodes[c], cssClass);
        c++;
    }
    //alert('res ' + res);
    return res;
}

getChildNodeByCssClass = function(node, cssClass) {
    var found = false;
    var c = 0;
    while (!found && c < node.childNodes.length) {
        //alert ('node.childNodes[c].id ' + node.childNodes[c].id);
        var n = node.childNodes[c];
        var nCssClass = getElClassName(n);
        if (nCssClass == cssClass) found = node.childNodes[c];
        c++;
    }
    //if (found) return 
    //alert ('found ' + found);
    return found;
}

getElementsByTagNameAndCssClass = function(tagName, cssClass) {
    var divs = document.getElementsByTagName(tagName);
    //alert ('divs.length ' + divs.length);
    var res = new Array();
    for (var c = 0; c < divs.length; c++) {
        var d = divs[c];
        if (elMatchesClassName(d, cssClass)) {
            res.push(d);
        }
    }
    //alert ('res.length ' + res.length);
    return res;
}

getDivsMatchingClassName = function(cssClass) {
    return getElementsByTagNameAndCssClass('div', cssClass);
}

getBeforeLastUnderscore = function(val) {
    var pos1 = val.lastIndexOf('_');
    var res;
    if (pos1 > -1) {
        res = val.substring(0, pos1);
    } else {
        res = val;
    }
    
    return res;
}
getAfterLastUnderscore = function(val) {
    var pos1 = val.lastIndexOf('_');
    var res;
    if (pos1 > -1) {
        res = val.substring(pos1 + 1);
    } else {
        res = val;
    }
    
    return res;
}

elMatchesIdBeginning = function(el, idBeginning) {
    var classIdbeginning = getBeforeLastUnderscore(el.id);
    return classIdbeginning == idBeginning;
}

elMatchesClassName = function(el, cssClass) {
    var foundCssClass = getElClassName(el);
    return foundCssClass == cssClass;
}

elBeginsWithClassName = function(el, targetClass) {
    //return el.cssClass == cssClass || el.className == cssClass;
    //var cc = getElClassName(el);
    
    //alert ('cssClass ' + cssClass);
    //alert ('el.nodeType ' + el.nodeType);
    
    if (el.nodeType != 1) return false;
    
    
    var itemClass = getElClassName(el);
    //alert ('itemClass ' + itemClass);
    //return (cssClass.match(
    
    //alert ('cc ' + cc);
    
    if (itemClass) {
        //var myReg = new RegExp('^' + targetClass);
        //alert ('itemClass.match(myReg) ' + itemClass.match(myReg));
        //return itemClass.match(myReg);
        var pos1 = itemClass.indexOf(targetClass);
        //alert ('pos1 ' + pos1);
        return (pos1 == 0);
        
    } else {
        return false;
    }
    
    
    
//    if (cc) {
//        var subs = cc.substring(0, cssClass.length - 1);
//        alert ('subs ' + subs);
//        
//        
//        
//        if (subs == cssClass) alert ('subs == cssClass');
//        
//        return (subs == cssClass)
//    }
//    
//    return false;
}
getElClassName = function(el) {
    //alert ('el.cssClass ' + el.cssClass);
    if (el.cssClass) return el.cssClass;
    //alert ('el.className ' + el.className);
    if (el.className) return el.className;
}

getIFrameDocument = function(iF) {
    var doc;
    if (iF.contentDocument) {
        doc = iF.contentDocument;
    } else if (iF.contentWindow) {
        doc = iF.contentWindow.document;
    } else if (iF.document) {
        doc = iF.document;
    }
    return doc;
}

getFileName = function(filePath) {
    var pos1 = -1;
    var pos2 = -1;
    var pos1 = filePath.lastIndexOf('\\');
    var pos2 = filePath.lastIndexOf('/');
    
    if (pos1 > -1 || pos2 > -1) {
        if (pos1 > pos2) {
            return filePath.substring(pos1 + 1);
        } else {
            return filePath.substring(pos2 + 1);
        }
    } else {
        return filePath;
    }
}

collapseDiv = function(div) {
    div.oldStyleDisplay = div.style.display;
    div.oldHeight = div.style.height;
    if (smoothSectionExpandContract) {
        //alert('smoothSectionExpandContract ' + smoothSectionExpandContract);
        
        
//        var parentFullHeight = div.parentNode.offsetHeight;
//        // changing the height in IE ruins its horizontal positioning in this case.
//        div.oldStyleDisplay = div.style.display;
//        div.style.display = 'none';
//        var parentHeightWithout = div.parentNode.offsetHeight;
//        div.oldHeight = div.style.height;
//        var divYOffset = parentFullHeight - parentHeightWithout;
//        div.style.display = div.oldStyleDisplay;
        
        var divYOffset = div.offsetHeight;
        
        // calculate the y offset in a different way, try the div's offsetHeight
        
        var display;
        var overflow;
        //var height;
        if (div.currentStyle){
            //alert ("section.div.currentStyle['paddingLeft'] " + section.div.currentStyle['paddingLeft']);
            display = div.currentStyle['display'];
            overflow = div.currentStyle['overflow'];
            //height = div.currentStyle['height'];
        }
        if (window.getComputedStyle) {
            //alert ("window.getComputedStyle(section.div, '').getPropertyValue('padding-left') " + window.getComputedStyle(section.div, '').getPropertyValue('padding-left'));
            display = window.getComputedStyle(div, '').getPropertyValue('display');
            overflow = window.getComputedStyle(div, '').getPropertyValue('overflow');
            //height = window.getComputedStyle(div, '').getPropertyValue('height');
        }
        div.oldOverflow = overflow;
        div.style.overflow = 'hidden';
        div.fullHeight = divYOffset;
        var sm = new SmoothMovement(divYOffset, 0, 0);
        var currentHeight = divYOffset;
        var fnMove = function() {
            currentHeight = sm.updatePosition();
            currentHeight = sm.updatePosition();
            //alert('currentHeight ' + currentHeight);
            removeAndReplaceElWithSetHeight(div, currentHeight + 'px');
            if (currentHeight > 0) {
                tO = setTimeout(fnMove, 25);
            } else {
                div.style.overflow = div.oldOverflow;
                //div.style.display = 'none';
                if (div.parentNode.control) {
                    if (div.parentNode.control.collapseComplete) div.parentNode.control.collapseComplete();
                }
                if (div.collapseComplete) {
                    div.collapseComplete();
                }
            }
        }
        var tO = setTimeout(fnMove, 25);
    } else {
        //div.oldStyleDisplay = div.style.display;
        div.style.display = 'none';
        if (div.parentNode.control) {
            div.parentNode.control.collapseComplete();
        }
    }
}

var elToBeRefreshed;

expandElToBeRefreshed = function(el) {
    expandDiv(elToBeRefreshed);
}

toggleDivExpansion = function(div) {
    var divIsExpanded = true;
    var display;
    if (div.currentStyle){
        //alert ("section.div.currentStyle['paddingLeft'] " + section.div.currentStyle['paddingLeft']);
        display = div.currentStyle['display'];
        //overflow = div.currentStyle['overflow'];
        height = div.currentStyle['height'];
    }
    if (window.getComputedStyle) {
        //alert ("window.getComputedStyle(section.div, '').getPropertyValue('padding-left') " + window.getComputedStyle(section.div, '').getPropertyValue('padding-left'));
        display = window.getComputedStyle(div, '').getPropertyValue('display');
        //overflow = window.getComputedStyle(div, '').getPropertyValue('overflow');
        height = window.getComputedStyle(div, '').getPropertyValue('height');
    }
    if (display == 'none') divIsExpanded = false;
    if (height == '0px') divIsExpanded = false;
    
    if (divIsExpanded) {
        collapseDiv(div);
    } else {
        expandDiv(div);
    }
}

expandDiv = function(div) {
    // should probably check it is not already expanded?
    
    
    // when it has reached the absolute height that has been tagged, remove its height attribute.
    //div.style.height = div.fullHeight;
    //alert ('div ' + div);
    // need to be able to make visible a div that has display 'none'
    // will need to temporarily make it display 'block'.
    // get the computed style?
    
    //div.innerHTML = 'Yo';
    //alert ('expandDiv');
    
    
    
    
    var display;
    var overflow;
    var height;
    if (div.currentStyle){
        //alert ("section.div.currentStyle['paddingLeft'] " + section.div.currentStyle['paddingLeft']);
        display = div.currentStyle['display'];
        overflow = div.currentStyle['overflow'];
        height = div.currentStyle['height'];
    }
    if (window.getComputedStyle) {
        //alert ("window.getComputedStyle(section.div, '').getPropertyValue('padding-left') " + window.getComputedStyle(section.div, '').getPropertyValue('padding-left'));
        display = window.getComputedStyle(div, '').getPropertyValue('display');
        overflow = window.getComputedStyle(div, '').getPropertyValue('overflow');
        height = window.getComputedStyle(div, '').getPropertyValue('height');
    }
    //alert ('overflow ' + overflow);
    
    //alert ('div.style.display ' + div.style.display);
    //alert ('div.style.display ' + div.style.display);
    div.style.display = 'block';
    //alert ('div.style.display ' + div.style.display);
    
    // get the computed overflow
    
    div.oldOverflow = overflow;
    //if (!div.oldHeight) div.oldHeight = height;
    //div.oldHeight = height;
    div.style.overflow = 'hidden';
    
    if (smoothSectionExpandContract) {
        
        if (display == 'none') {
            // we don't want this jolt where it appears full size for a moment.
            var divPosition = div.style.position;
            var divLeft = div.style.left;
            //alert ('divPosition ' + divPosition);
            
            div.style.display = 'block';
            div.style.position = 'absolute';
            div.style.left = '-1200px';
            // temporarily move it off the screen
            
            div.fullHeight = div.offsetHeight;
            div.style.height = '0px';
            //alert ('div.fullHeight ' + div.fullHeight);
            
            div.style.position = divPosition;
            div.style.left = divLeft;
        }
        
        
        var sm = new SmoothMovement(0, div.fullHeight, 0);
        //var currentHeight = divYOffset;
        var fnMove = function() {
            currentHeight = sm.updatePosition()
            currentHeight = sm.updatePosition()
            //alert('currentHeight ' + currentHeight);
            div.style.height = toPx(currentHeight);
            if (currentHeight < div.fullHeight) {
                tO = setTimeout(fnMove, 25);
            } else {
                elToBeRefreshed = div;
                setTimeout(rare, 1);
                setTimeout(rest, 50);
                if (div.oldOverflow) div.style.overflow = div.oldOverflow;
                if (div.parentNode.control) {
                    if (div.parentNode.control.expandComplete) div.parentNode.control.expandComplete();
                }
                if (div.expandComplete) {
                    div.expandComplete();
                }
            }
        }
        var tO = setTimeout(fnMove, 25);
    } else {
        //alert('div.oldStyleDisplay ' + div.oldStyleDisplay);
        
        if (div.oldStyleDisplay) {
            div.style.display = div.oldStyleDisplay;
            div.style.height = div.oldHeight;
        } else {
            div.style.display = 'block';
        }
        
        if (div.parentNode.control) {
            div.parentNode.control.expandComplete();
        }
    }
}

rare = function() {
    removeAndReplaceEl(elToBeRefreshed);
}

removeAndReplaceEl = function(el) {
    var nd = nD();
    el.parentNode.replaceChild(nd, el);
    nd.parentNode.replaceChild(el, nd);
}

removeAndReplaceElWithSetHeight = function(el, height) {
    //alert ('removeAndReplaceElWithSetHeight');
    //if (height < 0) height = 0;
    
    var nd = nD();
    el.parentNode.replaceChild(nd, el);
    el.style.height = height;
    nd.parentNode.replaceChild(el, nd);
}

rest = function() {
    removeElStyleHeight(elToBeRefreshed);
}
removeElStyleHeight = function(el) {
    el.style.height = '';
}

getPreviousSibling = function(startBrother) {
    endBrother=startBrother.previousSibling;
    if (endBrother) {
        while(endBrother.nodeType!=1){
            //alert ('2 endBrother.nodeType ' + endBrother.nodeType);
            if (endBrother.previousSibling) {
                endBrother = endBrother.previousSibling;
            } else {
                endBrother = null;
                return null;
                //alert ('null');
            }
        }
        return endBrother;
    } else {
        return null;
    }
}

getNextSibling = function(startBrother){
    endBrother=startBrother.nextSibling;
    if (endBrother) {
        //alert ('endBrother ' + endBrother);
        //alert ('1 endBrother.nodeType ' + endBrother.nodeType);
        while(endBrother.nodeType!=1){
            //alert ('2 endBrother.nodeType ' + endBrother.nodeType);
            if (endBrother.nextSibling) {
                endBrother = endBrother.nextSibling;
            } else {
                endBrother = null;
                return null;
                //alert ('null');
            }
        }
        //alert ('3 endBrother.nodeType ' + endBrother.nodeType);
        return endBrother;
    } else {
        return null;
    }
}

insertNodeAfter = function(node, sibling) {
    var ns = getNextSibling(sibling);
    if (ns) {
        ns.parentNode.insertBefore(node, ns);
    } else {
        node.parentNode.appendChild(node);
    }
}

removeNode = function(node) {
    node.parentNode.removeChild(node);
    return node;
}


getDocumentHeight = function() {
    var docHeight;
    if (typeof document.height != 'undefined') {
    docHeight = document.height;
    }
    else if (document.compatMode && document.compatMode != 'BackCompat') {
    docHeight = document.documentElement.scrollHeight;
    }
    else if (document.body && typeof document.body.scrollHeight !=
    'undefined') {
    docHeight = document.body.scrollHeight;
    }
    return docHeight;
}


/* Begin copyright N C Zakas*/

function zXMLSerializer() {

}

/**
 * Serializes the given XML node into an XML string.
 * @param oNode The XML node to serialize.
 * @return An XML string.
 */
zXMLSerializer.prototype.serializeToString = function (oNode /*:Node*/)/*:String*/ {

    var sXml = "";
    
    switch (oNode.nodeType) {
        case 1: //element
            sXml = "<" + oNode.tagName;
            
            for (var i=0; i < oNode.attributes.length; i++) {
                sXml += " " + oNode.attributes[i].name + "=\"" + oNode.attributes[i].value + "\"";
            }
            
            sXml += ">";
            
            for (var i=0; i < oNode.childNodes.length; i++){
                sXml += this.serializeToString(oNode.childNodes[i]);
            }
            
            sXml += "</" + oNode.tagName + ">";
            break;
            
        case 3: //text node
            sXml = oNode.nodeValue;
            break;
        case 4: //cdata
            sXml = "<![CDATA[" + oNode.nodeValue + "]]>";
            break;
        case 7: //processing instruction
            sXml = "<?" + oNode.nodevalue + "?>";
            break;
        case 8: //comment
            sXml = "<!--" + oNode.nodevalue + "-->";
            break;
        case 9: //document
            for (var i=0; i < oNode.childNodes.length; i++){
                sXml += this.serializeToString(oNode.childNodes[i]);
            }
            break;
            
    }  
    
    return sXml;
};

/* End copyright N C Zakas*/