///////////////////////////////////////////////////////////////////////////////
//	Core
///////////////////////////////////////////////////////////////////////////////

if (typeof core === 'undefined' || !core) {
    var core = {};
    core.debug = false;
    core.flashNavigationEnabled = true;
    core.suckerfishAnimationEnabled = false;
}

core.bootstrap = (function () {
    if (typeof window.console === 'undefined') {
        window.console = {
            'assert': function () { },
            'count': function () { },
            'debug': function () { },
            'dir': function () { },
            'dirxml': function () { },
            'error': function () { },
            'group': function () { },
            'groupCollapsed': function () { },
            'groupEnd': function () { },
            'info': function () { },
            'log': function () { },
            'profile': function () { },
            'profileEnd': function () { },
            'time': function () { },
            'timeEnd': function () { },
            'trace': function () { },
            'warn': function () { }
        };
        window.console.event = function () { };
        window.console.action = function () { };
    } else {
        if (core.debug === true) {
            window.console.event = function (event) {
                window.console.info('The event "' + event.type + '" has been triggered successfully. OBJECT ::: ', event);
            }
            window.console.action = function (action) {
                window.console.info('The action "' + action + '" has been initialized successfully.');
            }
        } else {
            window.console.event = function () { };
            window.console.action = function () { };
        }
    }

    if (typeof window.Class === 'undefined' || !window.Class) {
        window.Class = function () {
            var Class = {},
				EventHandler,
				instances = [];

            EventHandler = $(Class);

            Class.bind = function (type, data, fn) {
                EventHandler.bind(type, data, fn);
            }

            Class.trigger = function (type, data) {
                EventHandler.trigger(type, data);
            }

            return Class;

        }
    }

    return function () {
        throw new Error('Bootstrap has already executed.');
    }

} ());


///////////////////////////////////////////////////////////////////////////////
//	Classes
///////////////////////////////////////////////////////////////////////////////

core.Instantiatable = function () {
    var Instantiatable = new Class(),
		instances = {};

    Instantiatable.instantiate = function (key, instance) {
        instances[key] = instance;
    }

    Instantiatable.uninstantiate = function (key) {
        delete instances[key];
    }

    Instantiatable.getInstance = function (key) {
        if (instances[key] === undefined) {
            throw new Error('An instance with the key of "' + key + '" dose not exist.')
        } else {
            return instances[key];
        }
    }

    return Instantiatable;
}
core.Stateful = function (defaultState) {
    var Stateful = new Class(),
		state = defaultState;

    Stateful.setState = function (s) {
        state = s;
        Stateful.trigger('stateChanged', [state]);
    }

    Stateful.getState = function () {
        return state;
    }

    return Stateful;
}

///////////////////////////////////////////////////////////////////////////////
//	Environment
///////////////////////////////////////////////////////////////////////////////

core.env = {
    'host': function () {
        var url = window.location.href;
        url = core.util.String.explodeURL(url);
        return url;
    },
    'aircraftService': '/fragments/AircraftInfo.svc/',
    'section': null,
    'googleMaps': [{
        'authority': 'hbc',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRSNGG_Hiy7uzoYMpx4VMQBsqx26MhQVFNCLMdxsEcm4cpijgAI9wRmw8Q'
    }, {
        'authority': 'local.hawkerbeechcraft.com',
        'key': 'ABQIAAAA8GF3KjbCnx0gwkEkFz94DxTMMidnUt8-6pZQb_e8l6cL5mCqERTTiKBtpn-ootIp4r0ePjmo4sRTqg'
    }, {
        'authority': 'hawker-qa.cmass.criticalmass.com',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRTa7lWaQOsBGN8tf0HUeJ5jnKWXqhStO_R3KsKl_AtDidNKSG2AnIGR7w'
    }, {
        'authority': 'hawker-dev.cmass.criticalmass.com',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRTdFbDy89Eec-5qvrMTkCvfo1xANhTDRP4FnSksx29rybLSmxshrpKISw'
    }, {
        'authority': 'localhost',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQyHDlY9iv5olMfv18NLgqayJTq5g'
    }, {
        'authority': '63.87.133.205',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRQuQsb56NQSVQP5-LRKBvwxkY7PJhQimkT7HidLwDeepUVjorfrgvOx0w'
    }, {
        'authority': 'hawkerbeechcraftd',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRQ9jfjJIDsMWEQWJ0daURTu6YY6ZRSaylZ74o_SOK2iyYwAeDxQsoywDA'
    }, {
        'authority': 'www.hawkerbeechcraft.com',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRR4lb30wsmrXfUZJuoBq9IdKnnzeBSTeb0D0EwM1-f2F4axX0nhqjVrvw'
    }, {
        'authority': 'hawkerbeechcraft.com',
        'key': 'ABQIAAAAOSRLq57j1arhOsFfFMxqFRROPxt3tNqGaO7OXMWua7eQOPCXoRTsWxD3e9sKGcabjtaRB_KajMEPyQ'
    }]
}

core.env.getLocation = function () {
    if (this.section !== null) {
        return this.section;
    }
    else {
        return this.section = {
            'section': $('body').attr('id'),
            'pages': $('body').attr('class').split(' ')
        }
    }
}

core.env.getQueryParameter = function (key) {
    // Potentially may need to refactor this to cache query params
    var queryString = window.location.href.replace(/(.*)\/((?:[^?])*\/)?([^.\/?]+)(\?+(.*))?/g, '$5').split('&'), params = {};
    for (var i = 0, j = queryString.length; i < j; i = i + 1) {
        var param = queryString[i].split('=');
        if (param[0] === key) {
            return param[1];
        }
    }
}

core.env.getHash = function (key, hash) {

    hash = hash.replace('#', '').split('&');

    for (var i = 0, j = hash.length; i < j; i = i + 1) {
        var param = hash[i].split('=');
        if (param[0] === key) {
            return param[1];
        }

    }
}

