<!--

//
// Script    :   fes_gen_functions.js
// Author    :   C.E. Berry
// Notes     :   General Javascript function library for Flex-eSystems products
//
//               All material contained within is the intellectual property of Flex-eSystems Ltd.
//               and as such may not be reproduced in any way shape or form without the prior
//               consent of Flex-eSystems.
//
// Amendment Log
//
//      Version      Date           Author              Notes
//      -------      ----           ------              -----
//
//      5.00.006    05/02/2010      P.I. Gunhouse       Testing possible bug in fncFesGetAbsolutePosition
//                                                      Added extra browser detection for IE7 & 8
//
//      5.00.000    07/06/2009      P.I. Gunhouse       Added fesSlideShow and fesSlideShowController
//                                                      objects
//                                                      Added fncFesGetVerticalScroll
//
//      4.00.014    11/11/2008      P.I. Gunhouse       Updated FncDelayedPageSubmit
//                                                      Added fncFesGetDocumentHeight
//                                                      Added fncFesGetWindowHeight
//
//                  04/12/2007      C.E. Berry          Added 'Functions for Layer/Menu
//                                                      manipulation'
//
//      4.00.009    04/12/2007      C.E. Berry          Added fncFesDelayedPageSubmit function
//
//      4.00.000    21/03/2007      C.E. Berry          Added fncFesReDirCountdown function
//
//      3.00.028    27/07/2006      C.E. Berry          Amended fncFesSelectFormElementText to
//                                                      include create range statement and include
//                                                      commented out code that may after testing
//                                                      work better with browsers other than IE
//
//      1.14        04/08/2006     P.I. Gunhouse        Added fncFesLimitTextarea
//
//      1.13        18/10/2004     C.E. Berry           Amended fncFesGetEnvironment to cater for
//                                                      Safari browser
//
//      1.12        12/05/2004     P.I. Gunhouse        fncFesToggleCheckBoxes and
//                                                      fncFesToggleCheckBox
//
//      1.11        12/03/2004     C.E. Berry           Added copy to fncFesSelectFormElementText
//                                                      function
//
//      1.10        14/01/2004     C.E. Berry           Added fncFesGoToURLFromSelect function
//
//      1.9         12/01/2004     C.E. Berry           Added fncFesRandomNumber function
//
//      1.8         02/01/2004     C.E. Berry           Amended fncFesGetEnvironment to return
//                                                      opera6up and opera7up to indicate Opera
//                                                      6 or above and Opera 7 or above
//                                                      respectively
//
//      1.7         27/12/2003     C.E. Berry           Amended fncFesMoCreateOptionArrayElement
//                                                      fncFesMoCreateOptionArrayElement and
//                                                      fncFesMoPreload to no longer reference
//                                                      prm_top as full image name can now be
//                                                      passed to mouseover functions.
//
//                                                      Amended fncFesMoCreateOptionArrayElement
//                                                      to extract file extension from image names
//                                                      rather than always assuming they will be
//                                                      GIF images.
//
//      1.6         16/05/2003     C.E. Berry           Amended fncFesOpenWindow to perform a
//                                                      window.focus for Netscape browsers
//                                                      (prevents popup window from opening
//                                                      behind main window)
//
//                                                      Added fncFesResizeWindow and
//                                                      fncFesCheckResizeWindow functions.
//
//                                                      Added check for new versions of Opera/
//                                                      Netscape to fnsFesGetEnvironment.
//
//                                                      Amended script to execute
//                                                      fnsFesGetEnvironment function at end of
//                                                      script.
//
//      1.5         21/08/2002     C.E. Berry           Amended fncFesGetEnvironment to cater for
//                                                      Netscape 7
//
//      1.4         08/05/2002     C.E. Berry           Amended fncFesGetEnvironment to cater for
//                                                      Windows XP and Internet Explorer 6.
//
//      1.3         24/02/2002     C.E. Berry           Amended fncFesGetUrlParameters function to
//                                                      return array even if empty.
//
//      1.2         16/12/2001     C.E. Berry           Added fncFesGetEnvironment function.
//                                                      Amended exisitng functions and variables
//                                                      to fit in with more logical naming
//                                                      convention.
//                                                      Amended mouseover functions to use
//                                                      associative array rather than indexed
//                                                      array.
//                                                      Added fncFesSelectFormElementText function.
//
//      1.1         21/09/2001     C.E. Berry           Added fncFesGetUrlParameters function.
//
//      1.0         04/03/2000     C.E. Berry           Creation
//
//=================================================================================================
//
// General functions
//
//=================================================================================================

