/*
    SchoolFinder v1.0 - SchoolFinder Main JavaScript Controller
      - Copyright (c) 1995-2008 EDge Interactive. All rights reserved. <www.edgeip.com>
      - Script Author
            - Robert J. Secord, B.Sc. <Robert.Secord@edgeip.com>
      - Dependancies:
            - Mootools v1.2 or later.  <www.mootools.net>
      - Tested Browsers:
            - Windows: IE 6, IE 7, Firefox 2+, Opera 9+, Netscape 8+, Google Chrome 0.4
*/

var SchoolFinder = new Class(
{
    Implements: [Events, Options],

    // -------------------------------------------------------------------------------------------------------------
    // Member Variables
    options:
    {
        // Required Settings:
        BasePath:       '',
        GraphicsPath:   '',
        UseSpecialFX:   true,
        IsMainPage:     false,
        RightSideGMaps: false,
        Cookie:
        {
            domain:   '',
            path:     '/',
            duration: 14
        },

        // Optional Events:
        onPageLoad:  $empty,
        onPageReady: $empty,
        onPageUnload:  $empty,

        // Optional Developer Use:
        DebugMode: false
    },

    // -------------------------------------------------------------------------------------------------------------
    // Class Constructor (options = JSON Object)
    initialize: function( options )
    {
        this.setOptions( options );

        // Check for Required Settings for Object Instantiation
        if( this.options.GraphicsPath.length < 1 ) return this.ErrorAlert('Object Construction Failed - Invalid GraphicsPath Supplied!');

        // Google Maps Vars
        this.oMap = null;
        this.oGeoCoder = null;
        this.oMapCenter = null;

        // Drop Menu State Vars
        this.bDropMenuIsOpen = false;
        this.bDropMenuHover = false;
        this.bInTransition = false;

        // Attach Window Events
        window.addEvents(
        {
            'load':     this.OnLoad.bind(this),
            'unload':   this.OnUnload.bind(this),
            'domready': this.OnDomReady.bind(this)
        });
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: DOM Ready Event (before OnLoad)
    OnDomReady: function()
    {
        // Initialize Cookies
        this.oCookies = new Hash.Cookie('SchoolFinderCookie', this.options.Cookie);

        this.LinkHeaderImage();
        this.InitDropMenu();
        this.UpdateDisplayToggle();
        this.UpdateCookiedDisplayToggle();
        this.MainPage_InitAjax();
        this.MiniTabs_InitAjax( 2 );
        this.FavLinksSchool_InitAjax();
        this.FavLinksProgram_InitAjax();
        this.FavLinksCareer_InitAjax();
        this.FavLinksScholarship_InitAjax();

        if( Browser.Engine.trident )
            document.addEvent('click', this.OnWindowClick.bind(this));
        else
            window.addEvent('click', this.OnWindowClick.bind(this));

        // Fire Page Ready Event
        this.fireEvent('pageReady', this, 0);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Page Loaded Event
    OnLoad: function()
    {
        // Load Google Maps
        if( this.options.RightSideGMaps !== false ) this.LoadGoogleMaps();

        // Fire Page Loaded Event
        this.fireEvent('pageLoad', this, 0);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Page Unloaded Event
    OnUnload: function()
    {
        // Unload Google Maps API
        if( this.options.RightSideGMaps !== false ) this.UnloadGoogleMaps();

        // Fire Page Loaded Event
        this.fireEvent('pageUnload', this, 0);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Event: Window Clicked
    OnWindowClick: function( oEvent )
    {
        // DropMenu Not Visible; let click event continue
        if( !this.bDropMenuIsOpen || this.bInTransition ) return;

        // Get Mouse and DropMenu Coordinates
        var iMouseX = oEvent.client.x + window.getScrollLeft(),
            iMouseY = oEvent.client.y + window.getScrollTop(),
            oSize = this.oSubTabsDropMenuDiv2.getSize(),
            oPos = this.oSubTabsDropMenuDiv2.getPosition();

        // Hide Drop-Down Div if Mouse was Clicked outside of Div Bounds
        if( iMouseX < oPos.x || iMouseX > oPos.x + oSize.x || iMouseY < oPos.y || iMouseY > oPos.y + oSize.y )
        {
            // Hide DropMenu
            this.HideDropMenu();
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Link Header Image to Landing Page
    LinkHeaderImage: function()
    {
        var oHeaderImage = $('Page-ExDiv1');
        if( oHeaderImage ) oHeaderImage.addEvent('click', function(){location.href = this.options.BasePath + 'index.asp';}.bind(this));
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Initialize Drop Menu
    InitDropMenu: function()
    {
        this.oSubTabsDropMenuLink = $('SubTabsDropMenuLink');
        this.oSubTabsDropMenuDiv1 = $('SubTabsDropMenuDiv1');
        this.oSubTabsDropMenuDiv2 = $('SubTabsDropMenuDiv2');
        if( !this.oSubTabsDropMenuLink || !this.oSubTabsDropMenuDiv1 || !this.oSubTabsDropMenuDiv2 ) return;

        this.oSubTabsDropMenuLink.addEvents(
        {
            //'click': this.ShowDropMenu.bind(this),
            'mouseenter': function() { this.bDropMenuHover = true; this.ShowDropMenu.delay(100, this); }.bind(this),
            'mouseleave': function() { this.bDropMenuHover = false; this.HideDropMenu.delay(1000, this); }.bind(this)
        });

        this.oSubTabsDropMenuDiv2.addEvents(
        {
            'mouseenter': function() { this.bDropMenuHover = true; }.bind(this),
            'mouseleave': function() { this.bDropMenuHover = false; this.HideDropMenu.delay(1000, this); }.bind(this)
        });
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Show Drop Menu
    ShowDropMenu: function()
    {
        if( this.bInTransition || !this.bDropMenuHover || this.bDropMenuIsOpen ) return;

        // Transitions in Effect
        this.bInTransition = true;

        // Set Initial State
        this.oSubTabsDropMenuDiv1.setStyles({'visibility': 'visible', 'width': 30, 'height': 30, 'opacity': 0.0});
        this.oSubTabsDropMenuDiv2.setStyles({'visibility': 'visible', 'width': 20, 'height': 20, 'opacity': 0.0});

        // Display Drop-Down with Effects
        new Fx.Morph(this.oSubTabsDropMenuDiv1, {duration: 500, wait: false})
            .start(
            {
                'width':   (Browser.Engine.trident)?430:420,
                'height':  140,
                'opacity': 0.25
            });
        new Fx.Morph(this.oSubTabsDropMenuDiv2, {duration: 500, wait: false})
            .start(
            {
                'width':   (Browser.Engine.trident)?410:400,
                'height':  125,
                'opacity': 1.0
            })
            .chain(function()
            {
                // Transitions Completed
                this.bInTransition = false;

                // Drop-Down Visible
                this.bDropMenuIsOpen = true;
            }.bind(this));
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Hide Drop Menu
    HideDropMenu: function()
    {
        if( this.bInTransition || this.bDropMenuHover ) return;

        // Transitions in Effect
        this.bInTransition = true;

        // Display Drop-Down with Effects
        new Fx.Morph(this.oSubTabsDropMenuDiv1, {duration: 500, wait: false})
            .start(
            {
                'width':   30,
                'height':  30,
                'opacity': 0.0
            });
        new Fx.Morph(this.oSubTabsDropMenuDiv2, {duration: 500, wait: false})
            .start(
            {
                'width':   20,
                'height':  20,
                'opacity': 0.0
            })
            .chain(function()
            {
                // Transitions Completed
                this.bInTransition = false;

                // Drop-Down Visible
                this.bDropMenuIsOpen = false;

                // Set Final State
                this.oSubTabsDropMenuDiv1.setStyles({'visibility': 'hidden'});
                this.oSubTabsDropMenuDiv2.setStyles({'visibility': 'hidden'});
            }.bind(this));
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Updates Display Toggle for Hidden Elements
    UpdateDisplayToggle: function()
    {
        $$('.MinusLink').each(function( oLink )
        {
            this.ToggleDisplay( oLink.get('id').replace('ToggleLink', '').toInt() );
        }, this);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Display Toggle for Hidden Elements
    ToggleDisplay: function( iLinkID )
    {
        var oBlock = $('ToggleBlock' + iLinkID), oLink = $('ToggleLink' + iLinkID);
        if( !oBlock || !oLink ) return;

        if( oLink.hasClass('MinusLink') )
        {
            oBlock.setStyle('display', 'none');
            oLink.removeClass('MinusLink').addClass('PlusLink');
        }
        else
        {
            oBlock.setStyle('display', 'block');
            oLink.removeClass('PlusLink').addClass('MinusLink');
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Updates Cookied-Display Toggle for Hidden Elements
    UpdateCookiedDisplayToggle: function()
    {
        $$('.MinusLinkCookied').each(function( oLink )
        {
            this.ToggleCookiedDisplay( oLink.get('id'), true );
        }, this);

        this.oCookies.each(function( szCookieValue, szCookieKey )
        {
            if( szCookieValue == 'Open' ) this.ToggleCookiedDisplay( szCookieKey );
        }, this);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Cookied-Display Toggle for Hidden Elements
    ToggleCookiedDisplay: function( szLinkID, bInitial )
    {
        var oBlock = $(szLinkID + '_Content'), oLink = $(szLinkID);
        if( !oBlock || !oLink ) return;

        if( oLink.hasClass('MinusLinkCookied') )
        {
            oBlock.setStyle('display', 'none');
            oLink.removeClass('MinusLinkCookied').addClass('PlusLinkCookied');
            if( !bInitial ) this.oCookies.set(szLinkID, 'Closed');
        }
        else
        {
            oBlock.setStyle('display', 'block');
            oLink.removeClass('PlusLinkCookied').addClass('MinusLinkCookied');
            if( !bInitial ) this.oCookies.set(szLinkID, 'Open');
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    MainPage_InitAjax: function()
    {
        if( !this.options.IsMainPage ) return;

        // MainMenu Links
        this.oMainMenuLink1 = $('MainMenu_StudyType1');
        if( this.oMainMenuLink1 )
        {
            this.oMainMenuLink1.set('href', 'javascript:void(0)');
            this.oMainMenuLink1.addEvent('click', function(){ this.MainPage_AjaxRequest({'StudyType': 1}); }.bind(this));
        }

        this.oMainMenuLink2 = $('MainMenu_StudyType2');
        if( this.oMainMenuLink2 )
        {
            this.oMainMenuLink2.set('href', 'javascript:void(0)');
            this.oMainMenuLink2.addEvent('click', function(){ this.MainPage_AjaxRequest({'StudyType': 2}); }.bind(this));
        }

        this.oMainMenuLink3 = $('MainMenu_StudyType3');
        if( this.oMainMenuLink3 )
        {
            this.oMainMenuLink3.set('href', 'javascript:void(0)');
            this.oMainMenuLink3.addEvent('click', function(){ this.MainPage_AjaxRequest({'StudyType': 3}); }.bind(this));
        }

        this.oMainMenuLink4 = $('MainMenu_StudyType4');
        if( this.oMainMenuLink4 )
        {
            this.oMainMenuLink4.set('href', 'javascript:void(0)');
            this.oMainMenuLink4.addEvent('click', function(){ this.MainPage_AjaxRequest({'StudyType': 4}); }.bind(this));
        }

        this.oMainMenuLink5 = $('MainMenu_StudyType5');
        if( this.oMainMenuLink5 )
        {
            this.oMainMenuLink5.set('href', 'javascript:void(0)');
            this.oMainMenuLink5.addEvent('click', function(){ this.MainPage_AjaxRequest({'StudyType': 5}); }.bind(this));
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    MainPage_AjaxRequest: function( oParameters )
    {
        // Get Update Element
        var oUpdateEl = $('Ajax_ContentUpdate');
        if( !oUpdateEl ) return this.ErrorAlert('AjaxRequest Failed!\nUpdate Element Not Found!');

        var oAjaxResponse = new Request.HTML(
        {
            url: this.options.BasePath + 'ajax/mainpage.asp',
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                // Reset Active Tabs
                this.oMainMenuLink1.removeClass('Active');
                this.oMainMenuLink2.removeClass('Active');
                this.oMainMenuLink3.removeClass('Active');
                this.oMainMenuLink4.removeClass('Active');
                this.oMainMenuLink5.removeClass('Active');

                if( oParameters.StudyType == 1 ) this.oMainMenuLink1.addClass('Active');
                if( oParameters.StudyType == 2 ) this.oMainMenuLink2.addClass('Active');
                if( oParameters.StudyType == 3 ) this.oMainMenuLink3.addClass('Active');
                if( oParameters.StudyType == 4 ) this.oMainMenuLink4.addClass('Active');
                if( oParameters.StudyType == 5 ) this.oMainMenuLink5.addClass('Active');

                // Update HTML Element
                oUpdateEl.set('html', rHTML);

                // Rebuild MiniTabs Links
                this.MiniTabs_InitAjax( oParameters.StudyType );
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    MiniTabs_InitAjax: function( iStudyType )
    {
        if( !this.options.IsMainPage ) return;

        // MiniTabs Links
        this.oMiniTabs_Featured = $('MiniTabs_Featured');
        if( this.oMiniTabs_Featured )
        {
            this.oMiniTabs_Featured.set('href', 'javascript:void(0)');
            this.oMiniTabs_Featured.addEvent('click', function(){ this.MiniTabs_AjaxRequest({'StudyType': iStudyType, 'View': 'Featured'}); }.bind(this));
        }

        this.oMiniTabs_Events = $('MiniTabs_Events');
        if( this.oMiniTabs_Events )
        {
            this.oMiniTabs_Events.set('href', 'javascript:void(0)');
            this.oMiniTabs_Events.addEvent('click', function(){ this.MiniTabs_AjaxRequest({'StudyType': iStudyType, 'View': 'Events'}); }.bind(this));
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    MiniTabs_AjaxRequest: function( oParameters )
    {
        // Get Update Element
        var oUpdateEl = $('Ajax_MiniTabsUpdate');
        if( !oUpdateEl ) return this.ErrorAlert('AjaxRequest Failed!\nUpdate Element Not Found!');

        var oAjaxResponse = new Request.HTML(
        {
            url: this.options.BasePath + 'ajax/minitabs.asp',
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                // Reset Active Tabs
                if( this.oMiniTabs_Featured ) this.oMiniTabs_Featured.removeClass('Active');
                if( this.oMiniTabs_Events ) this.oMiniTabs_Events.removeClass('Active');

                if( oParameters.View == 'Featured' && this.oMiniTabs_Featured ) this.oMiniTabs_Featured.addClass('Active');
                if( oParameters.View == 'Events' && this.oMiniTabs_Events ) this.oMiniTabs_Events.addClass('Active');

                // Update HTML Element
                oUpdateEl.set('html', rHTML);
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksSchool_InitAjax: function()
    {
        if( !this.oFavLinksLoadingIcon )
            this.oFavLinksLoadingIcon = new Element('div', {'class': 'LoadingIcon', 'styles': {'width': 'auto'}});

        var aAddFavLinks = document.getElements('.AddFavSchool');
        if( aAddFavLinks && aAddFavLinks.length )
        {
            aAddFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksSchool_AddFunction.bindWithEvent(this));
            }, this);
        }

        var aRemFavLinks = document.getElements('.RemoveFavSchool');
        if( aRemFavLinks && aRemFavLinks.length )
        {
            aRemFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksSchool_RemFunction.bindWithEvent(this));
            }, this);
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksSchool_AjaxRequest: function( oTarget, oParameters )
    {
        var oAjaxResponse = new Request.HTML(
        {
            url: this.options.BasePath + 'ajax/school_fav.asp',
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                if( oParameters.Cmd == 'Add' )
                {
                    // Update Link Text/Title
                    oTarget.set({'html': '<img src="../graphics/favourite.gif" />', 'title': 'Remove from My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksSchool_RemFunction.bindWithEvent(this));
                }
                else
                {
                    // Update Link Text/Title
                    oTarget.set({'html': 'save', 'title': 'Save to My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksSchool_AddFunction.bindWithEvent(this));
                }
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksSchool_AddFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksSchool_AjaxRequest(oTarget, {'Cmd': 'Add', 'SchoolCode': aParameters[1].trim(), 'ProfileType': aParameters[2].trim(), 'ProfileID': aParameters[3].trim()});
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksSchool_RemFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksSchool_AjaxRequest(oTarget, {'Cmd': 'Rem', 'SchoolCode': aParameters[1].trim(), 'ProfileType': aParameters[2].trim(), 'ProfileID': aParameters[3].trim()});
    },






    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksProgram_InitAjax: function()
    {
        if( !this.oFavLinksLoadingIcon )
            this.oFavLinksLoadingIcon = new Element('div', {'class': 'LoadingIcon', 'styles': {'width': 'auto'}});

        var aAddFavLinks = document.getElements('.AddFavProgram');
        if( aAddFavLinks && aAddFavLinks.length )
        {
            aAddFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksProgram_AddFunction.bindWithEvent(this));
            }, this);
        }

        var aRemFavLinks = document.getElements('.RemoveFavProgram');
        if( aRemFavLinks && aRemFavLinks.length )
        {
            aRemFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksProgram_RemFunction.bindWithEvent(this));
            }, this);
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksProgram_AjaxRequest: function( oTarget, oParameters )
    {
        var oAjaxResponse = new Request.HTML(
        {
            url: this.options.BasePath + 'ajax/program_fav.asp',
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                if( oParameters.Cmd == 'Add' )
                {
                    // Update Link Text/Title
                    oTarget.set({'html': '<img src="../graphics/favourite.gif" />', 'title': 'Remove from My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksProgram_RemFunction.bindWithEvent(this));
                }
                else
                {
                    // Update Link Text/Title
                    oTarget.set({'html': 'save', 'title': 'Save to My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksProgram_AddFunction.bindWithEvent(this));
                }
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksProgram_AddFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksProgram_AjaxRequest(oTarget, {'Cmd': 'Add', 'ProgramID': aParameters[1].trim()});
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksProgram_RemFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksProgram_AjaxRequest(oTarget, {'Cmd': 'Rem', 'ProgramID': aParameters[1].trim()});
    },







    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksCareer_InitAjax: function()
    {
        if( !this.oFavLinksLoadingIcon )
            this.oFavLinksLoadingIcon = new Element('div', {'class': 'LoadingIcon', 'styles': {'width': 'auto'}});

        var aAddFavLinks = document.getElements('.AddFavCareer');
        if( aAddFavLinks && aAddFavLinks.length )
        {
            aAddFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksCareer_AddFunction.bindWithEvent(this));
            }, this);
        }

        var aRemFavLinks = document.getElements('.RemoveFavCareer');
        if( aRemFavLinks && aRemFavLinks.length )
        {
            aRemFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksCareer_RemFunction.bindWithEvent(this));
            }, this);
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksCareer_AjaxRequest: function( oTarget, oParameters )
    {
        var oAjaxResponse = new Request.HTML(
        {
            url: this.options.BasePath + 'ajax/career_fav.asp',
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                if( oParameters.Cmd == 'Add' )
                {
                    // Update Link Text/Title
                    oTarget.set({'html': '<img src="../graphics/favourite.gif" />', 'title': 'Remove from My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksCareer_RemFunction.bindWithEvent(this));
                }
                else
                {
                    // Update Link Text/Title
                    oTarget.set({'html': 'save', 'title': 'Save to My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksCareer_AddFunction.bindWithEvent(this));
                }
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksCareer_AddFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksCareer_AjaxRequest(oTarget, {'Cmd': 'Add', 'CareerCode': aParameters[1].trim()});
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksCareer_RemFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksCareer_AjaxRequest(oTarget, {'Cmd': 'Rem', 'CareerCode': aParameters[1].trim()});
    },





    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksScholarship_InitAjax: function()
    {
        if( !this.oFavLinksLoadingIcon )
            this.oFavLinksLoadingIcon = new Element('div', {'class': 'LoadingIcon', 'styles': {'width': 'auto'}});

        var aAddFavLinks = document.getElements('.AddFavScholarship');
        if( aAddFavLinks && aAddFavLinks.length )
        {
            aAddFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksScholarship_AddFunction.bindWithEvent(this));
            }, this);
        }

        var aRemFavLinks = document.getElements('.RemoveFavScholarship');
        if( aRemFavLinks && aRemFavLinks.length )
        {
            aRemFavLinks.each(function( oLink )
            {
                oLink.set('href', 'javascript:void(0)');
                oLink.addEvent('click', this.FavLinksScholarship_RemFunction.bindWithEvent(this));
            }, this);
        }
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksScholarship_AjaxRequest: function( oTarget, oParameters )
    {
        var oAjaxResponse = new Request.HTML(
        {
            url: this.options.BasePath + 'ajax/scholarship_fav.asp',
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                if( oParameters.Cmd == 'Add' )
                {
                    // Update Link Text/Title
                    oTarget.set({'html': '<img src="../graphics/favourite.gif" />', 'title': 'Remove from My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksScholarship_RemFunction.bindWithEvent(this));
                }
                else
                {
                    // Update Link Text/Title
                    oTarget.set({'html': 'save', 'title': 'Save to My Favourites'});

                    // Progress Animation
                    this.oFavLinksLoadingIcon.dispose();
                    oTarget.setStyle('display', '');

                    // Update Link Event
                    oTarget.removeEvents('click');
                    oTarget.addEvent('click', this.FavLinksScholarship_AddFunction.bindWithEvent(this));
                }
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksScholarship_AddFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksScholarship_AjaxRequest(oTarget, {'Cmd': 'Add', 'ScholarshipID': aParameters[1].trim()});
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    FavLinksScholarship_RemFunction: function( oEvent )
    {
        // Get Target and Parameters
        oEvent = new Event( oEvent );
        var oTarget = new Element(oEvent.target);
        if( oTarget.get('tag') == 'img' ) oTarget = oTarget.getParent();
        var aParameters = oTarget.get('id').trim().split('-');

        // Progress Animation
        oTarget.setStyle('display', 'none');
        oTarget.getParent().adopt(this.oFavLinksLoadingIcon);

        // Ajax Request
        this.FavLinksScholarship_AjaxRequest(oTarget, {'Cmd': 'Rem', 'ScholarshipID': aParameters[1].trim()});
    },





    // -------------------------------------------------------------------------------------------------------------
    // Request Info - Ajax Routines:
    // -------------------------------------------------------------------------------------------------------------

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    RequestInfo_AjaxRequest: function( oParameters, bFromStudyLevel )
    {
        var szUrl = (bFromStudyLevel) ? this.options.BasePath + 'ajax/recruitme_programs.asp' : this.options.BasePath + 'ajax/recruitme_country.asp';
        var oAjaxResponse = new Request.HTML(
        {
            url: szUrl,
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                // Remove Loading Icons
                if( bFromStudyLevel )
                {
                    $('AjaxLoading-StudyLevel').removeClass('LoadingIcon');
                }
                else
                {
                    // Remove Loading Icons
                    $('AjaxLoading-Country').removeClass('LoadingIcon');
                    $('AjaxLoading-Province').removeClass('LoadingIcon');
                }

                // Update Content
                var oUpdateDiv = $(this.RequestInfo_UpdateID);
                if( oUpdateDiv ) oUpdateDiv.empty().set('html', rHTML);
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    RequestInfo_LocationChanged: function( oElement, bIsCountry )
    {
        oElement = new Element(oElement);
        var szListID, szSelectElementName, szValue = oElement.get('value').trim();

        // Country Changed
        if( bIsCountry )
        {
            szListID = 'Country';

            // CA and US Countries get a Province Box
            if( szValue == 'US' || szValue == 'CA' )
            {
                szSelectElementName = 'province';
                this.RequestInfo_UpdateID = 'ProvinceList';
                $('ProvinceContainer').setStyle('display', 'block');
                $('CityList').set('html', '<'+'select id="TempCity" style="width:100%;"><'+'option value=""> Please Select a Province First <'+'/option><'+'/select>');
            }
            else
            {
                szSelectElementName = 'city';
                this.RequestInfo_UpdateID = 'CityList';
                $('ProvinceContainer').setStyle('display', 'none');
                $('CityList').set('html', '<'+'select id="TempCity" style="width:100%;"><'+'option value=""> Please Select a Country First <'+'/option><'+'/select>');
            }
        }
        // Province Changed
        else
        {
            szListID = 'Province';
            szSelectElementName = 'city';
            this.RequestInfo_UpdateID = 'CityList';
        }

        // Display Loading Icon
        $('AjaxLoading-' + szListID).addClass('LoadingIcon');

        // Send Ajax Request
        this.RequestInfo_AjaxRequest(
        {
            'List':        szListID,
            'Value':       szValue,
            'ElementName': szSelectElementName
         }, false);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    RequestInfo_StudyLevelChanged: function( oElement, szProfileID )
    {
        oElement = new Element(oElement);

        // Display Loading Icon
        $('AjaxLoading-StudyLevel').addClass('LoadingIcon');

        this.RequestInfo_UpdateID = 'ProgramsList';

        // Send Ajax Request
        this.RequestInfo_AjaxRequest(
        {
            'Value':     oElement.get('value').trim(),
            'ProfileID': szProfileID,
            'Styles':    'width:475px; margin-top:3px;'
        }, true);
    },

    // -------------------------------------------------------------------------------------------------------------
    // Google Maps API Routines:
    // -------------------------------------------------------------------------------------------------------------

    // -------------------------------------------------------------------------------------------------------------
    // External Routine:
    LoadGoogleMaps: function()
    {
        if( !GBrowserIsCompatible() ) return this.ErrorAlert('The Google Maps API is not compatible with your browser.');

        // Default Center Location / Depth
        var oSchoolLocation = {Lat: 43.808734293456276, Lng: -79.3342924118042, Depth: 14};

        // Load Google Maps API with GeoCoder
        this.oMap = new GMap2(document.getElementById("SchoolProfileMap"));
        this.oGeoCoder = new GClientGeocoder();
        this.oMap.setUIToDefault();

        // Build Search Address from School Address
        var szSearchAddress = '';
        if( this.options.RightSideGMaps.Address.length ) szSearchAddress += this.options.RightSideGMaps.Address.trim() + ', ';
        if( this.options.RightSideGMaps.City.length ) szSearchAddress += this.options.RightSideGMaps.City.trim() + ' ';
        if( this.options.RightSideGMaps.Province.length ) szSearchAddress += this.options.RightSideGMaps.Province.trim() + ', ';
        if( this.options.RightSideGMaps.Country.length ) szSearchAddress += this.options.RightSideGMaps.Country.trim() + ' ';
        if( this.options.RightSideGMaps.Postal.length ) szSearchAddress += this.options.RightSideGMaps.Postal.trim();

        // Get Location from School Address (GeoCoder)
        this.oGeoCoder.getLatLng(szSearchAddress, function( oPoint )
        {
            if( !oPoint )
            {
                // Send Alert for School Address Not Found
                this.ErrorAlert('Could not locate School Address! Using Default Location. (' + szSearchAddress + ')');

                // To hide the map block:
                //var oMapsBlock = $('SchoolProfileGoogleMaps');
                //if( oMapsBlock ) oMapsBlock.setStyle('display', 'none');

                // Set Default Center Point for Location
                this.oMapCenter = new GLatLng(oSchoolLocation.Lat, oSchoolLocation.Lng);
                this.oMap.setCenter(this.oMapCenter, 2);

                // Set Marker for School Location
                this.oMap.addOverlay(new GMarker(this.oMapCenter));
            }
            else
            {
                // Set Default Center Point for Location
                this.oMapCenter = oPoint;
                this.oMap.setCenter(this.oMapCenter, oSchoolLocation.Depth);

                // Set Marker for School Location
                this.oMap.addOverlay(new GMarker(this.oMapCenter));
            }
        }.bind(this));
    },

    // -------------------------------------------------------------------------------------------------------------
    // Click-through tracking Routines:
    // -------------------------------------------------------------------------------------------------------------

    // -------------------------------------------------------------------------------------------------------------
    // External Routine:
    ETourTracking: function( oParameters ) // oParameters = {'ProfileID': '[id-here]', 'SchoolCode': '[code-here]'}
    {
        var oAjaxResponse = new Request.HTML(
        {
            url: this.options.BasePath + 'ajax/tracking_etours.asp',
            onSuccess: function(rTree, rElements, rHTML, rJavaScript)
            {
                if( rHTML != 'Success' )
                {
                    console.log('tracking failed');
                }
            }.bind(this)
        }).get(oParameters);
    },

    // -------------------------------------------------------------------------------------------------------------
    // External Routine:
    UnloadGoogleMaps: function()
    {
        GUnload();
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine:
    PagingChange: function( szFormID, iPageCount, iPage )
    {
        var oForm = $(szFormID);
        for( var i = 1; i <= iPageCount; i++ )
            oForm.PageNo.options[i-1].selected = (i == iPage);
        oForm.submit();
    },

    // -------------------------------------------------------------------------------------------------------------
    // Internal Routine: Debug-Mode Error Alerts
    ErrorAlert: function( szErrorMsg )
    {
        // Debug Alert Message
        if( this.options.DebugMode )
            alert('[' + this.ClassName + ' ' + this.ClassVersion + '] -- Developer Error --\n\n' + szErrorMsg);
        return false;
    },

    // -------------------------------------------------------------------------------------------------------------
    // Class Name, Version, Author
    ClassName:    'SchoolFinder',
    ClassVersion: '1.0',
    ClassAuthor:  'Robert J. Secord, B.Sc.'
});