///////////////////////////////////////////////////////////////////////////////
//	Language
///////////////////////////////////////////////////////////////////////////////
/**
* The Language Components
* @module lang
* @title Language Components
*/

core.lang = {};

/**
* TODO: Add description
* @author Douglas Crockford
* @namespace core.lang
* @method typeOf
*/

core.lang.typeOf = function (value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length')) && typeof value.splice === 'function') {
                s = 'array';
            } else if (typeof value.test === 'function') {
                s = 'regex'
            }
        } else {
            s = 'null';
        }
    }
    return s;
};


///////////////////////////////////////////////////////////////////////////////
//	Actions
///////////////////////////////////////////////////////////////////////////////
/**
* The Actions Components 
* @module pages
* @title Action Components
*/

core.action = {};
core.action.AbstractAction = function (sections, pages, match) {
    var AbstractAction = {},
		applicableSections = [],
		applicablePages = [],
		i,
		j,
		k,
		l,
		matchAll = true;

    function execute() {
        $(function () {
            AbstractAction.initialize();
        });
    }

    switch (core.lang.typeOf(sections)) {
        case 'string':
            applicableSections.push(sections);
            break;
        case 'array':
            applicableSections = sections;
            break;
        case 'regex':
            if (sections.test(core.env.getLocation()['section'])) {
                applicableSections.push(core.env.getLocation()['section']);
            }
            break;
        default:
            execute();
            return AbstractAction;
            break;
    }

    switch (core.lang.typeOf(pages)) {
        case 'string':
            applicablePages.push(pages);
            break;
        case 'array':
            applicablePages = pages;
            break;
        case 'regex':
            for (var i = 0, j = pages.length; i < j; i = i + 1) {
                if (pages.test(core.env.getLocation()['pages'][i])) {
                    applicablePages.push(core.env.getLocation()['pages'][i]);
                }
            }
            break;
        default:
            break;
    }

    if (sections === false || $.inArray(core.env.getLocation()['section'], applicableSections) !== -1) {
        if (applicablePages.length !== 0) {
            switch (match) {
                case 'all':
                    for (i = 0, j = applicablePages.length; i < j; i = i + 1) {
                        if (matchAll) {
                            matchAll = ($.inArray(applicablePages[i], core.env.getLocation()['pages']) !== -1);
                        }
                    }
                    if (matchAll) {
                        execute();
                    }
                    break;
                default:
                    for (i = 0, j = applicablePages.length; i < j; i = i + 1) {
                        if ($.inArray(applicablePages[i], core.env.getLocation()['pages']) !== -1) {
                            execute();
                            break;
                        }
                    }
                    break;
            }
        } else {
            execute();
        }
    }

    return AbstractAction;

};

core.action.Common = (function () {

    var Common = core.action.AbstractAction(/.*/, /.*/);

    Common.initialize = function () {
        console.action('Common');
        // JavaScript body class helper name thing
        $('html').addClass('js');

        //Flash Detection
        (function () {
            if (swfobject.getFlashPlayerVersion().major < 9) {
                jQuery(document).ready(function ($) {
                    var deviceAgent = navigator.userAgent.toLowerCase();
                    var agentID = deviceAgent.match(/(iphone|ipod|ipad|android|blackberry)/);
                    if (agentID) {

                        // This is an iPad or iPhone, don't disable website
                    }
                    else {
                        var FlashOverlay = new core.ui.Overlay({ 'opacity': .8 });
                        FlashOverlay.show();
                        $('body').append('<div id="get_flash"><p>To view hawkerbeechcraft.com, please update your web browser with the latest version of the <a href="http://www.adobe.com/go/getflashplayer/">Flash player</a>.</p></div>');
                    }
                });
            }
        } ());

        //disable links with "#"
        (function () {
            $('a[href=#]').click(function (event) {
                event.preventDefault();
            });
        } ());

        //Suckerfish dropdown menus
        (function () {
            var Suckerfish,
			VideoPlayer = new core.ui.VideoPlayer({}),
			navigationVideo = {
			    'height': 120,
			    'bufferTime': 1,
			    'debug': false,
			    'controls': {
			        'nav': true
			    }
			};

            if (core.suckerfishAnimationEnabled) {
                Suckerfish = new core.ui.Suckerfish({
                    'list': new core.ui.List({
                        'list': $('#navigation'),
                        'autoSelectDefault': false
                    }),
                    'duration': 200,
                    'easing': 'swing',
                    'delay': 200
                })
            } else {
                Suckerfish = new core.ui.Suckerfish({
                    'list': new core.ui.List({
                        'list': $('#navigation'),
                        'autoSelectDefault': false
                    }),
                    'duration': 0,
                    'easing': 'swing',
                    'delay': 0
                })
            }

            $('#navigation li').each(function (index, item) {
                if ($('h2 > a[href=#]', item).length > 0) {
                    $(item).unbind('click');
                }
            });

            $('#navigation .video').each(function (index, item) {
                new VideoPlayer.VideoPlayerInstance({
                    'target': $(item)
                });
            });

            $('#navigation .video').bind('initialize', function (event) {
                var $this = $(this),
					key,
					VideoPlayerInstance;

                key = $this.attr('id');
                navigationVideo.width = $this.width();
                VideoPlayerInstance = VideoPlayer.getInstance(key);
                navigationVideo.flv = core.env.nav.videosURI + key + '.flv';
                FlashGateway('configuration', VideoPlayerInstance.getId(), navigationVideo);

            });

            Suckerfish.bind('suckerFished', function (event, item, state) {

                if (state === 'expanded') {
                    window.setTimeout(function () {
                        if (item.state.getState() === 'expanded') {

                            var instance = VideoPlayer.getInstance($('.video', item).attr('id')), isEmbeded;

                            isEmbeded = instance.getState();

                            if (!isEmbeded) {
                                if (core.flashNavigationEnabled) {
                                    instance.embed(instance.getId());
                                }
                            }
                        }

                    }, 1000);

                } else if (state === 'contracting') {

                    window.setTimeout(function () {
                        if (item.state.getState() === 'contracting' || item.state.getState() === 'contracted') {

                            var instance = VideoPlayer.getInstance($('.video', item).attr('id')), isEmbeded;

                            isEmbeded = instance.getState();

                            if (isEmbeded) {
                                if (core.flashNavigationEnabled) {
                                    instance.dispose(instance.getId());
                                }
                            }
                        }

                    }, 500);

                }

            });

        } ());

        //Resize
        (function () {
            $(window).bind('resize load', function (event) {
                var $this = $(this);
                window.console.event(event);
                if ($this.width() < 960) {
                    $('html').css({ 'overflowX': 'auto' });
                } else {
                    $('html').css({ 'overflowX': 'hidden' });
                }

            });
        } ());

        //Print link
        (function () {
            $('a[rel="print"]').click(function (event) {
                event.preventDefault();
                window.print();
            });
        })();

        //External
        (function () {
            $('a[rel="external"], a[rel="document"]').click(function (event) {
                event.preventDefault();
                window.open($(this).attr('href'));
                return false;
            });
        })();


        //Section Navigation

        (function () {
            var SectionNavigationList = new core.ui.List({
                'list': $('#section-navigation')
            }),
				$element = $('#section-navigation > .expandable');

            $('#section_navigation > .expandable > a').click(function (event) {
                event.preventDefault();
            });

            $element.each(function (index, item) {
                var $toggle = $('> a > span', $(this)),
				Expandable,
				ExpandableNavigationList;

                Expandable = core.ui.Expandable({ 'toggle': $toggle, 'element': $(this) });
                ExpandableNavigationList = new core.ui.List({ 'list': $('ul', $(item)) });
            });

        })()

    }

    return Common;

} ());