function fncFesGetEnvironment()
//
// Function to return information about the client environment e.g. operating system, browser
// type etc.
//
//    Function based on Ultimate client-side JavaScript sniffer Version 3.03
//    (C) Netscape Communications 1999.  Permission granted to reuse and distribute.
//
// Function creates an object with the following properties which are true/false unless
// otherwise indicated:-
//
// Navigator Object Properties
//
// useragent        - useragent string
// appname          - application name
// appversion       - application version
//
// Browser Vendor:
//
// ns               - Netscape
// ie               - Microsoft Internet Explorer
// opera            - Opera
// safari           - Safari (Apple)
// hotjava          - HotJava (sun)
// webtv            - WebTV
// tvnavigator      - TV Navigator
// aoltv            - AOL TV
//
// Browser Version Numbers
//
// major_version    - Integer containing major Version Number e.g. 2, 3, 4 ...
// minor_version    - Float containing minor Version Number e.g. 2.06, 3.02, 4.05 ...
//
// Browser Vendor & Version
//
// ns2              - Netscape 2
// ns3              - Netscape 3
// ns4              - Netscape 4
// ns6              - Netscape 6
// ns7              - Netscape 7
// gecko            - Gecko
// ie3              - Microsoft Internet Explorer 3
// ie4              - Microsoft Internet Explorer 4
// ie5              - Microsoft Internet Explorer 5
// ie5_5            - Microsoft Internet Explorer 5.5
// ie6              - Microsoft Internet Explorer 6
// aol3             - America Online 3
// aol4             - America Online 4
// aol5             - America Online 5
// aol6             - America Online 6
// opera2           - Opera 2
// opera3           - Opera 3
// opera4           - Opera 4
// opera5           - Opera 5
// opera6           - Opera 6
// opera7           - Opera 7
// safari           - Safari
// hotjava3         - HotJava 3
//
// Browser Vendor and Version upward compatibility
//
// ns4up            - Netscape 4 or higher
// ns6up            - Netscape 6 or higher
// ns7up            - Netscape 7 or higher
// ie4up            - Microsoft Internet Explorer 4 or higher
// ie5up            - Microsoft Internet Explorer 5 or higher
// ie5_5up          - Microsoft Internet Explorer 5.5 or higher
// ie6up            - Microsoft Internet Explorer 6 or higher
// opera5up         - Opera 5 or higher
// opera6up         - Opera 6 or higher
// opera7up         - Opera 7 or higher
// hotjava3up       - HotJava 3 or higher
//
// Javascript version
//
// js               - float containing full Javascript version number
//
// Platform/Operating System
//
// win              - Microsoft Windows
// win16            - Microsoft Windows 16 bit
// win32            - Microsoft Windows 32 bit
// win31            - Microsoft Windows 3.1
// win95            - Microsoft Windows 95
// win98            - Microsoft Windows 98
// winme            - Microsoft Windows Millenium Edition
// winnt            - Microsoft Windows NT
// win2k            - Microsoft Windows 2000
// winxp            - Microsoft Windows XP
// os2              - IBM OS2
// mac              - Apple Macintosh
// mac68k           - Apple Macintosh 68K
// macppc           - Apple Macintosh Power PC
// unix             - Unix
// sun              - Sun
// sun4             - Sun 4
// sun5             - Sun 5
// suni86           - Sun for Intel 86
// irix             - Irix
// irix5            - Irix 5
// irix6            - Irix 6
// aix              - Aix
// aix1             - Aix 1
// aix2             - Aix 2
// aix3             - Aix 3
// aix4             - Aix 4
// linux            - Linux
// sco              - Sco Unix
// unixware         - Unixware
// mpras            - Mpras
// reliant          - Reliant Unix
// dec              - Digital (Compaq) Ultrix/Alpha
// sinix            - Sinix
// freebsd          - FreeBSD
// bsd              - BSD
// vms              - Digital (Compaq) VMS
//
{

// Get the Navigator properties

    this.useragent = navigator.userAgent;
    this.appname = navigator.appName;
    this.appversion = navigator.appVersion;

// Get the user agent string and convert all characters to lowercase to simplify testing

    var loc_usragt = navigator.userAgent.toLowerCase();

//=================================================================================================
//
// Browser Information
//
//=================================================================================================

// Get the browser major and minor version id's

    this.major_version = parseInt(navigator.appVersion);
    this.minor_version = parseFloat(navigator.appVersion);

// Set up browser values
//
// ns = Netscape Navigator

// Opera and WebTV spoof Navigator so have to eliminate them via specific search for the browser
// names in the user agent.

    this.ns  = ((loc_usragt.indexOf("mozilla")!= -1) &&
                (loc_usragt.indexOf("spoofer") == -1) &&
                (loc_usragt.indexOf("compatible") == -1) &&
                (loc_usragt.indexOf("opera") == -1) &&
                (loc_usragt.indexOf("webtv") == -1) &&
                (loc_usragt.indexOf("safari") == -1) &&
                (loc_usragt.indexOf("hotjava") == -1));

    this.ns2 = (this.ns &&
               (this.major_version == 2));

    this.ns3 = (this.ns &&
               (this.major_version == 3));

    this.ns4 = (this.ns &&
               (this.major_version == 4));

// Although Netscape 6/7 should have major versions of 6/7 they actually report a major version
// of 5

    this.ns6 = (this.ns &&
                this.major_version == 5 &&
                loc_usragt.indexOf("netscape 7") == -1 &&
                loc_usragt.indexOf("netscape/7") == -1);

    this.ns7 = (this.ns &&
                this.major_version == 5 &&
               (loc_usragt.indexOf("netscape 7") != -1 ||
                loc_usragt.indexOf("netscape/7") != -1));

    this.ns4up = (this.ns &&
                 (this.major_version >= 4));

    this.ns6up = (this.ns &&
                 (this.major_version >= 5));

    this.ns7up = (this.ns &&
                  this.major_version == 5 &&
                 (loc_usragt.indexOf("netscape 7") != -1 ||
                  loc_usragt.indexOf("netscape/7") != -1));

    this.nsonly =  (this.ns &&
                  ((loc_usragt.indexOf(";nav") != -1) ||
                   (loc_usragt.indexOf("; nav") != -1)));

    this.gecko = (loc_usragt.indexOf("gecko") != -1 &&
                  loc_usragt.indexOf("safari") != -1);

// ie = Internet Explorer

    this.ie      = ((loc_usragt.indexOf("msie") != -1) &&
                    (loc_usragt.indexOf("opera") == -1));

    this.ie3     = (this.ie &&
                   (this.major_version < 4));

// Although Internet Explorer 4, 5, 5.5 and 6 should have a major versions of 4, 5, 5 and 6
// respectively they all report a major version of 4 so need to search the user agent string for
// specific names for each of them.

    this.ie4     = (this.ie &&
                   (this.major_version == 4) &&
                   (loc_usragt.indexOf("msie 4")!=-1));

    this.ie5     = (this.ie &&
                   (this.major_version == 4) &&
                   (loc_usragt.indexOf("msie 5.0")!=-1));

    this.ie5_5   = (this.ie &&
                   (this.major_version == 4) &&
                   (loc_usragt.indexOf("msie 5.5") !=-1));

    this.ie6     = (this.ie &&
                   (this.major_version == 4) &&
                   (loc_usragt.indexOf("msie 6.")!=-1));

    this.ie7     = (this.ie &&
                   (this.major_version == 4) &&
                   (loc_usragt.indexOf("msie 7.")!=-1));

    this.ie7comp = (document.documentMode == 7);

    this.ie8     = (this.ie &&
                   (this.major_version == 4) &&
                   (loc_usragt.indexOf("msie 8.")!=-1));

    this.ie4up   = (this.ie  &&
                   (this.major_version >= 4));

    this.ie5up   = (this.ie  &&
                   !this.ie3 &&
                   !this.ie4);

    this.ie5_5up = (this.ie &&
                   !this.ie3 &&
                   !this.ie4 &&
                   !this.ie5);

    this.ie6up   = (this.ie  &&
                   !this.ie3 &&
                   !this.ie4 &&
                   !this.ie5 &&
                   !this.ie5_5);

    this.ie7up   = (this.ie  &&
                   !this.ie3 &&
                   !this.ie4 &&
                   !this.ie5 &&
                   !this.ie5_5 &&
                   !this.ie6);

// aol = America Online - note that on AOL4 the test returns false if IE3 is the embedded browser
// or if this is the first browser window opened. Therefore the aol, aol3 and aol4 variables are
// not completely reliable

    this.aol   = (loc_usragt.indexOf("aol") != -1);

    this.aol3  = (this.aol &&
                  this.ie3);

    this.aol4  = (this.aol &&
                  this.ie4);

    this.aol5  = (loc_usragt.indexOf("aol 5") != -1);

    this.aol6  = (loc_usragt.indexOf("aol 6") != -1);

// opera = Opera

    this.opera =  (loc_usragt.indexOf("opera") != -1);

    this.opera2 = (loc_usragt.indexOf("opera 2") != -1 ||
                   loc_usragt.indexOf("opera/2") != -1);

    this.opera3 = (loc_usragt.indexOf("opera 3") != -1 ||
                   loc_usragt.indexOf("opera/3") != -1);

    this.opera4 = (loc_usragt.indexOf("opera 4") != -1 ||
                   loc_usragt.indexOf("opera/4") != -1);

    this.opera5 = (loc_usragt.indexOf("opera 5") != -1 ||
                   loc_usragt.indexOf("opera/5") != -1);

    this.opera6 = (loc_usragt.indexOf("opera 6") != -1 ||
                   loc_usragt.indexOf("opera/6") != -1);

    this.opera7 = (loc_usragt.indexOf("opera 7") != -1 ||
                   loc_usragt.indexOf("opera/7") != -1);

    this.opera5up = (this.opera &&
                    !this.opera2 &&
                    !this.opera3 &&
                    !this.opera4);

    this.opera6up = (this.opera &&
                    !this.opera2 &&
                    !this.opera3 &&
                    !this.opera4 &&
                    !this.opera5);

    this.opera7up = (this.opera &&
                    !this.opera2 &&
                    !this.opera3 &&
                    !this.opera4 &&
                    !this.opera5 &&
                    !this.opera6);
// safari = Safari

    this.safari = (loc_usragt.indexOf("safari") != - 1);

// webtv = WebTV

    this.webtv = (loc_usragt.indexOf("webtv") != -1);

    this.tvnavigator = ((loc_usragt.indexOf("navio") != -1) ||
                        (loc_usragt.indexOf("navio_aoltv") != -1));

    this.aoltv = this.tvnavigator;

// hotjava - HotJava (Sun)

    this.hotjava = (loc_usragt.indexOf("hotjava") != -1);

    this.hotjava3 = (this.hotjava &&
                    (this.major_version == 3));

    this.hotjava3up = (this.hotjava &&
                      (this.major_version >= 3));

//=================================================================================================
//
// Javascript Information
//
//=================================================================================================

    if (this.ns2 ||
        this.ie3)
    {
        this.js = 1.0;

    }

    if (this.ns3)
    {
        this.js = 1.1;

    }

    if (this.opera)
    {
        this.js = 1.1;

    }

    if (this.opera5up)
    {
        this.js = 1.3;

    }

    if ((this.ns4 &&
        (this.minor_version <= 4.05)) ||
         this.ie4)
    {
        this.js = 1.2;

    }

    if ((this.ns4 &&
        (this.minor_version > 4.05)) ||
         this.ie5)
    {
        this.js = 1.3;

    }

    if (this.hotjava3up)
    {
        this.js = 1.4;

    }

    if (this.ns6 ||
       this.gecko)
    {
        this.js = 1.5;

    }

    if (this.ns6up)
    {
        this.js = 1.5;

    }

    if (this.ie5up&
        loc_usragt.indexOf("mac") == -1)
    {
        this.js = 1.3;

    }


// On the Mac platform Javascript is Version 1.4 under Internet Explorer 5 and above

    if (this.ie5up&
        loc_usragt.indexOf("mac") != -1)
    {
        this.js = 1.4;
    }

//=================================================================================================
//
// Platform/OS Information
//
//=================================================================================================

// Microsoft Windows

    this.win = ((loc_usragt.indexOf("win") != -1) ||
                (loc_usragt.indexOf("16bit") != -1));

// On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all Win32 platforms so
// distnguishing between Windows 95 and NT is not possible

    this.win95 = ((loc_usragt.indexOf("win95") != -1) ||
                  (loc_usragt.indexOf("windows 95") != -1));

    this.win16 = ((loc_usragt.indexOf("win16") != -1) ||
                  (loc_usragt.indexOf("16bit") != -1) ||
                  (loc_usragt.indexOf("windows 3.1") != -1) ||
                  (loc_usragt.indexOf("windows 16-bit") != -1));

    this.win31 = ((loc_usragt.indexOf("windows 3.1") != -1) ||
                  (loc_usragt.indexOf("win16") != -1) ||
                  (loc_usragt.indexOf("windows 16-bit") != -1));

// Reliable detection of Windows 98 is not possible as on Ns4 and earlier you just get 'Windows'
// in the user agent string and on the Mercury client you get 'Win98' returned for the 32 bit
// version, but 'Win95' for the 16 bit version

    this.win98 = ((loc_usragt.indexOf("win98") != -1) ||
                  (loc_usragt.indexOf("windows 98") != -1));

    this.winnt = ((loc_usragt.indexOf("winnt") != -1) ||
                  (loc_usragt.indexOf("windows nt") != -1) ||
                  (loc_usragt.indexOf("windows 2000") != -1));

    this.win32 =  (this.win95 ||
                   this.winnt ||
                   this.win98 ||
                 ((this.major_version >= 4) &&
                  (navigator.platform == "Win32")) ||
                  (loc_usragt.indexOf("win32") != -1) ||
                  (loc_usragt.indexOf("32bit") != -1));

    this.winme = (loc_usragt.indexOf("win 9x 4.90") != -1);

    this.win2k = ((loc_usragt.indexOf("windows nt 5.0") != -1) ||
                  (loc_usragt.indexOf("windows 2000") != -1));

    this.winxp = (loc_usragt.indexOf("windows nt 5.1") != -1);

// IBM OS2

    this.os2   = ((loc_usragt.indexOf("os/2") != -1) ||
                  (navigator.appVersion.indexOf("OS/2") != -1) ||
                  (loc_usragt.indexOf("ibm-webexplorer") != -1));

// Apple Mac

    this.mac    = (loc_usragt.indexOf("mac") != -1);

    this.mac68k =  (this.mac &&
                  ((loc_usragt.indexOf("68k") != -1) ||
                   (loc_usragt.indexOf("68000") != -1)));

    this.macppc =  (this.mac &&
                  ((loc_usragt.indexOf("ppc") != -1) ||
                   (loc_usragt.indexOf("powerpc") != -1)));

// Various Unix and Linux derivatives

    this.sun   = (loc_usragt.indexOf("sunos") != -1);

    this.sun4  = (loc_usragt.indexOf("sunos 4") != -1);

    this.sun5  = (loc_usragt.indexOf("sunos 5") != -1);

    this.suni86 = (this.sun && (loc_usragt.indexOf("i86") != -1));

    this.irix  = (loc_usragt.indexOf("irix") != -1);

    this.irix5 = (loc_usragt.indexOf("irix 5") != -1);

    this.irix6 = ((loc_usragt.indexOf("irix 6") != -1) ||
                  (loc_usragt.indexOf("irix6") != -1));

    this.hpux  = (loc_usragt.indexOf("hp-ux")!=-1);

    this.hpux9 = (this.hpux &&
                 (loc_usragt.indexOf("09.") != -1));

    this.hpux10= (this.hpux &&
                 (loc_usragt.indexOf("10.") != -1));

    this.aix   = (loc_usragt.indexOf("aix") != -1);

    this.aix1  = (loc_usragt.indexOf("aix 1") != -1);

    this.aix2  = (loc_usragt.indexOf("aix 2") != -1);

    this.aix3  = (loc_usragt.indexOf("aix 3") != -1);

    this.aix4  = (loc_usragt.indexOf("aix 4") != -1);

    this.linux = (loc_usragt.indexOf("inux") != -1);

    this.sco   = (loc_usragt.indexOf("sco") != -1) ||
                 (loc_usragt.indexOf("unix_sv") != -1);

    this.unixware = (loc_usragt.indexOf("unix_system_v") != -1);

    this.mpras    = (loc_usragt.indexOf("ncr") != -1);

    this.reliant  = (loc_usragt.indexOf("reliantunix") != -1);

    this.dec   = ((loc_usragt.indexOf("dec") != -1) ||
                  (loc_usragt.indexOf("osf1") != -1) ||
                  (loc_usragt.indexOf("dec_alpha") != -1) ||
                  (loc_usragt.indexOf("alphaserver") != -1) ||
                  (loc_usragt.indexOf("ultrix") != -1) ||
                  (loc_usragt.indexOf("alphastation") != -1));

    this.sinix = (loc_usragt.indexOf("sinix") != -1);

    this.freebsd = (loc_usragt.indexOf("freebsd") != -1);

    this.bsd = (loc_usragt.indexOf("bsd") != -1);

    this.unix  = ((loc_usragt.indexOf("x11") != -1) ||
                   this.sun ||
                   this.irix ||
                   this.hpux ||
                   this.sco ||
                   this.unixware ||
                   this.mpras ||
                   this.reliant ||
                   this.dec ||
                   this.sinix ||
                   this.aix ||
                   this.linux ||
                   this.bsd ||
                   this.freebsd);

// Digital/Compaq VMS

    this.vms   = ((loc_usragt.indexOf("vax")!=-1) || (loc_usragt.indexOf("openvms")!=-1));
}

