function AEslideshow(pAEid, pAE_HTML_Node, pAE_ParamList, pAE_Parent)
{
/*
This is the Slideshow Active Element, which is responsible for providing the
display of a sequence of images

In its initial form, the images are specified as being those in a particular server-side
directory, and are displayed in a round-robin fashion. alternatives may be to display
images in a random order, and from other sources.

*/
    
    D.debugStartFunction("AEslideshow", arguments);
    
    this.superclass = activeElement;
    this.superclass(pAEid, "AEslideshow", "", pAE_HTML_Node, pAE_ParamList, pAE_Parent);
    
    var intervalBetweenImages;
    
    this.aeInitialise = function() // Overloads master aeInitialise function
    {
        /*
        Overrides aeInitialise from master activeElement class.
        
        Called after new AE has been created.  Populates HTML nodes with startup text and
        performs any other initialisation for this AE.

        Request list of images from server, based on parameters supplied.
        (Response will be processed in aeProcessResponseData method)
        */
        
        D.debugStartFunction("AEslideshow:aeInitialise", arguments);

        var Header = new Array;
        var Parameters = new Array;
        var DataRequest;
        var RequestXML;
        var RequestDetails;

        Parameters = this.aeParseParameters(this.AE_paramList);
        
        if (Parameters['interval'])
        {
            this.intervalBetweenImages = Parameters['interval'];
            D.debug("interval between images is " + this.intervalBetweenImages + " seconds.");
        }
        else
        {
            this.intervalBetweenImages = 5; // default number of seconds between images
            D.debug("Defaulting to " + this.intervalBetweenImages + " seconds between images.");
        }
        
        this.aeSetStatus("RequestingData");
        D.debug("Sending Request");
        
        Header['msgseqnum']   = "01" // this.aeGetMsgSeqNum();
        Header['requesttype'] = 'datarequest';
        Header['loggingflag'] = 'true';
        Header['aetype']      = this.aeGetAEtype();
        Header['aeid']        = this.aeGetAEid();

        RequestXML = this.aeCreateRequestHeaderXML(Header);

        // The payload for the Imagelist request will consist of the request type (i.e. Imagelist) and
        // the (sub)directory for which a list of files will be returned.
        RequestDetails = this.aeXMLnodeCreate('datarequesttype', 'Imagelist');
        RequestDetails += this.aeXMLnodeCreate('directory', Parameters['directory']);
        RequestXML += this.aeCreateDataRequestXML(RequestDetails);
        
        DataRequest = this.aeXMLnodeCreate('activeelementrequest', RequestXML);
        
        this.aeSendRequest(DataRequest);
    
        // Propogate to any controlled AEs under this one
        
        for (var i=0; i<this.AE_controlledAE_Count; i++)
        {
            this.AE_controlledAE_List[i].aeInitialise();
        }
        
        D.debugEndFunction("aeInitialise");
    }
    
    this.aeScreenChange = function(pScreen)
    {
        D.debugStartFunction("AEslideshow.aeScreenChange", arguments);
        
        this.aeUpdateContent();
        // Cascade to all child AEs
        
        for (var i=0; i<this.AE_controlledAE_Count; i++)
        {
            D.debug("Cascading to AEid " + this.AE_controlledAE_List[i].AE_AEid);
            this.AE_controlledAE_List[i].aeScreenChange(pScreen);
        }
        D.debugEndFunction();
    }

    this.aeUpdateContent = function()
    {
        // This function starts the slideshow, which then runs automatically
        
        D.debugStartFunction("AEslideshow:aeUpdateContent", arguments);
        
        // Used to call this.aeStartSlideshow() but this is not the right time because aeUpdateContent gets called
        // before we have the reponse data, so the starting of the slideshow is triggered by the receipt of the data
        // and there is nothing left to do in this aeUpdateContent function.
        
        D.debugEndFunction();
    }
    
    this.aeParseParameters = function(pParamString)
    {
    /* 
    This function parses the parameter list passed in to the constructor for the Slideshow.
    
    It is of the form name=value pairs separated by &
    where
        name = dir | interval
    and
        value = [dir] directory (relative or absolute)
                [interval] number (of seconds between images)
        
    */
        var paramArray = pParamString.split("&"); // now we can work on paramArray
        var paramData = new Array;

        D.debugStartFunction("aeParseParameters", arguments);

        for (var i=0; i<paramArray.length; i++)
        {
            var singleParamArray = paramArray[i].split("="); // now we can work on singleParamArray
            
            switch ( singleParamArray[0] )
            {
                case "dir":
                    paramData['directory'] = singleParamArray[1];
                    D.debug("Parameter [" + singleParamArray[0] + "] is [" + singleParamArray[1] + "]");
                break;
            
                case "interval":
                    paramData['interval'] = singleParamArray[1];
                    D.debug("Parameter [" + singleParamArray[0] + "] is [" + singleParamArray[1] + "]");
                break;
            
                default:
                    D.debug("Parameter [" + singleParamArray[0] + "] not known");
                break;
            }
        }

        D.debugEndFunction();
        return paramData;
    }
        
    this.aeCreateDataRequestXML = function(pRequestDetails)
    {
        var XML;
        
        XML = this.aeXMLnodeCreate('datarequest', pRequestDetails);
        
        return XML;
    }
    
    this.aeProcessResponseData = function(pXML)
    {
        /*
        This function overrides that of the parent class.
         
        From the file list returned, generate the XHTML to reside in the Slideshow, and start
        a timer to trigger the transition from one image to another.
        
        Note that associated CSS will style the slideshow (inc. showing/hiding images)
        */
        
        D.debugStartFunction("aeProcessResponseData", arguments);
        
        // Invoke the slideshow using the data received from the server       
        this.aeStartSlideshow(pXML);

        D.debugEndFunction();        
    }

    // Run the slideshow using (a) the data received from the server, (b) the time interval specified in the AE param list,
    // and (c) the base node for this active element (to allow more than one slideshow on a page)
    this.aeStartSlideshow = function( pXML )
    {
        D.debugStartFunction("aeStartSlideshow", arguments);
        
        // Non-object version - works, but limited to one slideshow per page
        D.debug("Slideshow: about to invoke run_slideshow with interval = " + this.intervalBetweenImages);
        run_slideshow( this.GetBaseNode(), pXML, this.intervalBetweenImages );

        //Object version - haven't quite got this working
        //D.debug("Slideshow: about to create new SlideshowObject and call SlideshowObject.run_slideshow");
        //mySlideshow = new SlideshowObject;
        //mySlideshow.run_slideshow( this.GetBaseNode(), pXML, this.intervalBetweenImages );
        
        D.debugEndFunction();        
    }


    this.aeInitialise();
    this.aeUpdateContent();
    
    D.debugEndFunction("AEslideshow");
}