//TEMPLATE ACTIONS
core.action.DetailsCommon = (function () {

    var DetailsCommon = core.action.AbstractAction(/.*/, ['details'], '');

    DetailsCommon.initialize = function () {
        console.action('DetailsCommon');
    };

    return DetailsCommon;

} ());

core.action.DetailsGallery = (function () {

    var DetailsGallery = core.action.AbstractAction(/.*/, ['details', 'gallery'], 'all');

    DetailsGallery.initialize = function () {
        console.action('DetailsGallery');

        var SlidingRangeList,
			Range,
			List,
			Slider,
			ImageLoader,
			HtmlTemplate,
			Slideshow,
			Frames,
			Overlay,
			frame,
			$background = $('#background_image ul.frames');

        Range = new core.ui.Range({});

        List = new core.ui.List({ 'list': $('div.slider > div.bounds > ul'), 'preventDefault': false });

        HtmlTemplate = new core.ui.HtmlTemplate({
            'element': $('#background_image')
        });

        $('body').append(HtmlTemplate.html);

        frame = core.util.String.template($background.html(), {});
        $background.empty();

        List.items.each(function (index, item) {
            var explodedUrl = core.util.String.explodeURL($('> a', item).attr('href'));
            $background.append(core.util.String.template(frame, {
                'id': explodedUrl.fragment,
                'contents': '<img src="' + explodedUrl.path + '.' + explodedUrl.extension + '"/>'
            }));
        });

        Frames = new core.ui.List({ 'list': $background, 'preventDefault': false });

        Slideshow = new core.ui.Slideshow({
            'slides': List,
            'frames': Frames,
            'speed': 500
        });

        Slider = core.ui.Slider({ 'target': List.list });

        SlidingRangeList = core.ui.SlidingRangeList({
            'slider': Slider,
            'range': Range,
            'list': List,
            'controls': {
                'left': new core.ui.Control({ 'element': $('.slider .left a') }),
                'right': new core.ui.Control({ 'element': $('.slider .right a') })
            }
        });

        Overlay = new core.ui.Overlay({
            'height': $(window).height(),
            'width': $(window).width()
        });

        List.bind('itemSelected', function (event, item) {
            $('.downloads', List.list).hide();
            $('.downloads', $(item)).show(250);

            /*
            ImageLoader = core.ui.ImageLoader({'url': $('a', item).attr('href')});
            Overlay.show();
            Overlay.$element.addClass('loading_animation');
            ImageLoader.bind('imageLoaded', function(event, image) {
            Overlay.hide();
            });
            */
        });

        $('.slider .list > li > div > a').click(function (event) {
            event.preventDefault();
        });

        List.items.eq(0).click();

    }

    return DetailsGallery;

} ());
core.action.DetailsInterior = (function () {

    var DetailsInterior = core.action.AbstractAction(/.*/, ['details', 'interior'], 'all');

    DetailsInterior.initialize = function () {
        console.action('DetailsInterior');
        var Slideshow,
			Slides = new core.ui.List({ 'list': $('div.slideshow ul.slides'), 'preventDefault': true });
        Frames = new core.ui.List({ 'list': $('div.slideshow ul.frames') });

        Frames.items.each(function (index, item) {
            var $this = $(this),
				swatch,
				Swatches;

            swatch = $('.swatch', $this);

            Swatches = new core.ui.List({ 'list': $('ul.swatches', $(this)) })

            Swatches.bind('itemSelected', function (event, item, index) {
                swatch.html($('a', item).html());
            });

            Swatches.select(Swatches.items.eq(1));
            Swatches.select(Swatches.items.eq(0));
        });

        Frames.select(Frames.items.eq(1));
        Frames.select(Frames.items.eq(0));

        Slideshow = new core.ui.Slideshow({
            'slides': Slides,
            'frames': Frames,
            'speed': 500
        });

    }


    return DetailsInterior;

} ());
core.action.DetailsOverviewThreeSixty = (function () {

    var DetailsOverview = core.action.AbstractAction(/.*/, ['details', 'overview', 'three_sixty'], 'all');

    DetailsOverview.initialize = function () {
        console.action('DetailsOverview : 360 Test');
        var VideoPlayer = new core.ui.VideoPlayer({}),
			VideoPlayerInstace;

        $('#three_sixty_container').append('<div id="three_sixty" class="video"><div id="three_sixty_embed" class="embed"></div></div>')

        VideoPlayer.VideoPlayerInstance({
            'target': $('#three_sixty')
        });

        $('#three_sixty').bind('initialize', function () {
            var path = window.location + 'assets/video/360.flv';
            FlashGateway('configuration', 'three_sixty_embed', {
                'flv': path,
                'height': 683,
                'width': 1280,
                'bufferTime': 1,
                'autoDispose': false,
                'controls': {
                    'nav': false,
                    'dragControl': true,
                    'muteControl': false,
                    'pausePlayControl': false,
                    'seekbarControl': false,
                    'textControl': {
                        'text': 'SKIP VIDEO',
                        'action': 'skipVideo'
                    },
                    'timeDisplayControl': false,
                    'volumeControl': false,
                    'x': 0,
                    'y': 0
                }
            });
        });

        try {
            VideoPlayerInstance = VideoPlayer.getInstance('three_sixty');
            VideoPlayerInstance.embed();
        }
        catch (err) {
        }

    }

    return DetailsOverview;

} ());
core.action.DetailsExterior = (function () {

    var DetailsExterior = core.action.AbstractAction(/.*/, ['details', 'exterior'], 'all');

    DetailsExterior.initialize = function () {
        console.action('DetailsExterior');
        var colorSchemes,
			ImageLoader,
			HtmlTemplate,
			Overlay,
			$colorscheme = $('ul.colorscheme'),
			frame,
			$background = $('#background_image ul.frames');

        HtmlTemplate = new core.ui.HtmlTemplate({
            'element': $('#background_image')
        });

        $('body').append(HtmlTemplate.html);

        frame = core.util.String.template($background.html(), {});
        $background.empty();

        var stripingThumbsList = new core.ui.List({ 'list': $colorscheme });
        stripingThumbsList.items.each(function (index, item) {
            var explodedUrl = core.util.String.explodeURL($('> a', item).attr('href'));
            $background.append(core.util.String.template(frame, {
                'id': explodedUrl.fragment,
                'contents': '<img src="' + explodedUrl.path + '.' + explodedUrl.extension + '"/>'
            }));
        });

        var stripingSlideShow = new core.ui.Slideshow({
            'slides': stripingThumbsList,
            'frames': new core.ui.List({ 'list': $background }),
            'speed': 500
        });
        stripingThumbsList.select($('li.selected', $colorscheme));

        Overlay = new core.ui.Overlay({
            'height': $(window).height(),
            'width': $(window).width()
        });

        $(" > li a", $colorscheme).click(function (event) {
            event.preventDefault();
        });

    }


    return DetailsExterior;

} ());
core.action.ExperienceDownloads = (function () {

    var ExperienceDownloads = core.action.AbstractAction(/.*/, ['experience', 'downloads'], '');

    ExperienceDownloads.initialize = function () {
        console.action('ExperienceDownloads');
        $('div.slider').each(function (index, item) {

            var $item = $(item),
				SlidingRangeList,
				Range,
				List,
				Slider,
				$list,
				$items;

            $list = $(' > div > ul', $item);
            $items = $(' > li', $list);

            Range = new core.ui.Range({ 'size': 2 });
            List = new core.ui.List({ 'list': $list });
            Slider = core.ui.Slider({ 'target': List.list });


            SlidingRangeList = core.ui.SlidingRangeList({
                'slider': Slider,
                'range': Range,
                'list': List,
                'controls': {
                    'left': new core.ui.Control({
                        'element': $('.left a', $item)
                    }),
                    'right': new core.ui.Control({
                        'element': $('.right a', $item)
                    })
                }
            });

            $('.left a, .right a').click(function (event) {
                event.preventDefault();
            });

            $items.click(function (event) {
                event.preventDefault();
            });

            List.bind('itemSelected', function (event, item) {
                $('.downloads', $item).hide();
                $('.downloads', $(item)).show(250);
            });

            List.select($('li.selected', $list));

            List.bind('itemSelected', function (event, item) {
                $('.downloads', $list).hide();
                $('.downloads', $(item)).show(250);
            });

        });

    }

    return ExperienceDownloads;

} ());