//=================================================================================================

function fncFesGetUrlParameters()
//
// Function to split URL CGI style parameters into an associative array (key/value pairs)
//
// Arguments
//
//  None
//
{
    var loc_str = window.top.location.search.substr(1);

    if (loc_str.length > 0)
    {
        var loc_params_array = loc_str.split("&");

        for (var loc_ind1 in loc_params_array)
        {
            loc_params_array[loc_ind1] = loc_params_array[loc_ind1].split("=");

        }

    }

    else
    {
        var loc_params_array = new Array;

    }

    return loc_params_array;

}

//=================================================================================================

function fncFesGetWindowHeight()
//
// Function to calculate the window height from diversely implemented Javascript
// used for vertically positioning/sizing tables
//
// Arguments
//
//  None
//


{
    if (typeof(window.innerHeight) == 'number') // Standard browesrs
    {
        return window.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) // Non Quirks IE6
    {
        return document.documentElement.clientHeight;
    }
    else // Other IE modes
    {
        return document.body.clientHeight;
    }

}

//=================================================================================================

function fncFesGetWindowWidth()
//
// Function to calculate the window height from diversely implemented Javascript
// used for vertically positioning/sizing tables
//
// Arguments
//
//  None
//

{
    if (typeof(window.innerWidth) == 'number') // Standard browesrs
    {
        return window.innerWidth;
    }
    else if (document.documentElement && document.documentElement.clientWidth) // Non Quirks IE6
    {
        return document.documentElement.clientWidth;
    }
    else // Other IE modes
    {
        return document.body.clientWidth;
    }

}

//=================================================================================================

function fncFesGetDocumentWidth()
//
// Function to calculate the document height from diversely implemented Javascript
// used for horizontally positioning/sizing elements
//
// Arguments
//
//  None
//

{


    if (typeof(window.innerWidth) == 'number') // Standard browesrs
    {
        return window.innerWidth;
    }
    else if (document.documentElement && document.documentElement.clientWidth) // Non Quirks IE6
    {
        return document.documentElement.clientWidth;
    }
    else // Other IE modes
    {
        return document.body.clientWidth;
    }

}

//=================================================================================================

function fncFesGetDocumentHeight()
//
// Function to calculate the document height from diversely implemented Javascript
// used for vertically positioning/sizing tables
//
// Arguments
//
//  None
//
{
// TODO Fine Tune
//Browser	window.innerHeight	document.body.clientHeight	document.documentElement.clientHeight
//Opera 9.5+ strict	window	document	window
//Opera 9.5+ quirks	window	window	document
//Opera 7-9.2	window	window	document
//Opera 6	window	window	N/A
//Mozilla strict	window	document	window
//Mozilla quirks	window	window	document
//KHTML	window	document	document
//Safari	window	document	document
//iCab 3	window	document	document
//iCab 2	window	window	N/A
//IE 6+ strict	N/A	document	window
//IE 5-7 quirks	N/A	window	0
//IE 4	N/A	window	N/A
//ICEbrowser	window	window	document
//Tkhtml Hv3	window	window	document
//Netscape 4	window	N/A	N/A

    if (document.compatMode && document.compatMode == 'BackCompat') // Quirks mode in operation
    {
        return document.documentElement.clientHeight;

    }
    else // Assume compliant strict mode browser
    {
        return document.body.clientHeight;

    }

}

//=================================================================================================

function fncFesGetVerticalScroll()
//
// Function to calculate the window height from diversely implemented Javascript
// used for vertically positioning/sizing tables
//
// Arguments
//
//  None
//


{
    if (typeof(window.pageYOffset) == 'number')
    {
        return window.pageYOffset;

    }
    else if (document.body && document.body.scrollTop )
    {
        return document.body.scrollTop;

    }
    else if (document.documentElement && document.documentElement.scrollTop )
    {
        return document.documentElement.scrollTop;

    }
    else
    {
        return 0;

    }

}

//=================================================================================================
//
// Functions for image mouseover effects
//
//=================================================================================================


// pub_fes_mo_dir       - relative directory location of mouseover images
// pub_fes_mo_options   - associative array used to store image mouseover option information (e.g.
//                        button images)
// pub_fes_mo_preloaded - boolean to indicate whether all mouseover images are loaded into the
//                        image mouseover options array

var pub_fes_mo_dir  = '';
var pub_fes_mo_options = new Array();
var pub_fes_mo_preloaded = false;

