// JScript source code

	/**
		this is a new class for handling scrollable browsing lists
		it's a copy of the original - but hopefully it can be changed to
		fix the cross browser issues with scrolling browse list
		
		@constructor
	**/
    
	function scrollingBrowseListObject2 () {}
        
    scrollingBrowseListObject2.prototype = new baseObject ();
        

	/***
		the start function is called when the document manager binds this object to
		an HTML element with an ALSiClass of "scrollingBrowseList2"
	**/
    
    
          
    scrollingBrowseListObject2.prototype.start = function ( element, strClass, obContainer ) {
    		trace("","scrolling browse list 2 start function called");
            this.outerElement = element;
            // humm - I'm not sure this does as expected for Mozilla.
            element.setAttribute("objectHandle",this.handle);
            element.hideFocus = true;
			this.requestNumber = 0;
            this.localFocusElement = this.outerElement;
            this.bFoundTop = false;
            this.bFoundBottom = false;
            this.numPixelFill = 200;
            this.elBrowseList = this.outerElement;
            this.numBlocks = 0;
            this.strRequestExtra = this.outerElement.getAttribute ( this.manager.attributePrefix + "RequestExtra" );
            this.bPageMode = ( this.outerElement.getAttribute ( this.manager.attributePrefix + "PageBrowse" ) == "1" );
            this.allowBackSpace = true;
            if ( this.strRequestExtra == null ) this.strRequestExtra = "";
            this.bNoFocus = this.outerElement.getAttribute ( this.manager.attributePrefix + "NoFocus" ) == "1";
            this.bNoPreloadAbove = this.outerElement.getAttribute ( this.manager.attributePrefix + "NoPreloadAbove" ) == "1";
            this.bFixedContent = this.outerElement.getAttribute ( this.manager.attributePrefix + "FixedContent" ) == "1";
            if ( this.elBrowseList.firstChild != null ) {
                var elDiv = this.elBrowseList.firstChild;
                
                if ( elDiv.nodeType == 1 ) {
                    this.bFoundTop = ( elDiv.getAttribute ( "bFoundTop" ) == "1" );
                    this.bFoundBottom = ( elDiv.getAttribute ( "bFoundBottom" ) == "1" );
                    this.bPausedDown  = ( elDiv.getAttribute ( "bPausedDown" ) == "1");
                }
            }
            obContainer.traverseChildren ( element ); // Recurse binding to child elements.
            this.bNoScrollBar = this.outerElement.getAttribute ( this.manager.attributePrefix + "NoScrollBar" ) == "1";
            this.strMarkerClass = this.outerElement.getAttribute ( this.manager.attributePrefix + "StopBarClass" );
            
            
            if (browserVersion >= 999)
            {
                // if it's Mozilla we use the auto scroll style.
                this.elBrowseList.style.overflow = "auto";//this.bNoScrollBar ? "hidden" : "auto";
                // if it's ie we will hide the x-scroll bar to get over irritating bug.
                 this.elBrowseList.style.overflowY = "auto";
                 this.elBrowseList.style.overflowX = "hidden";
                
            }
            else
            {
                // if it's ie we will hide the x-scroll bar to get over irritating bug.
                this.elBrowseList.style.overflowY = "auto";
                this.elBrowseList.style.overflowX = "hidden";
            }
            this.obAppServer = new cHttpFetcher ( this.manager.getUseScriptHTTPFetcher () );
            this.localFocusElement.onfocus = new Function ( "documentManager.controlGetsFocus(" + this.handle + ");" );
            this.localFocusElement.onblur = new Function ( "documentManager.controlLoosesFocus(" + this.handle + ");" );
            this.showFocus = false;
            this.manager.addTask ( this.createCallback ( "fnOnStart" ) );
            this.fnPollCallBack = this.createCallback ( "fnOnPoll" );
            this.strName = element.id;
            if ( this.bFixedContent ) {
                this.bFoundTop = true;
                this.bFoundBottom = true;
            }
        }

            var wheelHan = null;
            var wheelDir       = null;
            
            function handleMozMouseWheel(event)
               {
                //alert(wheelHan);
                if
                    (event.detail >0)
                {
                    //alert("Scroll down");
                    wheelDir = 1;
                }
                else
                {
                    //alert("Scroll up");
                    wheelDir = -1;
                    
                }
                if
                    (wheelHan != null)
                {
                    wheelHan();
                }

                event.preventDefault();
              }


        /***
			second half of the initialisation
        **/
        scrollingBrowseListObject2.prototype.fnOnStart = function () {
            trace("","scrollingBrowseListObject.fnOnStart called");
            if ( this.elBrowseList.parentNode == null ) {

                // The page was unloaded before we got a chance to start.
                trace("","scrollingBrowseListObject.thinks it's been unloaded");
                return;
            }
            if ( document.body.offsetHeight < 20 ) {
                trace("","scrollingBrowseListObject.thinks it needs to wait for more data ?");
                this.manager.addTask ( this.createCallback ( "fnOnStart" ) );
            } else {
                this.elBrowseList.style.pixelHeight = this.elBrowseList.offsetHeight;
                trace("",this.elBrowseList.style.pixelHeight);
                if ( ! this.bPageMode ) {
                    this.elBrowseList.style.pixelHeight = this.elBrowseList.offsetHeight;
                    this.elTopStop = document.createElement ( "div" );
                    this.elBottomStop = document.createElement ( "div" );
                    this.elPad = document.createElement ( "div" );
                    this.elTopStop.appendChild ( document.createElement ( "br" ) );
                    this.elBottomStop.appendChild ( document.createElement ( "br" ) );
                    this.elPad.appendChild ( document.createElement ( "br" ) );
                    this.elBrowseList.insertBefore ( this.elTopStop, this.elBrowseList.firstChild );
                    this.elBrowseList.appendChild ( this.elBottomStop );
                    this.elBrowseList.appendChild ( this.elPad );
                    if ( this.strMarkerClass != null ) {
                        this.elTopStop.className = this.strMarkerClass;
                        this.elBottomStop.className = this.strMarkerClass;
                    } else {
                        this.elTopStop.style.backgroundColor = "scrollbar";
                        this.elBottomStop.style.backgroundColor = "scrollbar";
                    }
                    this.fnColorMarkers ();
                    var strDisplay = ( this.bFoundTop && this.bFoundBottom ) ? "none" : "block";
                    this.elTopStop.style.display = strDisplay;
                    this.elBottomStop.style.display = strDisplay;
                    this.elBrowseList.scrollTop = this.elTopStop.offsetHeight;
                    this.fnDoResize ();
                    this.elBrowseList.onscroll = this.createCallback ( "fnOnScroll" );
                    //this.elBrowseList.offsetParent.onresize = this.createCallback ( "fnOnResizeParent" );
                    // becuase not all browsers support resize events on elements, we have to do something different
                    
                    documentManager.addOnResize( this.createCallback ( "fnOnResizeParent" ) );
                    if ( this.bNoScrollBar ) {
                        this.elBrowseList.onmousewheel = this.createCallback ( "fnOnMouseWheel" );
                        
                        if (document.body.addEventListener) {
                            wheelHan = this.createCallback ( "fnOnMozMouseWheel" );
                            window.addEventListener('DOMMouseScroll', handleMozMouseWheel, false);
                        }
                    }
                }
                if ( ! this.bNoFocus ) {
                    this.fnSetFocus ();
                }
                this.fnFill ();
            }
        }

            /***
				
				@type integer
            **/
            
            scrollingBrowseListObject2.prototype.fnGetSpareSpace = function () {
                var elOffsetParent = this.elBrowseList.offsetParent;
                var parentHeight = 0;
                if (elOffsetParent.style.pixelHeight) 
				{
					parentHeight =  elOffsetParent.style.pixelHeight;
				}
				else
				{
					parentHeight =  elOffsetParent.clientHeight;
				}
				
                trace("","fnGetSpareSpace called");
                trace("","elOffsetParent "+ elOffsetParent );
                trace("","parentHeight "+ parentHeight );
                trace("","elOffsetParent.scrollHeight "+ elOffsetParent.scrollHeight );
                var result = parentHeight - elOffsetParent.scrollHeight;
                trace("","fnGetSpareSpace return "+ result);
                return result;
                
            }
            
            
            
            
            /***
				called when we need to resize ourselves
            
            **/
            scrollingBrowseListObject2.prototype.fnDoResize = function () {
                trace("","scrollingBrowseListObject2.fnDoResize fish called");
				
	        
				
				var elOffsetParent = this.elBrowseList.offsetParent;	

                // so now its a bit more complex - ALSiContentContainer=1
                
                var w = elOffsetParent.offsetLeft;
                var h = elOffsetParent.offsetTop;
                var p = elOffsetParent;
                
                //debugger;
                
                //alert(p);
                //var av = p.getAttribute("ALSiContainer")
                //while
                //    ( av == null && p != null)
                //{
                //    w += p.offsetLeft;
                //    h += p.offsetTop;
                //    
                //    p = p.parentElement;
                //}
                //alert(p);
                //if
                //    (p.ALSiContainer)
                //{
                //   alert("woopee "+h);
                //}
                    
                var bottom_margin = 0;
                
                // this is something of a hack, but I have to make this work today so ...
                // we make it so a page may specify the width of the bottom margin around the scrolling
                // browse list, by defining an appropriate function.
                if
                    (typeof(pageBrowseBottomMargin) == "function")
                {
                    bottom_margin = pageBrowseBottomMargin();
                }
                
                trace("","parent height is "+ elOffsetParent.offsetHeight);
                
                var new_height = elOffsetParent.offsetHeight;
                var new_width = elOffsetParent.offsetWidth;
                var rc = getBoundingClientRect(this.elBrowseList);
                this.elBrowseList.style.height = (new_height-this.elBrowseList.offsetTop-8-bottom_margin)+"px";
                this.elBrowseList.style.width = (new_width-20) + "px";
                //this.elBrowseList.style.backgroundColor = "red";
                trace("","scrollingBrowseListObject2.fnDoResize fish finished");
                
            }
            
            /***
				called when the parent element is resized - at least it's supposed to be !!
				works on IE - but mozilla never calls this.
				
            **/
            scrollingBrowseListObject2.prototype.fnOnResizeParent = function () {
		        
                if ( ! this.bUpdatingList ) {
                    
                    var numPW = this.elBrowseList.offsetParent.offsetWidth;
                    var numPH = this.elBrowseList.offsetParent.offsetHeight;
                    if ( ( this.numPW != numPW ) || ( this.numPH != numPH ) ) {
		                trace("","scrollingBrowseListObject.fnOnResizeParent called");
                        this.numPW = numPW;
                        this.numPH = numPH;
                        if ( ! this.bScheduledResize ) {
                            this.bScheduledResize = true;
                            this.manager.addTask ( this.createCallback ( "fnActionResize" ) );
                        }
                    }
                }
            }

            /***
				called when the parent element is resized - and we have checked that it really
				has changed size.
            **/

            scrollingBrowseListObject2.prototype.fnActionResize = function () {
                trace("","scrollingBrowseListObject.fnActionResize called");

                this.fnDoResize ();
                this.fnFill ();
                this.bScheduledResize = false;
            }
            
            /***
				called when we use the wheely mouse ( I think this will be IE specific )
            **/
            
            scrollingBrowseListObject2.prototype.fnOnMouseWheel = function (e) {
                if (!e) var e = window.event;
               
                var numMove = this.elBrowseList.offsetHeight * 0.1;
                
                if ( numMove > 30 ) numMove = 30;
                if ( e.wheelDelta >= 120 ) {
                    if ( this.fnGetCanScrollUp () ) {
                        this.elBrowseList.scrollTop -= numMove;
                    }
                }
                if ( e.wheelDelta <= -120 ) {
                    if ( this.fnGetCanScrollDown () ) {
                        this.elBrowseList.scrollTop += numMove;
                    }
                }
                e.cancelBubble = true;
                if ( e.stopPropagation ) e.stopPropagation();
                e.returnValue = false;
                this.manager.activity ();
            }
			
            
           scrollingBrowseListObject2.prototype.fnOnMozMouseWheel = function (e) {
                
                var numMove = 30;
                if ( wheelDir == -1 ) {
                    if ( this.fnGetCanScrollUp () ) {
                    
                        this.elBrowseList.scrollTop -= numMove;
                    }
                }
                if ( wheelDir == 1 ) {
                    if ( this.fnGetCanScrollDown () ) {
                        var t = this.elBrowseList.scrollTop;
                        
                         t += numMove;
                       
                        this.elBrowseList.scrollTop = t;
                    }
                }
                this.manager.activity ();
            }

			/***
				Called when the scroll bar is used
			**/
            scrollingBrowseListObject2.prototype.fnOnScroll = function () {
                if ( this.strPendingRequest != null ) {
                    if ( this.obAppServer.IsAsyncWaiting () ) {
                        if ( this.obAppServer.IsAsyncReady () ) {
                            this.fnProcessResponse ();
                        }
                    }
                } else {
                    if ( ! this.bUpdatingList ) {
                        if ( this.bNoPreloadAbove ) {
                            if ( this.elBrowseList.scrollTop < this.elTopStop.offsetHeight ) {
                                this.bNoPreloadAbove = false;
                            }
                        }
                        this.fnFill ();
					}
                }
            }

			/***
				Called when we have recieved a response - 
			**/

			var scrollingBrowseListErrorHandler = null;

			scrollingBrowseListObject2.prototype.fnShowError = function ()
			{
				if
					(scrollingBrowseListErrorHandler == null)
				{
					trace("no scrollingBrowseListErrorHandler defined - using alert ");
					alert( "Error:"+ this.errorLevel +": ("+ this.errorNumber +") :" + this.errorDescription);				
				}
				else
				{
					// use callback to handle the error in a more elegant way...
					
					scrollingBrowseListErrorHandler( this.errorLevel ,this.errorNumber , this.errorDescription);				
				}
                delete this.strPendingRequest;
			}
			
            scrollingBrowseListObject2.prototype.fnProcessResponse = function () {
                trace("","fnProcessResponse called");
                
                if ( ! this.obAppServer.IsParsedOK () ) {
                    trace("","bad response recieved");
        			
        			// we should analyse the response, and see if
        			// we can figure out what is happening.
        			
    				this.errorLevel = "BadResponse"
                	this.errorNumber = 0
                	var msg = this.obAppServer.GetResponseBody ();
					this.errorDescription = msg;
                    window.setTimeout( this.createCallback ( "fnShowError" ), 100 );

                    return;
					
                    //this.bBadResponse = true;
                } else {
					
                    trace("","pending request = "+this.strPendingRequest);
                    
                    var errorOccured  = this.obAppServer.RspGet ( "errorOccured", "0" );
                    
                    if (errorOccured=="1")
                    {
                    	this.errorLevel = this.obAppServer.RspGet ( "errorLevel", "" );
                    	this.errorNumber = this.obAppServer.RspGet ( "errorNumber", "" );
						this.errorDescription = this.obAppServer.RspGet ( "errorDescription", "" );
                        window.setTimeout( this.createCallback ( "fnShowError" ), 100 );
                        return;
                    }
                    
                    var bUp = ( this.strPendingRequest == "up" );
                    
                    var elDiv = document.createElement ( "div" );
                    elDiv.style.paddingRight = "16px";
                    elDiv.innerHTML = this.obAppServer.GetResponseBody ();
                
                        
                    var bIsEmpty = false;
                    this.bUpdatingList = true;
                    if ( bUp ) {
                        
                        this.elBrowseList.insertBefore ( elDiv, this.elTopStop.nextSibling );
                        
                        //children--childNodes
                        if ( elDiv.childNodes.length == 0 ) {
                            elDiv.removeNode ( true );
                            bIsEmpty = true;
                        } else {
                            this.elBrowseList.scrollTop += elDiv.scrollHeight;
                        }
                    } else {
                        trace("","inserting content ");
                        this.elBrowseList.insertBefore ( elDiv, this.elBottomStop );
                        //children--childNodes
                        
                        if ( elDiv.childNodes.length == 0 ) {
                            
                            elDiv.removeNode ( true );
                            bIsEmpty = true;
                        }
                        
                    }
                    if ( ! bIsEmpty ) {
                        
                        
                        this.manager.bindChildElements ( elDiv );
                        
                        elDiv.setAttribute ( "targetObject", this.obAppServer.RspGet ( "targetObject", "???" ) );
                        
                        this.numBlocks++;
                        if ( this.obAppServer.RspGet ( "strStartHandle", "" ) != "" ) {
                            if ( this.obAppServer.RspGet ( "strEndHandle", "" ) != "" ) {
                                elDiv.strStartHandle = this.obAppServer.RspGet ( "strStartHandle", "" );
                                elDiv.strEndHandle = this.obAppServer.RspGet ( "strEndHandle", "" );
                            }
                        }
                        
                    }
                    
                    if ( this.obAppServer.RspGet ( "bFoundTop", "0" ) == 1 ) {
                        this.bFoundTop = true;
                    }
                    if ( this.obAppServer.RspGet ( "bFoundBottom", "0" ) == 1 ) {
                        this.bFoundBottom = true;
                    }
                    if ( this.obAppServer.RspGet ( "bPausedDown", "0" ) == 1 ) {
                        this.bPausedDown = true;
                    }
                    else
                    {
                       this.bPausedDown = true;
                    }

                    this.fnColorMarkers ();
                    delete this.bUpdatingList;
                    delete this.strPendingRequest;
                    if
                        (this.bPausedDown)
                    {
                        window.setTimeout( this.createCallback ( "fnFill" ), 2000 );
                    }
                    else
                    {
                        this.fnFill ();
                    }
                }
            }
            
            /***
				called to check to see if we have a response yet
            **/
            
            scrollingBrowseListObject2.prototype.fnOnPoll = function () {
                if ( this.elBrowseList.parentNode == null ) {
                    // The page was unloaded.
                    return;
                }
                if ( this.obAppServer.IsAsyncWaiting () ) {
                    if ( ! this.obAppServer.IsAsyncReady () ) {
                        window.setTimeout ( this.fnPollCallBack, 10 );
                    } else {
                        this.fnProcessResponse ();
                        if ( this.fnOnMoreCallback != null ) {
                            this.fnOnMoreCallback ();
                            this.fnOnMoreCallback = null;
                        }
                    }
                }
            }
            
            
            function NextSiblingElement(n)
            {
                n = n.nextSibling;
                while
                    ((n != null ) && (n.nodeType != 1))
                {
                    n = n.nextSibling;
                }
                return n;
            }

            function PreviousSiblingElement(n)
            {
                n = n.previousSibling;
                while
                    ((n != null ) && (n.nodeType != 1))
                {
                    n = n.previousSibling;
                }
                return n;
            }

            /***
				called in order to request more in the given direction
				bUp is true to request more items upwards, false to fetch more downwards
            **/
            scrollingBrowseListObject2.prototype.fnRequestMore = function ( bUp ) {
                
				if (bUp)
                {
                    trace("","fnRequestMore up called");
                }
                else
                {
                    trace("","fnRequestMore down called");
                }
                
                if ( ( this.strPendingRequest == null ) && ( ! this.bBadResponse ) ) {
                    trace("","eltopstop="+this.elTopStop.innerHTML);
                    trace("","elbottomstop="+this.elBottomStop);
                    trace("","ps="+this.elBottomStop.previousSibling);
                    
                    // so here we have a browser difference - in IE next / prev sibling does
                    // not seem to return text nodes, in mozilla it does return text nodes
                    // so we are going to have to make a helper functions for next/prev
                    // sibling element
                    
                    var el = bUp ? NextSiblingElement(this.elTopStop) : PreviousSiblingElement(this.elBottomStop);
                    trace("","element is "+el);
                    this.requestNumber++;
					this.strPendingRequest = bUp ? "up" : "down";
                	this.obAppServer.ClearCmd ();
                	var d = new Date();
                	this.obAppServer.SetUseUTF8Request ( 1 );
                	this.obAppServer.SetCmdPrefix ( el.getAttribute ( "targetObject" ) + this.strRequestExtra + "&ResponseEncoding=utf-8" );
                	this.obAppServer.CmdSet ( "Method", bUp ? "FetchIncrementalBrowseUp" : "FetchIncrementalBrowseDown" );
                	this.obAppServer.CmdSet("RequestId",this.requestNumber + "");
                	this.obAppServer.CmdSet("dateReq", d.getTime() + "");
                	this.obAppServer.SetUseMSXMLHTTPRequest ( 1 );
					
					if ( this.numBlocks > 999 ) {
                        var elBlock = bUp ? PreviousSiblingElement(this.elBottomStop) : NextSiblingElement(this.elTopStop);
                        var numStart = parseInt ( elBlock.getAttribute ( "strStartHandle" ) );
                        //alert(numStart);
                        var numEnd = parseInt ( elBlock.getAttribute ( "strEndHandle" ) );
                        //alert(numEnd);
                        this.bUpdatingList = true;
                        if ( bUp ) {
                            this.bFoundBottom = false;
                        } else {
                            this.bFoundTop = false;
                        }
                        this.fnColorMarkers ();
                        if ( ! ( isNaN ( numStart ) || isNaN ( numEnd ) ) ) {
                            //alert("Remove start "+numstart);
                            //alert("Remove end " +numEnd );
                            this.obAppServer.CmdSet ( "RemoveItemsStart", numStart.toString () );
                            this.obAppServer.CmdSet ( "RemoveItemsEnd", numEnd.toString () );
                            this.manager.removeChildElements ( elBlock );
                            if ( bUp ) {
                                elBlock.removeNode ( true );
                            } else {
                                var numCorrectedScrollTop = this.elBrowseList.scrollTop - elBlock.scrollHeight;
                                elBlock.removeNode ( true );
                                this.elBrowseList.scrollTop = numCorrectedScrollTop;
                            }
                            this.numBlocks--;
                        }
                        delete this.bUpdatingList;
                    }
                    trace("","calling DoCmdAsync");
				    this.obAppServer.DoCmdAsync ();
				
                    this.fnOnPoll ();
                }
            }
            /***
				@public
				can be called by to request more either upwards or downwards, can 
				provide a call back function which is called when we recieve the data
            **/
            
            scrollingBrowseListObject2.prototype.fnExternalRequestMore = function ( bUp, fnCallback ) {
                if ( this.bPageMode ) {
                    return false;
                } else {
                    if ( bUp ) {
                        if ( this.bFoundTop ) return false;
                    } else {
                        if ( this.bFoundBottom ) return false;
                    }
                    if ( this.strPendingRequest != null ) {
                        return false;
                    }
                    this.bNoPreloadAbove = false;
                    this.fnRequestMore ( bUp );
                    this.fnOnMoreCallback = fnCallback;
                    return true;
                }
            }

			/***
				colours the top and bottom markers according to the values of
				bFoundTop and bFoundBottom only
            **/
            
            scrollingBrowseListObject2.prototype.fnColorMarkers = function () {
                this.elTopStop.style.visibility = this.bFoundTop ? "visible" : "hidden";
                this.elBottomStop.style.visibility = this.bFoundBottom ? "visible" : "hidden";
            }
            
            /***
                returns true if we could scroll upwards 
                @type boolean
            **/
            scrollingBrowseListObject2.prototype.fnGetCanScrollUp = function () {
                with ( this.elBrowseList ) {
                    var numAbove = scrollTop;
                    var numUp = 0;
                    if ( this.bFoundTop ) {
                        numUp = this.elTopStop.offsetHeight;
                    }
                    if ( numAbove > numUp ) trace("","can scroll up is true");
                    trace("","num above is "+ numAbove);

                    return numAbove > numUp;
                }
            }

            /***
                returns true if we could scroll downwards
                @type boolean
            **/

            scrollingBrowseListObject2.prototype.fnGetCanScrollDown = function () {
                with ( this.elBrowseList ) {
					//debugger;
					// changed clientHeight to offsetHeight to get more consistent behaviour
					// with Mozilla.
                    var numBelow = ( ( scrollHeight - this.elPad.offsetHeight ) - scrollTop ) - offsetHeight;
                    if ( numBelow > 0 ) trace("","can scroll down is true");
                    else
                    {
                        trace("", "can scroll down return false");
                    }
                    trace("","num below is "+ numBelow);
                    return numBelow > 0;
                }
            }
            
            /*** 
				we call this in order to fill the list
            **/
            
			var stopCallTwice = false;
			
            scrollingBrowseListObject2.prototype.fnFill = function () {
				//if (stopCallTwice) return 
				//stopCallTwice = true;
				trace("","scrollingBrowseListObject2.fnFill called");
				
                if ( this.strPendingRequest == null ) {
				    
					stopCallTwice = false;
					
					with ( this.elBrowseList )   {
						
						
						if ( ! this.bPageMode ) {
                            var numAbove = this.elBrowseList.scrollTop;
							
							
							var numBelow = ( ( scrollHeight - this.elPad.offsetHeight ) - scrollTop ) - offsetHeight;
                            var numPixelFill = this.numPixelFill;
                            
						
                            
							if ( this.strName != null ) {
                                var obUpdate = new updateObject ();
                                var numUp = 0;
                                if ( this.bFoundTop ) {
                                    numUp = this.elTopStop.offsetHeight;
                                }
								
                                obUpdate.write ( this.strName, "canScrollUp", this.fnGetCanScrollUp () );
                                obUpdate.write ( this.strName, "canScrollDown", this.fnGetCanScrollDown () );
                                this.manager.oInterface.syncUpdate ( obUpdate );
                            }
                            if ( numBelow < numPixelFill ) {
                                if ( ! this.bFoundBottom ) {
									
                                    this.fnRequestMore ( false );
									stopCallTwice = false;
                                    return;
                                }
                            }
                            if ( numAbove < numPixelFill ) {
                                if ( this.bNoPreloadAbove != true ) {
                                    if ( ! this.bFoundTop ) {
									    this.fnRequestMore ( true );
                                        stopCallTwice = false;
										return;
                                    }
                                }
                            }
							
                        }
                    } 
                }
            }
            
            /***
				not sure what this is for 
            **/
            scrollingBrowseListObject2.prototype.fnFindTopCandidate = function ( el, elOffsetParent, numTop, numBottom, fnTest ) {
                for ( var elChild = el.firstChild; elChild != null; elChild = elChild.nextSibling ) {
                    if ( elChild.nodeType == 1 ) {
                        var numChildTop = 0;
                        var elP = elChild;
                        while ( true ) {
                            numChildTop += elP.offsetTop;
                            elP = elP.offsetParent;
                            if ( elP == elOffsetParent ) break;
                            if ( elP == null ) return null;
                        }
                        if ( numChildTop < numBottom ) {
                            var numChildBottom = numChildTop + elChild.offsetHeight;
                            if ( numChildBottom > numTop ) {
                                var obResult = fnTest ( elChild );
                                if ( obResult == null ) {
                                    obResult = this.fnFindTopCandidate ( elChild, elOffsetParent, numTop, numBottom, fnTest );
                                }
                                if ( obResult != null ) {
                                    return obResult;
                                }
                            }
                        }
                    }
                }
                return null;
            }

            /***
				I think this find the top object in the list - but why pass fnTest ?
            **/

            scrollingBrowseListObject2.prototype.fnFindTopObject = function ( fnTest ) {
                var numTop = this.elBrowseList.scrollTop;
                var numBottom = numTop + this.elBrowseList.offsetHeight;
                return this.fnFindTopCandidate ( this.elBrowseList, this.elBrowseList, numTop, numBottom, fnTest );
            }

            /***
				I think this find the top object in the list which has a handle and is selectable
            **/

            scrollingBrowseListObject2.prototype.fnGetTopListItemElement = function () {
                var obManager = this.manager;
                var fnTest = function ( el ) {
                    if ( el.objectHandle != null ) {
                        var ob = obManager.getObject ( el.objectHandle );
                        if ( ob != null ) {
                            if ( ob.selectable != null ) {
                                return ob;
                            }
                        }
                    }
                    return null;
                }
                return this.fnFindTopObject ( fnTest );
            }

            /***
				I think this find the top object in the list which has an "alsiListItemIdetifier"
            **/

            scrollingBrowseListObject2.prototype.fnGetTopListItemIdentifier = function () {
                var strAttr = this.manager.attributePrefix + "ListItemIdentifier";
                var fnTest = function ( el ) {
                    if ( el.nodeType == 1 ) {
                        var str = el.getAttribute ( strAttr );
                        if ( str != null ) {
                            return el;
                        }
                    }
                    return null;
                }
                var el = this.fnFindTopObject ( fnTest );
                if ( el != null ) {
                    return el.getAttribute ( strAttr );
                }
                return null;
            }
            
            /***
				selects the first item in the list - maybe this is for keyboard support ?
            **/
            
            scrollingBrowseListObject2.prototype.fnSelectTop = function () {
                if ( this.manager.selectedObject == null ) {
                    var elTop = this.fnGetTopListItemElement ();
                    if ( elTop != null ) {
                        this.manager.setSelectedObject ( elTop );
                    }
                }
            }
            
            /***
				on focus we select the top item, then focus on the list
            **/

            scrollingBrowseListObject2.prototype.fnSetFocus = function () {
                this.fnSelectTop ();
                if
                    (this.elBrowseList)
                {
                    if (this.elBrowseList.focus)
                    {
                        this.elBrowseList.focus ();
                    }
                }
            }


            /***
				scroll up numpixels
            **/

            scrollingBrowseListObject2.prototype.fnDoScrollUp = function ( numPixels ) {
				var temp = this.elBrowseList.scrollTop;
				temp -= numPixels; 
				if (temp <0) temp = 0;
				trace("","fnDoScrollUp "+ numPixels+" new scroll top = "+temp );
                this.elBrowseList.scrollTop = temp;
                
                
				var obUpdate = new updateObject ();
				obUpdate.write ( this.strName, "canScrollUp", this.fnGetCanScrollUp () );
                obUpdate.write ( this.strName, "canScrollDown", this.fnGetCanScrollDown () );
                this.manager.oInterface.syncUpdate ( obUpdate );                
            }
            
            /***
				scroll down numpixels
            **/
            
            scrollingBrowseListObject2.prototype.fnDoScrollDown = function ( numPixels ) {
				trace("","fnDoScrollDown "+ numPixels );
				var temp = this.elBrowseList.scrollTop;
				trace("","scrollTop "+ temp );
				temp += numPixels;
				trace("","try to set to "+ temp );
				//debugger;
                this.elBrowseList.scrollTop = temp;
                trace("","new scrollTop "+ this.elBrowseList.scrollTop );
                
                
				var obUpdate = new updateObject ();
				obUpdate.write ( this.strName, "canScrollUp", this.fnGetCanScrollUp () );
                obUpdate.write ( this.strName, "canScrollDown", this.fnGetCanScrollDown () );
                this.manager.oInterface.syncUpdate ( obUpdate );                
            }
            
            /***
				compute number of pixels from percentage
            **/
            
            scrollingBrowseListObject2.prototype.fnGetPercentAsPixels = function ( numPercent ) {
                var numHeight = this.elBrowseList.offsetHeight;
                numPercent = parseFloat ( numPercent.toString () );
                return ( numPercent / 100.0 ) * numHeight;
            }
            
            /***
                scroll up numPercent % pixels  
            **/
            scrollingBrowseListObject2.prototype.fnDoScrollUpPercent = function ( numPercent ) {
                this.fnDoScrollUp ( this.fnGetPercentAsPixels ( numPercent ) );
            }

            /***
                scroll down numPercent % pixels  
            **/
            
            scrollingBrowseListObject2.prototype.fnDoScrollDownPercent = function ( numPercent ) {
                this.fnDoScrollDown ( this.fnGetPercentAsPixels ( numPercent ) );
            }
            
            
            /***
                called when a key goes down - currently does nothing
            **/
            scrollingBrowseListObject2.prototype.onKeyDown = function (e) {

//                if (!e) var e = window.event;
//                var element = getTargetElement( e );
//                var code = getKeyCode( e );
                return false;
            }

            /***
                called when a key is pressed - currently does nothing
            **/

            scrollingBrowseListObject2.prototype.onKeyPress = function (e) {
//                if (!e) var e = window.event;
//                var element = getTargetElement( e );
//                var code = getKeyCode( e );

                return false;
            }
            
            /***
                called when a key is pressed - currently does nothing
            **/
            scrollingBrowseListObject2.prototype.onKeyUp = function () {
            }

            /***
                called when we focus on the list ?
            **/

            scrollingBrowseListObject2.prototype.focusIn = function () {
                if ( ! this.bActive ) {
                    this.fnSelectTop ();
                    this.bActive = true;
                }
            }
            
            /***
                called when we focus out of the list - set's bActive to true - why ?
            **/
            scrollingBrowseListObject2.prototype.focusOut = function () {
                this.bActive = true;
            }




            function applyToChildren( n, f )
            {
            
                if (n.nodeType == 1 /*Node.ELEMENT_NODE*/)
                {
                    f(n);
                }
                    
                var children = n.childNodes;
                if
                    (n != null )
                {                
                    for(var i=0; i < children.length; i++) {    
                        applyToChildren(children[i],f);      
                    }
                }
            }
            
            function isChild( n, child )
            {
            
                if (n.nodeType == 1 /*Node.ELEMENT_NODE*/)
                {
                    
                }
                    
                var children = n.childNodes;
                if
                    (n != null )
                {                
                    for(var i=0; i < children.length; i++) {    
                        if (children[i] == child) return true;
                        if (isChild(children[i],child)) return true;      
                    }
                }
                return false;
            }
            
            function contains( parent, child )
            {
                if (parent.contains) 
                {
                    // this is ie - so this useful helper exists
                    return parent.contains(child);
                }
                return isChild( parent, child );
                
            }

            scrollingBrowseListObject2.prototype.fnTestIfVisible = function (elem,top) 
            {
                // if top then we want to make the top of the item visible otherwise we will make the bottom visible
                var top_y = this.elBrowseList.scrollTop;
                var bot_y = this.elBrowseList.scrollTop+this.elBrowseList.clientHeight;
                var elem_y = elem.offsetTop;
                //debugger;    
                
                var p = elem.offsetParent;
                
                while
                    ((p != null ) && (p != this.elBrowseList )  && contains(this.elBrowseList,p))
                {
                    //alert(elem_y);
                    elem_y += p.offsetTop;
                    p = p.offsetParent;
                }
                
                if (p == null )
                {
                    
                    alert("Make visible called on element which is not a child of the browse list");
                    var p = elem.offsetParent;
                    while
                        ((p != null ) && (p != this.elBrowseList ))
                    {
                        alert(p.innerHTML);
                        p = p.offsetParent;
                    }
                    
                }
                
                var elem_by  = elem_y+elem.clientHeight;
                elem_by += this.elBrowseList.scrollTop;
                //alert("top_y is "+ top_y );
                //alert("bot_y is "+ bot_y );
                //alert("elem_y is "+elem_y);
                //alert("elem_by is "+elem_by);
                
                if ( elem_y < top_y )
                {
                   if (elem_y > 100 ) elem_y -= 100;
                   return false;
                }
                
                
                if ( elem_y > bot_y )
                {
                    return false;
                }

                return true;                
            }

            scrollingBrowseListObject2.prototype.fnMakeVisible = function (elem,top) 
            {
                // if top then we want to make the top of the item visible otherwise we will make the bottom visible
                var top_y = this.elBrowseList.scrollTop;
                var bot_y = this.elBrowseList.scrollTop+this.elBrowseList.clientHeight;
                var elem_y = elem.offsetTop;
                //debugger;    
                
                var p = elem.offsetParent;
                
                while
                    ((p != null ) && (p != this.elBrowseList )  && contains(this.elBrowseList,p))
                {
                    //alert(elem_y);
                    elem_y += p.offsetTop;
                    p = p.offsetParent;
                }
                
                if (p == null )
                {
                    
                    alert("Make visible called on element which is not a child of the browse list");
                    var p = elem.offsetParent;
                    while
                        ((p != null ) && (p != this.elBrowseList ))
                    {
                        alert(p.innerHTML);
                        p = p.offsetParent;
                    }
                    
                }
                
                var elem_by  = elem_y+elem.clientHeight;
                elem_by += this.elBrowseList.scrollTop;
                //alert("top_y is "+ top_y );
                //alert("bot_y is "+ bot_y );
                //alert("elem_y is "+elem_y);
                //alert("elem_by is "+elem_by);
                
                if ( elem_y < top_y )
                {
                   if (elem_y > 100 ) elem_y -= 100;
                   this.elBrowseList.scrollTop = elem_y;
                }
                
                
                if ( elem_y > bot_y )
                {
                    //alert("we need to scroll down");
                    
                    // so we want scroll top to be as follows.
                    
                    var scroll_top = elem_y - bot_y+ this.elBrowseList.scrollTop;
                    scroll_top+=100;
                    
                    //if (scroll_top + this.elBrowseList.clientHeight > this.elBrowseList.offsetHeight )
                    //{
                    //   scroll_top = 
                    
                    //alert(scroll_top);
                    
                    this.elBrowseList.scrollTop = scroll_top;
                }

                
            }

        function xDocManScrollBrowseList2_Startup()
        {
            documentManager.registerClass ( "scrollingBrowseList", scrollingBrowseListObject2 );

        }