///////////////////////////////////////////////////////////////////////////////
//	User Interface
///////////////////////////////////////////////////////////////////////////////

core.ui = {};
core.ui.Modal = function (settings) {
    var Modal = new Class(),
	defaults = {
	    'id': 'modal_window',
	    'container': $('body'),
	    'speed': 250,
	    'style': 'video'
	},
	$modal;

    settings = $.extend(true, defaults, settings);

    Modal.open = function () {
        $modal = $('<div id="' + settings.id + '" class="' + settings.style + '"></div>');
        $modal.append($('<div id="' + settings.id + '-content"></div>'));
        settings.container.append($modal);
        $modal.eq(0).fadeIn(settings.speed, function () {
            Modal.trigger('opened');
        });

    };

    Modal.close = function () {
        $('#' + settings.id).fadeOut(settings.speed, function () {
            $('#' + settings.id).empty().remove();
            Modal.trigger('closed');
        });
    };

    return Modal;

};

core.ui.Slideshow = function (settings) {
    var Slideshow = new Class(),
		defaults = {
		    'speed': 500,
		    'easing': 'linear'
		},
		Frames,
		Slides;

    settings = $.extend(true, defaults, settings);

    Frames = settings.frames;
    Slides = settings.slides;

    Slides = settings.slides;

    Frames.items.stop(true, true).animate({ 'opacity': 0 }, 0, settings.easing, function () {
        Frames.items.eq(Frames.getIndex()).animate({ 'opacity': 1 }, 0, settings.easing);
    });

    function gotoFrame(nextFrame) {
        var selectedFrame = Frames.items.filter('.selected');
        if (Frames.isSelected(nextFrame) === false) {
            Frames.items.stop(true, true);
            nextFrame.addClass('next').stop(true, true).animate({
                'opacity': 1
            }, 0, settings.easing);
            selectedFrame.stop(true, true).animate({
                'opacity': 0
            }, settings.speed, settings.easing, function () {
                nextFrame.removeClass('next');
                Frames.select(nextFrame);
            });
        }
    }

    Slides.bind('itemSelected', function (event, item, index) {
        var nextFrame = $('#' + core.util.String.explodeURL($('> a', item).attr('href')).fragment);
        gotoFrame(nextFrame);
    });

    Slideshow.gotoFrame = function (frame) {
        gotoFrame(frame);
    }

    return Slideshow;

}