// Preload images

// Parameters:

//      prm_id = name of image tag
//      prm_img = name of GIF to be associated
//      prm_status = text for the status line
//      prm_top = 1 for top level page, 0 for other

//=================================================================================================

function fncFesMoPreLoad(prm_id,prm_img,prm_status)
//
// Function to preload images for mouseover effects
//
// Arguments
//
//  prm_id          string used to uniquely identify mouseover option in the array
//  prm_img         image name
//  prm_status      message to be displayed in window status bar when mouse is moved over image
//
{

    if(!document.images)
    {
        return false;

    }

    else
    {
        pub_fes_mo_options[prm_id] = new fncFesMoCreateOptionArrayElement(prm_id,prm_img,prm_status);
        return true;

    }

}

//=================================================================================================

function fncFesMoCreateOptionArrayElement(prm_id,prm_img,prm_status)
//
// Function to create new image mouseover option array element and load image button objects
// accordingly
//
// Arguments
//
//  prm_id          string used to uniquely identify mouseover option in the array
//  prm_img         image name
//  prm_status      message to be displayed in window status bar when mouse is moved over image
//
{
    this.Id = prm_id;
    this.Status = prm_status;
    this.ImgOff = new Image;
    this.ImgOn = new Image;

// Split image file into name and file extension

    loc_image_name = pub_fes_mo_dir + prm_img;
    loc_file_ext = loc_image_name.substr(loc_image_name.lastIndexOf("."));
    loc_file_name = loc_image_name.substr(0,loc_image_name.lastIndexOf("."));

// Set up properties for image without mouseover and image with mouseover

    this.ImgOff.src = loc_file_name + loc_file_ext;
    this.ImgOn.src = loc_file_name + '_on' + loc_file_ext;

}

//=================================================================================================

function fncFesMoChangeState(prm_action, prm_id, prm_imgswap)
//
// Function to create perform image swapping for mouseover and mouseout events
//
// Arguments
//
//  prm_action      1 - mouseover, 0 - mouseout
//  prm_id          string used to uniquely identify menu option
//  prm_imgswap     1 - swap image, 0 - don't swap image (just alter window status text)
//
{

    if (document.images && pub_fes_mo_preloaded==true)
    {
        if (prm_action)
        {
            if (prm_imgswap)
            {
                document[prm_id].src = pub_fes_mo_options[prm_id].ImgOn.src;

            }

            window.status = pub_fes_mo_options[prm_id].Status;

        }

        else
        {
            if (prm_imgswap)
            {
                document[prm_id].src = pub_fes_mo_options[prm_id].ImgOff.src;

            }

            window.status = '';

        }

    }

    return true;

}

//=================================================================================================
//
// Functions for window manipulation
//
//=================================================================================================

function fncFesOpenWindow(prm_page_name,
                          prm_target_name,
                          prm_window_width,
                          prm_window_height,
                          prm_xoffset,
                          prm_yoffset,
                          prm_scrollbars,
                          prm_toolbar,
                          prm_location,
                          prm_directories,
                          prm_status,
                          prm_menubar,
                          prm_resizeable)
//
// Function to open a URL in a new window. User can specify height, width and position of window
//
// Arguments
//
//  prm_page_name       URL to be opened in new window
//  prm_target_name     name of new window
//  prm_window_width    window width in pixels
//  prm_window_height   window height in pixels
//  prm_xoffset         horizontal offset position in pixels that window will be displayed at
//                      (measured from centre)
//  prm_yoffset         vertical offset position in pixels that window will be displayed at
//                      (measured from centre)
//  prm_scrollbars      1 - scrollbars displayed, 0 - no scrollbars displayed
//  prm_toolbar         1 - toolbar displayed, 0 - no toolbar displayed
//  prm_location        1 - location displayed, 0 - no location displayed
//  prm_directories     1 - directories displayed, 0 - no directories displayed
//  prm_status          1 - status line displayed, 0 - no status line displayed
//  prm_menubar         1 - menubar displayed, 0 - no menubar displayed
//  prm_resizeable      1 - resizeable, 0 - not resizeable
//
{
    var loc_xpos = ((screen.width - prm_window_width) / 2) + prm_xoffset;
    var loc_ypos = ((screen.height - prm_window_height) / 2) + prm_yoffset;

// Get browser type

    if (fes_environment.ns4)
    {
        loc_win_features = "toolbar=" + prm_toolbar + ",location=" + prm_location + ",directories=" + prm_directories + ",status=" + prm_status + ",menubar=" + prm_menubar + ",scrollbars=" + prm_scrollbars +",resizable=" + prm_resizeable + ",screenX=" + loc_xpos + ",screenY=" + loc_ypos + ",width=" + prm_window_width + ",height=" + prm_window_height;
    }
    else
    {
        loc_win_features = "toolbar=" + prm_toolbar + ",location=" + prm_location + ",directories=" + prm_directories + ",status=" + prm_status + ",menubar=" + prm_menubar + ",scrollbars=" + prm_scrollbars +",resizable=" + prm_resizeable + ",left=" + loc_xpos + ",top=" + loc_ypos + ",width=" + prm_window_width + ",height=" + prm_window_height;
    }

    loc_win = window.open(prm_page_name,prm_target_name,loc_win_features);

    if (fes_environment.ns)
    {
        loc_win.focus();

    }

    return true;

}

//=================================================================================================
//
// Functions for window manipulation
//
//=================================================================================================

function fncFesOpenProductWindow(prm_image_object,
                                 prm_page_name,
                                 prm_target_name,
                                 prm_window_width,
                                 prm_window_height,
                                 prm_xoffset,
                                 prm_yoffset,
                                 prm_scrollbars,
                                 prm_toolbar,
                                 prm_location,
                                 prm_directories,
                                 prm_status,
                                 prm_menubar,
                                 prm_resizeable)
//
// Function to open a Product Image URL in a new window.
//
// Arguments
//
//  prm_image_object    Image to use, attributes such as index may be added to the specified URL
//  other Arguments passed to fncFesOpenWindow
//
{
    var loc_page_name = prm_page_name;

    if (prm_image_object.fes_alt_image)
    {
        loc_page_name += (loc_page_name.indexOf("?") < 0) ? "?" : "&";
        loc_page_name += "fes_alt_image=" + prm_image_object.fes_alt_image;

    }

    return fncFesOpenWindow(loc_page_name,
                            prm_target_name,
                            prm_window_width,
                            prm_window_height,
                            prm_xoffset,
                            prm_yoffset,
                            prm_scrollbars,
                            prm_toolbar,
                            prm_location,
                            prm_directories,
                            prm_status,
                            prm_menubar,
                            prm_resizeable)

}

//=================================================================================================

function fncFesResizeWindow(prm_window_width,
                            prm_window_height)

// Function to dynamically resize the browser window
//
// Parameters:
//
//      prm_height = height of window
//      prm_width = width of window

{

    if (screen.width < prm_window_width)
    {
        prm_window_width = screen.width;
    }

    if (screen.height < prm_window_height)
    {
        prm_window_height = screen.height;
    }

    window.resizeTo(prm_window_width,prm_window_height);

}

//=================================================================================================

function fncFesCheckResizeWindow(prm_window_width,
                                 prm_window_height,
                                 prm_new_window_width,
                                 prm_new_window_height)

// Function to dynamically resize the browser window
//
// Parameters:
//
//      prm_window_height = height of window
//      prm_window_width = width of window
//      prm_new_window_height = height of new window (allows for difference between window.open
//                              window size and window.resizeto window size)
//      prm_new_window_width = width of new window (allows for difference between window.open
//                              window size and window.resizeto window size)

{
    if (!fes_environment.ns4)
    {
        if (fes_environment.ie)
        {
            if (document.body.clientWidth != prm_window_width ||
                document.body.clientHeight != prm_window_height)
            {
                fncFesResizeWindow(prm_new_window_width,prm_new_window_height);

            }

        }

        else
        {
            if (window.innerWidth != prm_window_width ||
                window.innerHeight != prm_window_height)
            {
                fncFesResizeWindow(prm_new_window_width,prm_new_window_height);

            }

        }

    }

}

//=================================================================================================
//
// Functions for Layer/Menu manipulation
//
//=================================================================================================

var pub_fes_active_layername;   // placeholder for the name of the active layer/menu to fade out when a new menu is activated // TODO make this an array for handling nested visible menus
var pub_fes_layer_linger_timer; // global timer object for implementing a persistence delay for menus
var pub_fes_layer_fade_timer;   // global timer object for fading out layers/menus
var pub_fes_layer_slide_timer;  // global timer object for sliding layers/menus

//=================================================================================================

// Harness function
//
// Parameters:
//
//      prm_layername = name of layer/menu
//      prm_opacity   = optional opacity setting

function fncFesShowLayer(prm_layername,prm_opacity)
{
    fncFesToggleLayer(prm_layername,(typeof(prm_opacity) == 'undefined') ? 100 : prm_opacity);

}

//=================================================================================================

// Harness function
//
// Parameters:
//
//      prm_layername = name of layer/menu

function fncFesHideLayer(prm_layername)
{
    fncFesToggleLayer(prm_layername,"hidden");

}

//=================================================================================================

// Function to fade and move a layer/menu into position
//
// Parameters:
//
//      prm_layername = name of layer/menu
//      prm_state     = 'hidden' or opacity setting


function fncFesToggleLayer(prm_layername,prm_state)
{
    var loc_old_layername = pub_fes_active_layername;

    pub_fes_active_layername = prm_layername;

    if (prm_state == 'hidden')
    {
//        pub_fes_layer_linger_timer = setTimeout('fncFesFadeLayer("' + prm_layername + '",0); fncFesSlideLayer("' + prm_layername + '",0)',500);
        pub_fes_layer_linger_timer = setTimeout('fncFesSlideLayer("' + prm_layername + '",0)',2000);
    }

    else
    {
        clearTimeout(pub_fes_layer_linger_timer);

        if (loc_old_layername && (loc_old_layername != pub_fes_active_layername))
        {
//           fncFesFadeLayer(loc_old_layername,0);
//           fncFesSlideLayer(loc_old_layername,0);
        }

        if (!document.getElementById(prm_layername)) return;

        menu = (document.getElementById) ? document.getElementById(prm_layername) : menu = document.all[prm_layername];

//        fncFesFadeLayer(pub_fes_active_layername,prm_state);
        fncFesSlideLayer(pub_fes_active_layername,((typeof(menu.fes_movement) == 'undefined') ? 100 : menu.fes_movement));

    }

}


//=================================================================================================

// Function to fade a layer/menu
//
// Parameters:
//
//      prm_layername      = name of layer/menu
//      prm_opacity_target = new opacity setting
//      prm_time           = time in milliseconds to perform the fade // TODO not yet implemented

function fncFesFadeLayer(prm_layername,prm_opacity_target,prm_time)
{
    var menu;

    if (!document.getElementById(prm_layername)) return;

    menu = (document.getElementById) ? document.getElementById(prm_layername) : menu = document.all[prm_layername];

    if (typeof(prm_opacity_target) != 'undefined') menu.fes_opacity_target = prm_opacity_target;

    if (!menu.fes_visibility || menu.fes_visibility == "hidden")
    {
        menu.style.visibility = 'visible';
        menu.fes_visibility = 'visible';
        if (typeof(menu.fes_opacity) == 'undefined') menu.fes_opacity = 0;

    }
    else if (menu.fes_opacity === 0)
    {
        menu.style.visibility = 'hidden';
        menu.fes_visibility = 'hidden';

    }

    if (menu.style.MozOpacity)   menu.style.MozOpacity = menu.fes_opacity/100;
    if (menu.style.KhtmlOpacity) menu.style.KhtmlOpacity = menu.fes_opacity/100;
    if (menu.filters)            menu.filters.alpha.opacity = menu.fes_opacity;
    menu.style.opacity = menu.fes_opacity/100;

    if (menu.fes_opacity < menu.fes_opacity_target)
    {
        menu.fes_opacity += Math.min(5,menu.fes_opacity_target - menu.fes_opacity);
        pub_fes_layer_fade_timer  = setTimeout('fncFesFadeLayer("' + prm_layername + '")',5);

    }

    else if (menu.fes_opacity > menu.fes_opacity_target)
    {
        menu.fes_opacity -= Math.min(5,menu.fes_opacity - menu.fes_opacity_target);
        pub_fes_layer_fade_timer  = setTimeout('fncFesFadeLayer("' + prm_layername + '")',5);

    }

}

//=================================================================================================

// Function to fade a layer/menu
//
// Parameters:
//
//      prm_layername               = name of layer/menu
//      prm_vertical_slide_target   = new target setting // TODO partial values not yet implemented only 0 or 100
//      prm_horizontal_slide_target = new target setting // TODO partial values not yet implemented only 0 or 100
//      prm_time                    = time in milliseconds to perform the fade // TODO not yet implemented


function fncFesSlideLayer(prm_layername,prm_vertical_slide_target,prm_horizontal_slide_target,$prm_time)
{
    if (!document.getElementById(prm_layername)) return;

    var menu = (document.getElementById) ? document.getElementById(prm_layername) : document.all[prm_layername];

    if (typeof(menu.fes_vertical_slide_home) == 'undefined') // initialise the base/origin settings
    {
        menu.fes_vertical_slide_home = menu.offsetTop;
        menu.fes_vertical_position = menu.offsetTop;
        menu.fes_horizontal_slide_home = menu.offsetLeft;
        menu.fes_horizontal_position = menu.offsetLeft;

    }

    if (typeof(prm_vertical_slide_target) == 'undefined')
    {
//        menu.fes_vertical_slide_target = menu.fes_vertical_slide_home;
    }
    else
    {
        if (prm_vertical_slide_target > 0) // TODO impleemnt partial slide, currently anything other than 100 is assumed to be 0
        {
            menu.fes_vertical_slide_target = menu.fes_vertical_slide_home + (menu.offsetHeight * prm_vertical_slide_target / 100);
        }
        else if (prm_vertical_slide_target < 0) // TODO impleemnt partial slide, currently anything other than 100 is assumed to be 0
        {
            menu.fes_vertical_slide_target = menu.fes_vertical_slide_home - (menu.offsetHeight * prm_vertical_slide_target / 100);
        }
        else
        {
            menu.fes_vertical_slide_target = menu.fes_vertical_slide_home;

        }

    }


/*
    if (typeof(prm_horizontal_slide_target) == 'undefined')
    {
        menu.fes_horizontal_slide_target = menu.fes_horizontal_slide_home;
    }
    else
    {
        if (prm_horizontal_slide_target == 100) // TODO impleemnt partial slide, currently anything other than 100 is assumed to be 0
        {
            menu.fes_horizontal_slide_target = menu.fes_horizontal_slide_home + menu.offsetWidth;
        }
        else if (prm_horizontal_slide_target == -100) // TODO impleemnt partial slide, currently anything other than 100 is assumed to be 0
        {
            menu.fes_horizontal_slide_target = menu.fes_horizontal_slide_home - menu.offsetWidth;
        }
        else
        {
            menu.fes_horizontal_slide_target = menu.fes_horizontal_slide_home;

        }

    }
*/

    menu.style.top  = menu.fes_vertical_position + 'px';
/*
    menu.style.left = menu.fes_horizontal_position + 'px';
*/

    if ((typeof(menu.fes_movement) == 'undefined') || menu.fes_movement > 0)
    {
        menu.style.clip = 'rect(' + (menu.offsetHeight - Math.abs(menu.fes_vertical_slide_home - menu.fes_vertical_position)) + 'px, ' + menu.offsetWidth + 'px, ' + menu.offsetHeight + 'px, 0px)';

    }
    else
    {
        menu.style.clip = 'rect(0px, ' + menu.offsetWidth + 'px, ' + Math.abs(menu.fes_vertical_slide_home - menu.fes_vertical_position) + 'px, 0px)';

    }

/*
    if (menu.fes_vertical_position != menu.fes_vertical_slide_target ||
        menu.fes_horizontal_position != menu.fes_horizontal_slide_target)
*/
    if (menu.fes_vertical_position != menu.fes_vertical_slide_target)
    {
        pub_fes_layer_slide_timer  = setTimeout('fncFesSlideLayer("' + prm_layername + '")',2);

    }

    if (menu.fes_vertical_position < menu.fes_vertical_slide_target)
    {
        menu.fes_vertical_position += Math.min(10,menu.fes_vertical_slide_target - menu.fes_vertical_position);

    }
    else if (menu.fes_vertical_position > menu.fes_vertical_slide_target)
    {
        menu.fes_vertical_position -= Math.min(10,menu.fes_vertical_position - menu.fes_vertical_slide_target);

    }

/*
    if (menu.fes_horizontal_position < menu.fes_horizontal_slide_target)
    {
        menu.fes_horizontal_position += Math.min(10,menu.fes_horizontal_slide_target - menu.fes_horizontal_position);

    }
    else if (menu.fes_horizontal_position > menu.fes_horizontal_slide_target)
    {
        menu.fes_horizontal_position -= Math.min(10,menu.fes_horizontal_position - menu.fes_horizontal_slide_target);

    }
*/

}

//=================================================================================================
//
// DOM Event handlers
//
//=================================================================================================

function fncFesOnMouseWheel(event)
{
    var loc_delta = 0;

    if (!event) event = window.event;

    if (event.wheelDelta)
    {
        loc_delta = event.wheelDelta/120;
        // if (window.opera) loc_delta = -loc_delta; // Opera mmmm... don't think so

    }
    else if (event.detail)
    {
        loc_delta = -event.detail/3; // Mozilla

    }

    if (loc_delta) fncFesOnMouseWheelAction(loc_delta); // Note this needs defining within page
    if (event.preventDefault) event.preventDefault();

    event.returnValue = false;

}