core.ui.Expandable = function (settings) {
    var Expandable = new Class(),
		defaults = {
		    'speed': 500
		},
		startHeight,
		endHeight;

    settings = $.extend(true, defaults, settings);

    startHeight = settings.toggle.height(),
	endHeight = settings.element.height();

    settings.element.height(startHeight).css({
        'overflow': 'hidden'
    });

    settings.toggle.toggle(function (event) {
        event.preventDefault();
        settings.element.animate({ 'height': endHeight }, settings.speed).
			addClass('selected');
        settings.toggle.addClass('expanded');
    },
	function (event) {
	    event.preventDefault();
	    settings.element.animate({ 'height': startHeight }, settings.speed, function () {
	        $(this).removeClass('selected');
	        settings.toggle.removeClass('expanded');
	    });
	})

    if ($('li.selected', settings.element).length > 0) {
        settings.toggle.click();
    }

    return Expandable;

}
core.ui.Slider = function (settings) {
    var Slider = core.Stateful(false),
		defaults = {
		    'speed': 500,
		    'increment': 115
		},
		increment,
		$target;

    settings = $.extend(true, defaults, settings);

    $target = settings.target;
    increment = settings.increment;


    function slide(distance) {
        if (Slider.getState() === false) {
            var left;
            Slider.setState(true);
            Slider.trigger('animationStarted');
            left = parseInt($target.css('left'));
            $target.animate({ 'left': left + distance }, settings.speed, 'swing', function () {
                Slider.setState(false);
                Slider.trigger('animationCompleted');
            });
        }
    }

    Slider.forward = function () {
        return slide(increment * -1);
    }

    Slider.backward = function () {
        return slide(increment);
    }

    Slider.getIncrement = function () {
        return increment;
    }

    Slider.setIncrement = function (i) {
        increment = i;
    }

    Slider.speed = settings.speed;

    return Slider;

}
core.ui.List = function (settings) {
    var List = new Class(),
		defaults = {
		    'selectEvent': 'click',
		    'preventDefault': false,
		    'autoSelectDefault': true
		},
		$items = $('> li', settings.list),
		index = 0,
		defaultSeleced;

    settings = $.extend(true, defaults, settings);

    $list = settings.list;

    function init() {

        if ($items.length > 0) {
            var selected = $('> li.selected', $list);
            if (selected.length > 0) {
                index = $items.index(selected);
            }
        }

        if (settings.autoSelectDefault === true) {
            select($items.eq(index));
        }

        List.trigger('initialize');
        return List;

    }

    function select($item) {
        if ($item.hasClass('selected') === false) {
            $items.removeClass('selected');
            $item.addClass('selected');
            index = $items.index($item);
            List.trigger('itemSelected', [$item, index]);
        }
        return $item;
    }

    $items[settings.selectEvent](function (event) {
        var $this = $(this);
        select($(this));
        if (settings.preventDefault === true) {
            event.preventDefault();
        }
    });

    List.select = function ($item) {
        return select($item);
    };

    List.getIndex = function () {
        return index;
    }

    List.isSelected = function ($item) {
        return $items.index($item) === index;
    }

    List.list = $list;
    List.items = $items;

    return init();
}
core.ui.Range = function (settings) {
    var Range = new Class(),
		defaults = {
		    'size': 5
		},
		offset = 0;

    settings = $.extend(true, defaults, settings);

    Range.forward = function () {
        offset = offset + 1;
    }

    Range.backward = function () {
        offset = offset - 1;
    }

    Range.getOffset = function () {
        return offset;
    }

    Range.size = settings.size;

    return Range;

}
core.ui.Control = function (settings) {
    var Control = new Class(),
		defaults = {
		    'states': {
		        'disabled': { 'opacity': .25 },
		        'enabled': { 'opacity': .75 },
		        'mouseover': { 'opacity': 1 },
		        'mouseup': { 'opacity': .75 },
		        'mousedown': { 'opacity': .85 },
		        'mouseout': { 'opacity': .75 }
		    },
		    'duration': 0,
		    'easing': 'linear'
		},
		state = 'enabled',
		$element;

    settings = $.extend(true, defaults, settings);

    $element = settings.element;

    function init() {

        $element.mouseover(Control.mouseover);
        $element.mouseout(Control.mouseout);
        $element.mousedown(Control.mousedown);
        $element.mouseup(Control.mouseup);

        return Control;
    }

    function setState(s, r) {
        Control.trigger('StateChangeInitialized', [s]);
        $element.stop(true, true).animate(settings.states[s], settings.duration, settings.easing, function () {
            Control.trigger('StateChangeComplete', [s]);
            state = s;
            $element.addClass(s).removeClass(r);
        });
    }

    Control.setState = function (s, r) {
        setState(s, r);
    }

    Control.getState = function () {
        return state;
    }

    Control.enable = function () {
        if (state === 'disabled') {
            setState('enabled', 'disabled');
        }
    }

    Control.disable = function () {
        if (state !== 'disabled') {
            setState('disabled', 'enabled');
        }
    }

    Control.mouseover = function () {
        if (state !== 'disabled') {
            setState('mouseover', 'mouseout');
        }
    }

    Control.mouseout = function () {
        if (state !== 'disabled') {
            setState('mouseout', 'mouseover');
        }
    }

    Control.mousedown = function () {
        if (state !== 'disabled') {
            setState('mousedown', 'mouseup');
        }
    }

    Control.mouseup = function () {
        if (state !== 'disabled') {
            setState('mouseup', 'mousedown');
        }
    }

    Control.element = $element;

    return init();

}
core.ui.SlidingRangeList = function (settings) {

    var SlidingRangeList = new Class(),
		defaults = {},
		width = 0,
		Slider,
		Range,
		List,
		left,
		right;

    settings = $.extend(true, defaults, settings);

    Slider = settings.slider;
    Range = settings.range;
    List = settings.list;
    left = settings.controls.left;
    right = settings.controls.right;

    function init() {

        List.items.each(function (index, item) {
            var $item = $(item);
            $item.css({ 'left': width });
            width = width + $item.width();
        });

        List.list.css({
            'width': width
        });

        initControls();

        return SlidingRangeList;

    }

    function initControls() {
        var i;

        if (Slider.getState() === false) {
            if (Range.getOffset() <= 0) {
                left.disable();
            }
            else {
                left.enable();
            }

            if (Range.getOffset() >= List.items.length - Range.size) {
                right.disable();
            }
            else {
                right.enable();
            }
        }
    }

    right.element.click(function (event) {
        event.preventDefault();
        if (right.getState() !== 'disabled' && Slider.getState() === false) {
            Slider.setIncrement(List.items.eq(Range.getOffset() + Range.size).width());
            Slider.forward();
            Range.forward();
        }
    });

    left.element.click(function (event) {
        event.preventDefault();
        if (left.getState() !== 'disabled' && Slider.getState() === false) {
            Slider.setIncrement(List.items.eq(Range.getOffset()).width());
            Slider.backward();
            Range.backward();
        }
    });

    Slider.bind('animationCompleted', function (event) {
        initControls();
    });

    Slider.bind('animationStarted', function (event) {
        initControls();
    });

    return init();

}
core.ui.HtmlTemplate = function (settings) {
    var HtmlTemplate = new Class(),
		defaults = {},
		element;

    settings = $.extend(true, defaults, settings);

    element = settings.element;
    element.remove();

    HtmlTemplate.html = element;

    return HtmlTemplate;

}
core.ui.Overlay = function (settings) {
    var Overlay = new Class(),
		defaults = {
		    'color': '#000000',
		    'opacity': .5,
		    'target': $('body'),
		    'id': 'overlay',
		    'speed': 250
		},
		element;

    settings = $.extend(true, defaults, settings);

    element = $('<div></div>').attr({
        'id': settings.id
    }).css({
        'backgroundColor': settings.color,
        'opacity': 0
    }).addClass('overlay');

    Overlay.show = function () {
        settings.target.append(element);
        Overlay.$element = $('#' + settings.id);
        Overlay.$element.css('display', 'block');
        Overlay.$element.eq(0).fadeTo(settings.speed, settings.opacity, function () {
            Overlay.trigger('shown');
        });

    }

    Overlay.hide = function () {
        $('#' + settings.id).stop().fadeOut(settings.speed, function () {
            $(this).remove();
            Overlay.trigger('hidden');
        });
    }

    return Overlay;

}
core.ui.ImageLoader = function (settings) {
    var ImageLoader = new Class(),
		defaults = {},
		image = new Image();

    settings = $.extend(true, defaults, settings);

    (function () {
        var url = settings.url;

        image.onload = function () {
            ImageLoader.trigger('imageLoaded', image);
        }

        image.src = url;

    } ());

    return ImageLoader;

}
core.ui.Marquee = function (settings) {
    return new core.ui.StateManager(settings);
}
core.ui.StateManager = function (settings) {
    var StateManager = core.Stateful(settings.state);
    return StateManager;
}
core.ui.Suckerfish = function (settings) {
    var Suckerfish = new Class(),
		defaults = {
		    'duration': 500,
		    'easing': 'swing',
		    'delay': 500
		},
		$dropdowns;

    settings = $.extend(true, defaults, settings);

    List = settings.list;

    $dropdowns = $('.dropdown', List.items);

    List.items.each(function (index, item) {
        var $this = $(item),
			$background,
			$dropdown,
			$shim,
			$item,
			expandedHeight,
        //Manage the Suckerfish State -- contracted, expanding, expanded, contracting
			SuckerfishStateManager = new core.ui.StateManager({ 'state': 'contracted' }),
        //Manage Hover states of Elements within the Suckerfish dropdown -- true for hover over, false for hover out
			DropdownStateManager = new core.ui.StateManager({ 'state': false }),
			ShimStateManager = new core.ui.StateManager({ 'state': false }),
			ItemStateManager = new core.ui.StateManager({ 'state': false });

        SuckerfishStateManager.bind('stateChanged', function (event, state) {
            Suckerfish.trigger('suckerFished', [$this, state]);
            $this.removeClass('contracted expanding expanded contracting');
            $this.addClass(state);
        });

        ShimStateManager.bind('stateChanged', function (event, state) {
            updateState();
        });

        ItemStateManager.bind('stateChanged', function () {
            updateState();
        });

        DropdownStateManager.bind('stateChanged', function () {
            updateState();
        });

        $dropdown = $('.dropdown', $this);

        (function () {
            var $shim = $('<a href="#"> </a>').css({
                'position': 'absolute',
                'top': 0,
                'left': 0,
                'display': 'block',
                'width': '100%',
                'background': 'url(/assets/images/global/common/transparencies/00x000000.gif)',
                'height': '100%',
                'cursor': 'default'
            }).click(function (event) {
                event.preventDefault();
            });
            $dropdown.append($shim);
        } ());

        $background = $('.background', $this);
        $shim = $('.tab_shim', $this);
        $item = $('h2', $this);

        expandedHeight = $dropdown.height();
        collapse();

        $item.hover(function (event) {
            ItemStateManager.setState(true);
        }, function (event) {
            ItemStateManager.setState(false);
        });

        $shim.hover(function (event) {
            ShimStateManager.setState(true);
        }, function (event) {
            ShimStateManager.setState(false);
        });

        $dropdown.hover(function (event) {
            DropdownStateManager.setState(true);
        }, function (event) {
            DropdownStateManager.setState(false);
        });

        function updateState() {
            var itemOver = ItemStateManager.getState(),
				dropdownOver = DropdownStateManager.getState(),
				shimOver = ShimStateManager.getState();

            if (shimOver) {
                collapse(0, settings.duration / 2);
            } else {
                if (itemOver) {
                    expand(settings.delay);
                } else if (!itemOver && !dropdownOver) {
                    collapse(settings.delay, settings.duration);
                } else if (!itemOver && dropdownOver) {
                    expand(settings.delay);
                }
            }

        }

        function expand(delay) {
            SuckerfishStateManager.setState('expanding');
            window.setTimeout(function () {
                if (SuckerfishStateManager.getState() === 'expanding') {
                    $background.stop().animate({
                        'height': expandedHeight
                    }, settings.duration, settings.easing, function () {
                        SuckerfishStateManager.setState('expanded');
                    });
                }
            }, delay);
        }

        function collapse(delay, duration) {
            SuckerfishStateManager.setState('contracting');
            window.setTimeout(function () {
                if (SuckerfishStateManager.getState() === 'contracting') {
                    ;
                    $background.stop().animate({
                        'height': 0
                    }, duration, settings.easing, function () {
                        SuckerfishStateManager.setState('contracted');
                    });
                }
            }, delay);
        }

        $this.state = SuckerfishStateManager;

    });

    Suckerfish.getList = function () {
        return List;
    }
    return Suckerfish;
}
core.ui.VideoPlayer = function (settings) {
    var VideoPlayer = core.Instantiatable(),
		defaults = {},
		videoPlayer = '/assets/plugins/video_player.swf',
		flashVersion = '9.0.0',
		expressInstall = '/assets/plugins/expressInstall.swf';


    settings = $.extend(true, defaults, settings);

    VideoPlayer.VideoPlayerInstance = function (settings) {
        var VideoPlayerInstance = core.ui.StateManager({ 'state': false }),
			defaults = {},
			id,
			target,
			player;

        settings = $.extend(true, defaults, settings);

        target = settings.target;

        id = $('.embed', target).attr('id');


        VideoPlayerInstance.embed = function () {
            swfobject.embedSWF(videoPlayer, id, target.width(), target.height(), flashVersion, expressInstall, {
                'target': target.attr('id'),
                'gateway': 'EventDelegator'
            }, {
                'menu': 'false',
                'wmode': 'transparent',
                'allowScriptAccess': 'always',
                'scale': 'noscale',
                'salign': 'tl'
            }, {
                'class': 'video_player'
            }, function (event) {
                window[id] = document.getElementById(id);
            });

            VideoPlayerInstance.setState(true);

        }

        VideoPlayerInstance.dispose = function () {
            core.util.purge($('.video_player', target).get(0));
            target.empty().append('<div id="' + id + '" class="embed"></div>');
            VideoPlayerInstance.setState(false);
        }

        VideoPlayerInstance.getId = function () {
            return id;
        }

        VideoPlayerInstance.getPlayer = function () {
            return player;
        }

        VideoPlayer.instantiate(target.attr('id'), VideoPlayerInstance);

        return VideoPlayerInstance;

    }

    return VideoPlayer;

}