//=================================================================================================
//
// Object fesSlideShow (+Functions) for Slideshow
//
//=================================================================================================

function fesSlideShow(parameters)
{
    this.img_id = parameters.img_id; // DOM id of the image that will present the slideshow, used as reference key

    this.interval = 0; // duration/persistence of image between fades in milliseconds, 0 [the default] will deactivate slideshow
    this.duration = 4; // duration/speed of fade TODO only implemented in IE at the moment
    this.images_array = new Array(); // container array of images to iterate through
    this.image_index = 0; // current iteration pointer
    this.timeout_timer; // reference to the timer object
    this.slideshow_images_preloaded = 0; // flag
    this.random = 0; // flag
    this.clone_active = 0; // flip-flop flag to indicate which canvas is currently displayed

    if (parameters.duration) this.duration = parameters.duration;
    if (parameters.interval) this.interval = parameters.interval;
    if (parameters.random)   this.random = parameters.random;

    if (typeof(parameters.img_url_array) === 'object') this.fncLoadSlideShowImages(parameters.img_url_array);

    if (typeof window.fes_slideshows === 'undefined')
    {
        window.fes_slideshows = new Object(); // Create global container object anchored to the window object to hold references to slideshow objects so that the Settimer functions (which runs with window context) can locate them, scrappy but effective

    }

    window.fes_slideshows[this.img_id] = this; // Add a reference to this object keyed on the image ID it will reference

    this.timer_command = 'window.fes_slideshows["' + this.img_id + '"].fncSlideShowRun()';

    if (this.interval) this.fncSlideShowRun();
}

//
//=================================================================================================
//

fesSlideShow.prototype.fncLoadSlideShowImages = function(prm_image_array)
{
    for (loc_index = 0; loc_index < prm_image_array.length; loc_index++)
    {
        this.images_array[loc_index] = new Image();
        this.images_array[loc_index].src = prm_image_array[loc_index];

    }

    this.slideshow_images_preloaded = true;

}

//
//=================================================================================================
//

fesSlideShow.prototype.fncSetRandomImage = function(prm_exclusion)
{
    this.image_index = Math.floor(Math.random() * this.images_array.length);

// quick cludge for exclusions, TODO proper implementation for an array of excluded choices
    if (this.image_index == prm_exclusion) this.image_index = Math.floor(Math.random() * this.images_array.length);
    if (this.image_index == prm_exclusion) this.image_index = Math.floor(Math.random() * this.images_array.length);
    if (this.image_index == prm_exclusion) this.image_index = Math.floor(Math.random() * this.images_array.length);

}

//
//=================================================================================================
//

fesSlideShow.prototype.fncSetNextImage = function(prm_exclusion)
{
    this.image_index++;

    if (this.image_index > (this.images_array.length - 1)) this.image_index = 0;

}

//
//=================================================================================================
//

fesSlideShow.prototype.fncSlideShowRun = function(prm_interval)
//
// Function to run slideshow of images
//
// Arguments
//

{
    if (prm_interval) this.interval = prm_interval;

    clearTimeout(this.timeout_timer);

    if (this.slideshow_images_preloaded)
    {
        var loc_slideshow_image = document.getElementById(this.img_id);
        var loc_slideshow_clone = document.getElementById(this.img_id + "_clone"); // used as the alternate canvas for painting fading images

        if (loc_slideshow_image &&
            loc_slideshow_clone &&
            loc_slideshow_image.style.visibility === "visible" &&
            loc_slideshow_clone.style.visibility === "visible") // we are recalled to perform the fade between canvases
        {
            if (this.clone_active) // fading in image fading out clone
            {
                loc_slideshow_image.fes_opacity += 5;
                loc_slideshow_clone.fes_opacity -= 5;

            }
            else // fading in the clone
            {
                loc_slideshow_image.fes_opacity -= 5;
                loc_slideshow_clone.fes_opacity += 5;

            }

            if (loc_slideshow_image.style.MozOpacity)   loc_slideshow_image.style.MozOpacity      = loc_slideshow_image.fes_opacity/100;
            if (loc_slideshow_image.style.KhtmlOpacity) loc_slideshow_image.style.KhtmlOpacity    = loc_slideshow_image.fes_opacity/100;
            if (loc_slideshow_image.filters)            loc_slideshow_image.filters.alpha.opacity = loc_slideshow_image.fes_opacity;
            loc_slideshow_image.style.opacity = loc_slideshow_image.fes_opacity/100;

            if (loc_slideshow_clone.style.MozOpacity)   loc_slideshow_clone.style.MozOpacity      = loc_slideshow_clone.fes_opacity/100;
            if (loc_slideshow_clone.style.KhtmlOpacity) loc_slideshow_clone.style.KhtmlOpacity    = loc_slideshow_clone.fes_opacity/100;
            if (loc_slideshow_clone.filters)            loc_slideshow_clone.filters.alpha.opacity = loc_slideshow_clone.fes_opacity;
            loc_slideshow_clone.style.opacity = loc_slideshow_clone.fes_opacity/100;

            if (loc_slideshow_image.fes_opacity === 0)
            {
                loc_slideshow_image.style.visibility = "hidden"; // used to flag inactive canvas as well as making the DOM clear
                this.clone_active = true;

            }
            else if (loc_slideshow_clone.fes_opacity === 0)
            {
                loc_slideshow_clone.style.visibility = "hidden";
                this.clone_active = false;

            }

            if (loc_slideshow_image.fes_opacity === 0 || loc_slideshow_clone.fes_opacity === 0) // fully faded so wake up on next image
            {
                if (this.interval) this.timeout_timer = setTimeout(this.timer_command, this.interval);

            }
            else // still fading call again
            {
                this.timeout_timer = setTimeout(this.timer_command, 10);

            }

        }
        else // we are recalled to start rolling the next image
        {
            if (typeof(document.images[this.img_id].filters) == 'undefined') // no IE filtering so do it the hard way
            {
                if (!loc_slideshow_clone) // need a copy of the image as an alternate location
                {
                    loc_slideshow_image.style.visibility = "visible";
                    loc_slideshow_image.fes_opacity = 100;
                    loc_slideshow_clone = loc_slideshow_image.cloneNode(false);
                    loc_slideshow_clone.id = loc_slideshow_image.id + "_clone";
                    loc_slideshow_clone.style.visibility = "hidden";
                    loc_slideshow_clone.fes_opacity = 0;
                    if (loc_slideshow_clone.style.MozOpacity)   loc_slideshow_clone.style.MozOpacity = loc_slideshow_clone.fes_opacity/100;
                    if (loc_slideshow_clone.style.KhtmlOpacity) loc_slideshow_clone.style.KhtmlOpacity = loc_slideshow_clone.fes_opacity/100;
                    if (loc_slideshow_clone.filters)            loc_slideshow_clone.filters.alpha.opacity = loc_slideshow_clone.fes_opacity;
                    loc_slideshow_clone.style.opacity = loc_slideshow_clone.fes_opacity/100;
                    loc_slideshow_clone.style.position = "absolute";
                    loc_slideshow_clone.style.left = fncFesGetAbsolutePosition(loc_slideshow_image).left + "px";
                    loc_slideshow_clone.style.top = fncFesGetAbsolutePosition(loc_slideshow_image).top + "px";
                    loc_slideshow_image.parentNode.appendChild(loc_slideshow_clone);

                    this.timeout_timer = setTimeout(this.timer_command, this.interval);

                }
                else
                {
                    if (fncFesGetAbsolutePosition(loc_slideshow_image).left !== fncFesGetAbsolutePosition(loc_slideshow_clone).left || // have we moved via resize
                        fncFesGetAbsolutePosition(loc_slideshow_image).top !== fncFesGetAbsolutePosition(loc_slideshow_clone).top)
                    {
                        loc_slideshow_clone.style.left = fncFesGetAbsolutePosition(loc_slideshow_image).left + "px";
                        loc_slideshow_clone.style.top = fncFesGetAbsolutePosition(loc_slideshow_image).top + "px";

                    }

                    if (loc_slideshow_clone.style.visibility === "hidden")
                    {
                        loc_slideshow_clone.src = this.images_array[this.image_index].src;
                        loc_slideshow_clone.style.visibility = "visible";

                        this.timeout_timer = setTimeout(this.timer_command, 10);

                    }
                    else
                    {
                        loc_slideshow_image.src = this.images_array[this.image_index].src;
                        loc_slideshow_image.style.visibility = "visible";

                        this.timeout_timer = setTimeout(this.timer_command, 10);

                    }

                    if (this.random)
                    {
                        this.fncSetRandomImage(this.image_index);

                    }
                    else
                    {
                        this.fncSetNextImage(this.image_index);

                    }

                }

            }
            else
            {
                if (!document.images[this.img_id].style.filter)
                {
                    document.images[this.img_id].style.filter="blendTrans(duration=this.duration)";

                }
                else
                {
                    document.images[this.img_id].filters.blendTrans.Apply();
                    document.images[this.img_id].src = this.images_array[this.image_index].src;
                    document.images[this.img_id].filters.blendTrans.Play();

                    if (this.random)
                    {
                        this.fncSetRandomImage(this.image_index);

                    }
                    else
                    {
                        this.fncSetNextImage(this.image_index);

                    }

               }

               if (this.interval) this.timeout_timer = setTimeout(this.timer_command, this.interval);

            }

        }

    }
    else
    {
        this.timeout_timer = setTimeout(this.timer_command, 100);

    }

}

//
//=================================================================================================
//

function fesSlideShowController(parameters)
{
    this.ref_id = parameters.ref_id;

    this.interval = 0;
    this.slideshow_id_array = new Array();
    this.slideshow_index = 0;
    this.timeout_timer;

    if (parameters.interval) this.interval = parameters.interval;

    if (typeof(parameters.slideshow_id_array) == 'object') this.slideshow_id_array = parameters.slideshow_id_array;

    if (typeof window.fes_slideshow_controllers === 'undefined')
    {
        window.fes_slideshow_controllers = new Object(); // Create global container object anchored to the window object to hold references to slideshow objects so that the Settimer functions (which runs with window context) can locate them, scrappy but effective

    }

    window.fes_slideshow_controllers[this.ref_id] = this; // Add a reference to this object keyed on the image ID it will reference

    this.timer_command = 'window.fes_slideshow_controllers["' + this.ref_id + '"].fncSlideShowRun()';

    if (this.interval) this.fncSlideShowRun();

}


//
//=================================================================================================
//

fesSlideShowController.prototype.fncSlideShowRun = function(prm_interval)
//
// Function to run and control a series of related slideshows
//
// Arguments
//
// prm_interval - sets the interval in milliseconds for the controller's actions

{
    if (prm_interval) this.interval = prm_interval;

    if (window.fes_slideshows[this.slideshow_id_array[this.slideshow_index]]) window.fes_slideshows[this.slideshow_id_array[this.slideshow_index]] .fncSlideShowRun();

    this.slideshow_index++;

    if (this.slideshow_index > (this.slideshow_id_array.length - 1))
    {
        this.slideshow_index = 0;

    }

    this.timeout_timer = setTimeout(this.timer_command, this.interval);

}

//=================================================================================================
//
// Miscellaneous functions
//
//=================================================================================================

function fncFesGetAbsolutePosition(prm_element)
{

    var loc_element = prm_element;
    var loc_left = 0;
    var loc_top = 0;

    while (loc_element !== null)
    {
        loc_left += loc_element.offsetLeft;
        loc_top += loc_element.offsetTop;
        loc_element = loc_element.offsetParent;
    }

//    loc_left += loc_element.offsetLeft;
//    loc_top += loc_element.offsetTop;

    return {left:loc_left, top:loc_top};

}

//=================================================================================================

function fncFesDelayedPageSubmit(prm_interval,
                                 prm_action_or_post,
                                 prm_form)
//                               prm_cgi_vars
//
// Function to submit page/form after a delay
//
// Arguments
//
//  prm_interval            Number of seconds before page/form submission
//  prm_action_or_post      Variable to indicate whether CGI variables to be updated as form
//                          variables or added to the form's action field as URL parameters. If
//                          this parameter is empty then the CGI variables are updated as form
//                          variables otherwise this value is taken as the form action script and
//                          the CGI variables appended to it.
//  prm_form                Name of form to submit
//  prm_cgi_vars            Remaining variables are CGI variable key/value pairs
//

{

    if (prm_interval == 0)
    {

// Timer has expired

        loc_index = 3;

        if (prm_action_or_post == "")
        {

// Set document form paramater values

            while (loc_index < arguments.length)
            {
                document.forms[prm_form].elements[arguments[loc_index]].value = arguments[loc_index + 1];

                loc_index = loc_index + 2;

            }

        }

        else
        {
            loc_form_action = "";

            while (loc_index < arguments.length)
            {
                loc_separator = (loc_form_action == "") ? "?" : "&";

                loc_form_action += loc_separator + arguments[loc_index]+ "=" + arguments[loc_index + 1];

                loc_index = loc_index + 2;

            }

            document.forms[prm_form].action = prm_action_or_post + loc_form_action;

        }

// Submit form/page

        document.forms[prm_form].submit();

        return false;

    }

    else
    {

// Unload argument array back in to se of function parameters

        loc_args = "";

        for (loc_index = 3; loc_index < arguments.length; loc_index++)
        {
            loc_args += ',\'' + arguments[loc_index] +'\'';

        }

// Set timer for specified interval and recall function with no time interval when it expires

        setTimeout('fncFesDelayedPageSubmit(0,\'' + prm_action_or_post + '\',\'' + prm_form + '\'' + loc_args + ')',prm_interval);

    }

}

//=================================================================================================

function fncFesSelectFormElementText(prm_form_name,
                                     prm_element_name)
//
// Function to highlight all text in a specific form element (usually a textarea)
//
// Arguments
//
//  prm_form_name       name of form
//  prm_element_name    name of element in form
//
{
    document.forms[prm_form_name].elements[prm_element_name].focus();
    document.forms[prm_form_name].elements[prm_element_name].select();
    loc_range=document.forms[prm_form_name].elements[prm_element_name].createTextRange();
    loc_range.execCommand('Copy');

// Included as may work better on some browsers than the above - needs testing
//    if(window.clipboardData)
//    {
//        var loc_selected_text=clipboardData.setData('Text',document.forms[prm_form_name].elements[prm_element_name].value); return true;
//    }
//
//    else
//    {
//        return false;
//
//    }

}

//=================================================================================================

function fncFesReDirCountdown(prm_secs,
                              prm_form_switch,
                              prm_location_or_form,
                              prm_display_countdown,
                              prm_redir_name)
//
// Function to redirect page after a specific time
//
// Arguments
//
//  prm_secs                Number of seconds before redirect
//  prm_form                Switch to indicate whether to submit a form or do a location redirect,
//                          1 - submit a form, 0 - location redirect
//  prm_location_or_form    Location to redirect to or form to submit
//  prm_display_countdown   1 - display countdown message in status bar, 0 - don't display message
//  prm_redir_name          Name to be displayed by redirect message
//

{
    prm_secs = prm_secs - 1;

    if (prm_secs <= 0)
    {
        if (prm_form_switch)
        {
            document.forms[prm_location_or_form].submit();

        }

        else
        {
            window.location.replace(prm_location_or_form);

        }

    }

    else
    {
        if (prm_display_countdown)
        {
            window.status = 'Redirecting to ' + prm_redir_name + ' in ' + prm_secs + ' seconds';

        }

        setTimeout('fncFesReDirCountdown(' + prm_secs + ',' + prm_form_switch + ',\"' + prm_location_or_form + '\",' + prm_display_countdown + ',\"' + prm_redir_name + '\")',1000);

    }

}

//=================================================================================================

function fncFesPrintPage()
//
// Function to print current page
//
// Arguments
//
//  None
//
{

    if (window.print)
    {
        window.print();
    }

    else
    {
        var loc_web_browser = '<OBJECT ID="WebBrowser1" WIDTH=0 HEIGHT=0 CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>';
        document.body.insertAdjacentHTML('beforeEnd', loc_web_browser);
        WebBrowser1.ExecWB(6, 2); //Use a 1 vs. a 2 for a prompting dialog box    WebBrowser1.outerHTML = "";

    }

}

//=================================================================================================

function fncFesRandomNumber(prm_start,
                            prm_end)
//
// Function to generate random number between two integer values
//
// Arguments
//
//  prm_start           First number
//  prm_end             Last number
//
{

    return prm_start + Math.floor(Math.random() * (prm_end - prm_start + 1));

}

//=================================================================================================

function fncFesGoToURLFromSelect (prm_form,
                                  prm_field)
//
// Function to load URL from selected dropdown index value on HTML form
//
// Arguments
//
//  prm_form            Form object
//  prm_field           Name of dropdown element (<SELECT> field)
//

{
    var loc_index = prm_form.elements[prm_field].selectedIndex;

    if(loc_index != "")
    {
        window.location.href=prm_form.elements[prm_field].options[loc_index].value;

    }

}

//=================================================================================================

function fncFesToggleCheckboxes (prm_form,
                                 prm_prefix)
//
// Function to toggle/invert all checkboxes within a form
//
// Arguments
//
//  prm_form            Form object
//  prm_prefix          Optional name prefix to restrict which boxes are processed
//