core.util = {};
core.util.String = (function () {
    return {
        'beautify': function (str) {
            str = str.replace(/-/g, ' ');
            return this.toTitleCase(str);
        },
        'uglify': function (str) {
            return str.replace(' & ', ' and ').replace(/[^a-zA-Z0-9_]/g, '-').replace(/^-|-$/g, '').toLowerCase().replace(/~[^-a-z0-9_]+~/g, '').replace(/[-]+/g, '-').replace(/[_]+/g, '_');
        },
        'explodeURL': function (url) {
            var regexp = /^(([^:\/\?#]+):)?(\/\/([^\/\?#]*))?([^\.\?#]*)(\.([^\?#]*))?(\?([^#]*))?(#(.*))?/, exploded = regexp.exec(url), urlFragments = {
                scheme: exploded[2],
                authority: exploded[4],
                path: exploded[5],
                extension: exploded[7],
                query: exploded[9],
                fragment: exploded[11]
            };

            return urlFragments;
        },
        'implodeURL': function (obj) {
            var url = '';
            if (obj['scheme'] && obj['authority']) {
                url += obj['scheme'] + '://' + obj['authority'];
            }
            url += obj['path'];
            if (obj['extension']) {
                url += '.' + obj['extension'];
            }
            if (obj['query']) {
                url += '?' + obj['query'];
            }
            if (obj['fragment']) {
                url += '#' + obj['fragment'];
            }
            return url;
        },
        /**
        * TODO: Add description
        * @author David Gouch <http://individed.com>
        * @method toTitleCase
        */
        'toTitleCase': function (str) {
            return str.replace(/([\w&`'‘’"“.@:\/\{\(\[<>_]+-? *)/g, function (match, p1, index, title) {
                if (index > 0 && title.charAt(index - 2) !== ":" &&
				match.search(/^(a(nd?|s|t)?|b(ut|y)|en|for|i[fn]|o[fnr]|t(he|o)|vs?\.?|via)[ \-]/i) > -1)
                    return match.toLowerCase();
                if (title.substring(index - 1, index + 1).search(/['"_{(\[]/) > -1)
                    return match.charAt(0) + match.charAt(1).toUpperCase() + match.substr(2);
                if (match.substr(1).search(/[A-Z]+|&|[\w]+[._][\w]+/) > -1 ||
				title.substring(index - 1, index + 1).search(/[\])}]/) > -1)
                    return match;
                return match.charAt(0).toUpperCase() + match.substr(1);
            });
        }
    }
} ());
core.util.String.template = function (string, object) {
    if (string == '' || string == null) {
        return '';
    }
    else {
        return string.replace(/{([^{}]*)}/g, function (a, b) {
            var r = object[b];
            return typeof r === 'string' || typeof r === 'number' ? r : a;
        });
    }
}
core.util.JSON = {};
core.util.JSON.initialize = (function () {

    /*
    http://www.JSON.org/json2.js
    2009-09-29
    Public Domain.
    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
    See http://www.JSON.org/js.html
    */

    function f(n) {
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf()) ?
			this.getUTCFullYear() + '-' +
			f(this.getUTCMonth() + 1) + '-' +
			f(this.getUTCDate()) + 'T' +
			f(this.getUTCHours()) + ':' +
			f(this.getUTCMinutes()) + ':' +
			f(this.getUTCSeconds()) + 'Z' : null;
        };

        String.prototype.toJSON =
		Number.prototype.toJSON =
		Boolean.prototype.toJSON = function (key) {
		    return this.valueOf();
		};
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
	escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
	gap,
	indent,
	meta = {
	    '\b': '\\b',
	    '\t': '\\t',
	    '\n': '\\n',
	    '\f': '\\f',
	    '\r': '\\r',
	    '"': '\\"',
	    '\\': '\\\\'
	},
	rep;

    function quote(string) {
        escapable.lastIndex = 0;
        return escapable.test(string) ?
		'"' + string.replace(escapable,
		function (a) {
		    var c = meta[a];
		    return typeof c === 'string' ? c :
			'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
		}) + '"' :
		'"' + string + '"';
    }

    function str(key, holder) {
        var i,
			k,
			v,
			length,
			mind = gap,
			partial,
			value = holder[key];

        if (value && typeof value === 'object' &&
		typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

        switch (typeof value) {
            case 'string':
                return quote(value);
            case 'number':
                return isFinite(value) ? String(value) : 'null';
            case 'boolean':
            case 'null':
                return String(value)
            case 'object':

                if (!value) {
                    return 'null';
                }

                gap += indent;
                partial = [];

                if (Object.prototype.toString.apply(value) === '[object Array]') {

                    length = value.length;
                    for (i = 0; i < length; i += 1) {
                        partial[i] = str(i, value) || 'null';
                    }

                    v = partial.length === 0 ? '[]' :
				gap ? '[\n' + gap +
				partial.join(',\n' + gap) + '\n' +
				mind + ']' :
				'[' + partial.join(',') + ']';
                    gap = mind;
                    return v;

                }

                if (rep && typeof rep === 'object') {
                    length = rep.length;
                    for (i = 0; i < length; i += 1) {
                        k = rep[i];
                        if (typeof k === 'string') {
                            v = str(k, value);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                } else {

                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = str(k, value);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                }

                v = partial.length === 0 ? '{}' :
			gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
			mind + '}' : '{' + partial.join(',') + '}';
                gap = mind;
                return v;
        }
    }

    if (typeof core.util.JSON.stringify !== 'function') {
        core.util.JSON.stringify = function (value, replacer, space) {

            var i;
            gap = '';
            indent = '';

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }


            } else if (typeof space === 'string') {
                indent = space;
            }

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
			(typeof replacer !== 'object' ||
			typeof replacer.length !== 'number')) {
                throw new Error('core.util.JSON.stringify');
            }

            return str('', {
                '': value
            });
        };
    }

    if (typeof core.util.JSON.parse !== 'function') {
        core.util.JSON.parse = function (text, reviver) {

            var j;

            function walk(holder, key) {

                var k,
				v,
				value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }

            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx,
				function (a) {
				    return '\\u' +
					('0000' + a.charCodeAt(0).toString(16)).slice(-4);
				});
            }

            if (/^[\],:{}\s]*$/.
			test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
			replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
			replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

                j = eval('(' + text + ')');

                return typeof reviver === 'function' ?
				walk({
				    '': j
				},
				'') : j;
            }

            throw new SyntaxError('core.util.JSON.parse');
        };
    }

    return true;

} ());
core.util.ServiceHandler = function (settings) {
    var Handler = new Class(),
		defaults = {
		    'type': 'get',
		    'url': '',
		    'data': '',
		    'dataType': 'html'
		};

    settings = $.extend(true, defaults, settings);

    Handler.data = {};

    function init() {

        $.ajax({
            'type': "POST",
            'url': settings.url,
            'data': settings.data,
            'dataType': settings.dataType,
            'contentType': 'application/json',
            'success': function (data) {
                Handler.data = data;
                Handler.trigger('loaded');
            }
        });

        return Handler;

    }

    return init();
}
core.util.Array = {};
core.util.Array.indexOf = function (array, value, options) {
    var i,
		defaultOptions = {
		    'start': 0
		};

    options = $.extend(true, {}, defaultOptions, options);

    for (i = options.start; i < array.length; i = i + 1) {
        if (array[i] === value) {
            return i;
        }
    }

    return -1;
}
core.util.Array.unique = function (array) {
    var i,
		tempArray = [],
		length = array.length;

    for (i = 0; i < length; i = i + 1) {
        if (core.util.Array.indexOf(tempArray, array[i]) < 0) {
            tempArray.push(array[i]);
        }
    }

    return tempArray;
}
core.util.purge = function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}

FlashGateway = function (type, target, args) {
    var embed;
    args = core.util.JSON.stringify(args);
    (function () {
        embed = document.getElementById(target);
        if (embed === null) {
            window.setTimeout(arguments.callee, 0);
        } else {
            embed.javascriptGateway(type, args);
        }
    })();

}

EventDelegator = function (type, target, args) {
    $('#' + target).trigger(type);
}