{
    prm_prefix = prm_prefix || "";

    for (var loc_index = 0; loc_index < prm_form.elements.length; loc_index++)
    {
        if (prm_form.elements[loc_index].type == "checkbox")
        {
            if (prm_form.elements[loc_index].name.substr(0,prm_prefix.length) == prm_prefix)
           {
                fncFesToggleCheckbox(prm_form.elements[loc_index]);
            }

        }

    }

}

//=================================================================================================

function fncFesToggleCheckbox (prm_checkbox)
//
// Function to toggle/invert a specific checkbox object
//
// Arguments
//
//  prm_checkbox        Checkbox object
//

{
    prm_checkbox.checked = prm_checkbox.checked ^ true;
}

//=================================================================================================

function fncFesCheckboxesChecked (prm_form,
                                  prm_prefix)
//
// Function to validate that at least one checkbox from a series within a form
// has been selected
//
// Arguments
//
//  prm_form            Form object
//  prm_prefix          Optional name prefix to restrict which boxes are processed
//

{
    prm_prefix = prm_prefix || "";

    for (var loc_index = 0; loc_index < prm_form.elements.length; loc_index++)
    {
        if (prm_form.elements[loc_index].type == "checkbox")
        {
            if (prm_form.elements[loc_index].name.substr(0,prm_prefix.length) == prm_prefix)
            {
                if (prm_form.elements[loc_index].checked)
                {
                    return true;

                }

            }

        }

    }

    return false; // no matching checkboxes were found
}

//=================================================================================================

function fncFesConfirmCheckboxes (prm_form,
                                  prm_prefix,
                                  prm_message,
                                  prm_limit)
//
// Function to confirm
// has been selected
//
// Arguments
//
//  prm_form            Form object
//  prm_prefix          Optional name prefix to restrict which boxes are processed
//

{
    prm_prefix  = prm_prefix  || "";
    prm_limit   = prm_limit   || 1;
    prm_message = prm_message || "Confirm selection of";

    var loc_counter= 0;

    for (var loc_index = 0; loc_index < prm_form.elements.length; loc_index++)
    {
        if (prm_form.elements[loc_index].type == "checkbox")
        {
            if (prm_form.elements[loc_index].name.substr(0,prm_prefix.length) == prm_prefix)
            {
                if (prm_form.elements[loc_index].checked)
                {
                    loc_counter++;

                }

            }

        }

    }

    if (loc_counter > prm_limit)
    {
        return confirm(prm_message + " " + loc_counter + " items","XX");

    }

    return true;

}

//=================================================================================================

var pub_contextmenu_message="";

//=================================================================================================

function fncFesHandleContextMenuForImages(prm_event)
//
// Function to disable right mouse click context menu for images only
//
// Arguments
//
//  prm_event - in this instance equates to mouse key pressed
//

{

// The script pops up an alert box with a 'message' or if no message is passed just returns
// without any action

// Internet Explorer 4 - test for mouse button press

    if (fes_environment.ie4)
    {
        if (event.button == 2 || event.button == 3)
        {
            if (event.srcElement.tagName == "IMG")
            {
                if (pub_contextmenu_message != "")
                {
                    alert(pub_contextmenu_message);

                }

                return false;

            }

        }

    }

// Internet Explorer 5 upwards

    else if (fes_environment.ie5up)
    {
        if (event.srcElement.tagName == "IMG")
        {
            if (pub_contextmenu_message != "")
            {
                alert(pub_contextmenu_message);

            }

            return false;

        }

    }

// Netscape 4 - test for mouse button press

    else if (fes_environment.ns4)
    {
        if (prm_event.which == 3)
        {
            if (pub_contextmenu_message != "")
            {
                alert(pub_contextmenu_message);

            }

            return false;

        }

    }

// Netscape 6

    else if (fes_environment.ns6up)
    {
        if (prm_event.target.tagName == "IMG")
        {
            if (pub_contextmenu_message != "")
            {
                alert(pub_contextmenu_message);

            }

            return false;

        }

    }

// Opera 6 upwards - not currently functional due to bug in Opera apparently

    else if (fes_environment.opera6up)
    {
        if (prm_event.which == 3 && prm_event.target.tagName == "IMG")
        {
            if (pub_contextmenu_message != "")
            {
                alert(pub_contextmenu_message);

            }

            return false;

        }

    }

}

//=================================================================================================

function fncFesAssociateImages()

//
// Function to associate mousedown event on images with context menu handler - used for Netscape
// 4 only.
//
// Arguments
//
//  None
//

{
    for(loc_counter = 0; loc_counter < document.images.length; loc_counter++)
    {
       document.images[loc_counter].onmousedown = fncFesHandleContextMenuForImages;

    }

}

//=================================================================================================

function fncFesDisableContextMenuForImages()

//
// Function to invoke the disabling of the right mouse click context menu for images only
//
// Arguments
//
//  None
//

{
    if (fes_environment.ie4)
    {
        document.onmousedown = fncFesHandleContextMenuForImages;

    }

    else if (fes_environment.ie5up)
    {
        document.oncontextmenu = fncFesHandleContextMenuForImages;

    }

    else if (fes_environment.ns6up)
    {
        document.oncontextmenu = fncFesHandleContextMenuForImages;

    }

    else if (fes_environment.opera6up)
    {
        document.onmouseup = fncFesHandleContextMenuForImages;

    }

    else if (fes_environment.ns4)
    {
        fncFesAssociateImages();

    }

}

//=================================================================================================

function fncFesDisableCopyText()

//
// Function to disable the copying of text via select and copy on an HTML page
//
// Arguments
//
//  None
//

{

// Note that there is currently a cludge in here for Safari - need to test when we can afford a Mac

    if ((fes_environment.ie4up ||
         fes_environment.opera6up) &&
         !fes_environment.safari)
    {
        document.onselectstart=new Function ("return false");

    }

    else if (fes_environment.ns6up &&
            !fes_environment.safari)
    {
        document.onmousedown=new Function ("return false");
        document.onclick=new Function ("return true");

    }

}

//=================================================================================================

function fncFesDefaultSubmit(prm_event,
                             prm_form,
                             prm_action,
                             prm_directive)

//
// Function to parse keypresses for a form and submit the form if the enter key is pressed
// negating the need to have a submit button. Normally invoked via an 'onkeypress' action
// in the form definition
//
// Arguments
//
//  prm_event           The keypress event passed via the form
//  prm_form            Form object
//  prm_action          Optional action string to be placed in the fes-action field
//  prm_directive       Optional action string to be placed in the fes-action field
//

{
    var loc_key = (prm_event && prm_event.which) ? prm_event.which : prm_event.keyCode;

    if (loc_key == 13) // Enter key pressed
    {
        if (prm_action)    prm_form.fes_action.value    = prm_action;
        if (prm_directive) prm_form.fes_directive.value = prm_directive;

        prm_form.submit();

        return false;

    }

    return true;

}

//=================================================================================================

function fncFesLimitTextarea(prm_textarea,
                             prm_limit,
                             prm_message)

//
// Function to limit daat entry into a textarea, normally called from onkeyup
//
// Arguments
//
//  prm_textarea        The field to be tested
//  prm_limit           The maximum number of characters
//  prm_message         Optional message for a popup box
//

{
    if (prm_textarea.value.length > prm_limit)
    {
        field.value = field.value.substring(0, prm_limit);

        if (prm_message) alert(prm_message);

    }

}

//=================================================================================================

function fncFesResetMail(prm_anchor_id,
                         prm_obscured_address,
                         prm_obscured_text)
{
//
// Function to unobscure email addresses enbedded in the html
//
// Arguments
//
//  prm_anchor_id           The ID of the anchor tag containg the dummy mailto: href
//  prm_obscured_address    The email in obscured form
//  prm_obscured_text       Optional textual represenation of the e-mail address in obscured form
//
    var loc_mask = 'mail';
    var loc_mail = '';
    var loc_text = '';

    for (var counter = 0; counter < prm_obscured_address.length; counter++)
        loc_mail += String.fromCharCode(prm_obscured_address.charCodeAt(counter) ^ (loc_mask.charCodeAt(counter % loc_mask.length) & 7));

    if (document.getElementById(prm_anchor_id)) document.getElementById(prm_anchor_id).href = 'mailto:' + loc_mail;

    if (prm_obscured_text)
    {
        for (var counter = 0; counter < prm_obscured_text.length; counter++)
             loc_text += String.fromCharCode(prm_obscured_text.charCodeAt(counter) ^ (loc_mask.charCodeAt(counter % loc_mask.length) & 7));
    }
    else
    {
        loc_text = loc_mail;
    }

    if (document.getElementById(prm_anchor_id)) document.getElementById(prm_anchor_id).innerHTML = loc_text;

}

//=================================================================================================

function debugDump(prm_message,prm_tag)
{
    loc_tag = (prm_tag) ? prm_tag + ' ' : '';

    if (typeof window.opera != "undefined") opera.postError(loc_tag + prm_message);

}

//=================================================================================================

// Set up environment object

    var fes_environment = new fncFesGetEnvironment();

//-->
