//  HULU CONFIDENTIAL MATERIAL. DO NOT DISTRIBUTE.
//  Copyright (C) 2009-2010 Hulu, LLC
//  All Rights Reserved
/**
 *
 * htvViews.js
 *
 * Defines the view classes that comprise the navigation UI and interactions.
 * The BaseView implements general functionality related to use input, state,
 * and the optional hierarchical layout definition of controls.   
 */
/*jslint maxerr: 1000, nomen: false, evil: false, immed: true, plusplus: false */
/*global LOG describe */
var $htv;
$htv.Views = {};

$htv.Views.BaseView = function () {
    this._root = null;
    this._platformCanvasHandle = null;
    this._activeNode = null; 
    this._controls = [];
    this._instanceOptions = null;
    this.saveState = this._saveState;
    this.restoreState = this._restoreState;
    this.discard = this._discard;
    this._currentControlHasNotReceivedInput = true;
    this._overrideFirstSpotlightAnimation = false;
    this._overrideLastSpotlightAnimation = false;
    this._inSavedState = false;
};

$htv.Views.BaseView.prototype._loadChild = function (url, type, node, options) {
    var target, ac, temp, i, snode;
    
    // is this a bad idea?  swallowing options errors..
    if (options === undefined) {
        options = {};
    }
    options.canvas = this._platformCanvasHandle;
    
    // check command, get pointer to target
    target = node.children[type];
    
    // recurse through children that we're switching away from, and release them into the pool.
    ac = node.activeChild;
    while (ac !== null) {
        if (ac.control !== null) {
            $htv.ControlPool.releaseObject(ac.control);
            ac.control = null;
        }
        for (i = 0; i < ac.siblings.length; i++) {
            snode = ac.siblings[i];
            $htv.ControlPool.releaseObject(snode.control);
            snode.control = null;
        }
        // set activeChild branch to null
        temp = ac.activeChild;
        ac.activeChild = null;
        ac = temp;
    }
    
    if (target === undefined) {
        
        return;
    }
    
    node.activeChild = target;
    // initialize control based on type
    target.control = $htv.ControlPool.getObject(target.type);
    if (target.control !== null) {
        target.control.initialize(target.position, target, $htv.Constants.Endpoints.menu + url, options);
        this._initializeSiblingViews(target);
    }
    else {
        
    }  
};

$htv.Views.BaseView.prototype._initializeSiblingViews = function (node) {
    var i, snode;
    for (i = 0; i < node.siblings.length; i++) {
        snode = node.siblings[i];
        snode.control = $htv.ControlPool.getObject(snode.type);
        if (snode.control !== null) {
            // todo: if snodes need nnode state, then we can pass a pointer in options.
            snode.control.initialize(snode.position, snode, "", {});
        }
    }
};

$htv.Views.BaseView.prototype._allowInput = function (eventData) {
    // ignore if first even to new view is up event.
    if (this._currentControlHasNotReceivedInput === true) {
        if (eventData.is_down === false) {
            
            return false;
        }
        this._currentControlHasNotReceivedInput = false;
    }
    return true;
};

$htv.Views.BaseView.prototype._navigateToControl = function (node, direction) {
    if (this._activeNode !== null) { // todo: something happened that made this necessary. (player stop bug)
        this._activeNode.control.unfocus();
    }
    
    if (node !== null) {
        this._activeNode = node;
        this._activeNode.control.focus(direction);
        this._currentControlHasNotReceivedInput = true;
    }
};

// basically gives you some navigation features for free.  don't specify a nav_dir
// and handle the events yourself if you want more complicated behavior.
$htv.Views.BaseView.prototype._navigateBetweenControls = function (eventData) {
    var navInfo = this._activeNode.nav_info;
    if (!navInfo || !navInfo[eventData.nav_dir]) {
        
        return;
    }
    navInfo = navInfo[eventData.nav_dir];
    switch (navInfo.type) {
    case "control":
        this._navigateToControl(navInfo.node, eventData.nav_dir);
        break;
    case "child_control":
        this._navigateToControl(this._activeNode.activeChild, eventData.nav_dir);
        break;
    case "pop_view":
        $htv.Controller.popView();
        break;
    case "push_view":
        $htv.Controller.pushView(eventData.view_name, eventData.options);
        break;
    }
};

$htv.Views.BaseView.prototype._saveState = function () {
    // recurse through children that we're switching away from, and release them into the pool.
    var view, i;
    
    view = {
        activeControl: null,
        viewNodes: [],
        viewName: null,
        options: null
    };
    
    this._inSavedState = true;
    view.viewName = this.viewName;
    view.activeControl = this._activeNode;
    view.options = this._instanceOptions;
    
    
    // 2 stage hide, does this improve transition?
    for (i = 0; i < this._controls.length; i++) {
        if (this._controls[i].control !== null) {
            this._controls[i].control.hide();
        }
    }
    
    for (i = 0; i < this._controls.length; i++) {
        view.viewNodes.push({
            activeChild: this._controls[i].activeChild,
            control: this._controls[i].control
        });
        this._controls[i].control = null;
        this._controls[i].activeChild = null;
    }
    return view;
};
    
$htv.Views.BaseView.prototype._restoreState = function (view) {
    this._inSavedState = false;
    for (var i = 0; i < view.viewNodes.length; i++) {
        this._controls[i].control = view.viewNodes[i].control;
        if (this._controls[i].control !== null) {
            this._controls[i].control.show();
        }
        this._controls[i].activeChild = view.viewNodes[i].activeChild;
    }
    this._activeNode = view.activeControl;
    this._instanceOptions = view.options;
    if (this._activeNode.control) {
        this._activeNode.control.focus();
    } else {
        
        this._activeNode = this._controls[0];
        this._activeNode.control.focus();
    }
};
    
$htv.Views.BaseView.prototype._discard = function () {
    this._activeNode = null;
    for (var i = 0; i < this._controls.length; i++) {
        this._controls[i].activeChild = null;
        if (this._controls[i].control !== null) {
            $htv.ControlPool.releaseObject(this._controls[i].control);
        } 
        this._controls[i].control = null;
    }
};


$htv.Views.ActivationView = function () {
    this.viewName = "ActivationView";
    this._overrideFirstSpotlightAnimation = true;
    
    this._initialize = function (options) {
        
        this._activeNode = this.loginButton;
        this._inSavedState = false;
        
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-top-unfocused.png", options);
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        
        var activationUrl = "www.hulu.com/signmein";
        if (!$htv.Utils.stringIsNullOrEmpty($htv.Constants.Endpoints.activateCodeURL)) {
            activationUrl = $htv.Constants.Endpoints.activateCodeURL;
        }
        activationUrl = activationUrl.replace("http://", ""); // make user friendlier

        // Text
        this.titleText.control = $htv.ControlPool.getObject("TextControl");
        this.titleText.control.initialize(this.titleText.position, this.titleText, null, {
            text: "Activate This Device",
            styleName: $htv.Styles.ActivationTitle
        });
        this.descriptionText.control = $htv.ControlPool.getObject("TextControl");
        this.descriptionText.control.initialize(this.descriptionText.position, this.descriptionText, null, {
            text: "Or connect this device to your Hulu Plus account by going to\n" + activationUrl + " and entering your activation code.",
            styleName: $htv.Styles.ActivationDescription
        });
        this.codeText.control = $htv.ControlPool.getObject("TextControl");
        this.codeText.control.initialize(this.codeText.position, this.codeText, null, {
            text: "",
            styleName: $htv.Styles.ActivationCode
        });

        // Buttons
        this.loginButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.loginButton.control.initialize(this.loginButton.position, this.loginButton, null, {
            text: "Log in to Hulu Plus",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-sample-learn.png",
            unfocused_image: "images/btn-sample-learn.png",
            include_brackets: true
        });
        this.sampleVideosButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.sampleVideosButton.control.initialize(this.sampleVideosButton.position, this.sampleVideosButton, null, {
            text: "View sample videos",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-sample-learn.png",
            unfocused_image: "images/btn-sample-learn.png",
            include_brackets: true
        });
        this.learnMoreButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.learnMoreButton.control.initialize(this.learnMoreButton.position, this.learnMoreButton, null, {
            text: "Learn more about Hulu Plus",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-sample-learn.png",
            unfocused_image: "images/btn-sample-learn.png",
            include_brackets: true
        });
        
        this.loginButton.control.focus();        
                
        this.codeText.control.setText("Device Activation Code:   (loading...)");
        $htv.Profile.getAuthenticationCode(this, this.onCodeLoaded); 
    };
    
    this.onCodeLoaded = function (result) {
        if (result.success) {
            this.authenticationCode = result.code;

            if (this.codeText.control !== null) {
                this.codeText.control.setText("Device Activation Code:   " + this.authenticationCode);
            }
            $htv.Profile.enableAuthenticationPolling();
        }
    };

    this._handleButtonActivated = function (eventData) {
        switch (eventData.target) {
        case this.loginButton:
            $htv.Controller.pushView("LoginView", {});
            break;
        case this.sampleVideosButton:
            $htv.Controller.pushView("SampleVideosView", {});
            break;
        case this.learnMoreButton:
            $htv.Controller.pushView("LearnMoreView", {});
            break;
        default:
            break;
        }
    };

    this._handleEvent = function (eventName, eventData) {
       
        switch (eventName) {
        case "USER_INPUT":
            // TODO: RETURN should probably exit.
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "RETURN_KEY_PRESSED":
            $htv.Controller.popView();
            break;
        case "BUTTON_ACTIVATED":
            this._handleButtonActivated(eventData);
            break;
        case "VIEW_WILL_DISAPPEAR":
            $htv.Profile.disableAuthenticationPolling();
            break;
        case "VIEW_DID_REAPPEAR":
            $htv.Profile.enableAuthenticationPolling();
            break;
        default: 
            
            break;
        }
    };

    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };

    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 54,
            y: 26,
            z: 2,
            width: 200,
            height: 34
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 300,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };

    this.titleText = {
        view: view,
        type: "TextControl",
        position: {
            x: 280,
            y: 43,
            z: 2,
            width: 680,
            height: 150
        },
        control: null
    };
    
    this.descriptionText = {
        view: view,
        type: "TextControl",
        position: {
            x: 280,
            y: 168,
            z: 2,
            width: 680,
            height: 150
        },
        control: null
    };
    
    this.codeText = {
        view: view,
        type: "TextControl",
        position: {
            x: 280,
            y: 225,
            z: 2,
            width: 680,
            height: 30
        },
        control: null
    };
    
    this.loginButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 960 / 2 - 249 / 2,
            y: 101,
            z: 2,
            width: 249,
            height: 29
        },
        control: null
    };
    
    this.sampleVideosButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 960 / 2 - 249 / 2,
            y: 373,
            z: 2,
            width: 249,
            height: 29
        },
        control: null
    };
    
    this.learnMoreButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 960 / 2 - 249 / 2,
            y: 421,
            z: 2,
            width: 249,
            height: 29
        },
        control: null
    };
    
    // attach nav_info
    
    this.loginButton.nav_info = {
        down: {
            type: "control",
            node: this.sampleVideosButton
        }
    };
    this.sampleVideosButton.nav_info = {
        down: {
            type: "control",
            node: this.learnMoreButton
        },
        up: {
            type: "control",
            node: this.loginButton
        }
    };
    this.learnMoreButton.nav_info = {
        up: {
            type: "control",
            node: this.sampleVideosButton
        }
    };
    
    this._controls.push(this.topBar);
    this._controls.push(this.huluLogo);
    this._controls.push(this.horizonMiddle);
    this._controls.push(this.titleText);
    this._controls.push(this.descriptionText);
    this._controls.push(this.codeText);
    this._controls.push(this.loginButton);
    this._controls.push(this.sampleVideosButton);
    this._controls.push(this.learnMoreButton);
    
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.ActivationView.prototype = new $htv.Views.BaseView();

$htv.Views.BrowseView = function () {
    var view, newRoot;
    this.viewName = "BrowseView";
    this.alphaIndexes = {};
    
    this._initialize = function (options) {
        
        this._instanceOptions = options;
        this._platformCanvasHandle = options.canvas;
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();      
        this.breadCrumb.control = $htv.ControlPool.getObject("BreadCrumb");
        this.breadCrumb.control.initialize(this.breadCrumb.position, this.breadCrumb, "null", options);
        this.breadCrumb.control.show();
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-unfocused.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-center-unfocused.png", options);
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-nav.png", options);
        this._loadChild(options.menu_url, "BrowseView", this._root, options);
        this._activeNode = this._root.children.BrowseView;
        this._activeNode.control.focus();
    };
    
    this._selectionChanged = function (eventData) {
        var ctl, letter, newIndex;
        if (this._activeNode === this.alphaMenu) {
            // Use the newly selected alpha menu item to jump
            // to the correct place in the thumbs carousel
            ctl = this.alphaMenu.control;
            letter = ctl.items.getItemAt(ctl.activeIndex).item.title;
            newIndex = ctl.getAlphaIndex(letter);
            
            if (!this.alphaMenu.children.ShowThumbnailCarousel.control && 
               !this.alphaMenu.children.VideoThumbnailCarousel.control && 
               !this.alphaMenu.children.CompanyThumbnailCarousel.control) {
                eventData.options.show_id = this._instanceOptions.show_id;
                eventData.options.show_canonical_name = this._instanceOptions.show_canonical_name;
                eventData.options.show_actual_total = true;
                this._loadChild(eventData.items_url, eventData.cmtype, eventData.target, eventData.options);
            }
            if (newIndex >= 0) {
                if (this.alphaMenu.children.ShowThumbnailCarousel.control) {
                    this.alphaMenu.children.ShowThumbnailCarousel.control.jumpToIndex(newIndex, {delayed_jump: true});
                }
                else if (this.alphaMenu.children.VideoThumbnailCarousel.control) {
                    this.alphaMenu.children.VideoThumbnailCarousel.control.jumpToIndex(newIndex, {delayed_jump: true});
                }
                else if (this.alphaMenu.children.CompanyThumbnailCarousel.control) {
                    this.alphaMenu.children.CompanyThumbnailCarousel.control.jumpToIndex(newIndex, {delayed_jump: true});
                }
            }
            return;
        }

        
        switch (eventData.cmtype) {
        case "VideoThumbnailCarousel":
        case "ShowThumbnailCarousel":
        case "CompanyThumbnailCarousel":
        case "ChannelThumbnailCarousel":
            eventData.options.show_id = this._instanceOptions.show_id;
            eventData.options.show_canonical_name = this._instanceOptions.show_canonical_name;
            eventData.options.show_actual_total = true;
            break;
        }
        this._loadChild(eventData.items_url, eventData.cmtype, eventData.target, eventData.options);
    };
    
    this._carouselSelectionChanged = function (eventData) {
        if (this._activeNode === this.vtc || this._activeNode === this.stc || this._activeNode === this.ctc) {
            if (this.alphaMenu.control) {
                var letter = null;
                if (!$htv.Utils.stringIsNullOrEmpty(eventData.collation_name)) {
                    letter = eventData.collation_name.charAt(0).toUpperCase();
                }
                else if (!$htv.Utils.stringIsNullOrEmpty(eventData.collation_title)) {
                    letter = eventData.collation_title.charAt(0).toUpperCase();
                }
                // TODO: does compnay have collation_name in Twinkie?
                else if (!$htv.Utils.stringIsNullOrEmpty(eventData.canonical_name)) {
                    letter = eventData.canonical_name.charAt(0).toUpperCase();
                }
                else {
                    return;
                }
                
                this.alphaMenu.control.jumpToAlpha(letter);
            }
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            if (this._activeNode === null) {
                //do nothing
            } else if (this._activeNode === this.vtc || this._activeNode === this.stc || this._activeNode === this.ctc) {
                this.horizonTop.control.setSource("images/horizon-top-focused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-focused.png");
            } else {
                this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-unfocused.png");
            }
            break;
        case "MENU_ITEM_ACTIVATED":
            this._navigateBetweenControls({nav_dir: "down"});
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "CAROUSEL_SELECTION_CHANGED":
            this._carouselSelectionChanged(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        default: 
            
            break;
        }
    };
    
    view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 217,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.breadCrumb = {
        view: view,
        parent: null,
        type: "BreadCrumb",
        position: {
            x: 4,
            y: 9,
            z: 4,
            width: 700,
            height: 40
        },
        control: null
    };
    
    newRoot = {
        view: view,
        parent: null,
        type: "None",
        position: {
            x: 0,
            y: 0,
            z: 3,
            width: 0,
            height: 0
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            BrowseView: null
        }
    };
    
    this.nsm = newRoot.children.BrowseView = {
        view: view,
        parent: newRoot,
        type: "NonSlidingMenu",
        position: {
            x: 40,
            y: 47,
            z: 4,
            width: 700,
            height: 35
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            AlphaMenu: null,
            NonSlidingMenu: null
        }
    };
    
    this.nsm2 = newRoot.children.BrowseView.children.NonSlidingMenu = {
        view: view,
        parent: newRoot.children.BrowseView,
        type: "NonSlidingMenu",
        position: {
            x: 80,
            y: 80,
            z: 4,
            width: 800,
            height: 35
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            VideoThumbnailCarousel: null
        }
    };
    
    this.vtc2 = newRoot.children.BrowseView.children.NonSlidingMenu.children.VideoThumbnailCarousel = {
        view: view,
        parent: newRoot.children.BrowseView.children.NonSlidingMenu,
        type: "VideoThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            
        }
    };

    this.chtc = newRoot.children.BrowseView.children.ChannelThumbnailCarousel = {
        view: view,
        parent: newRoot.children.BrowseView,
        type: "ChannelThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SlidingMenu: null
        } 
    };

    this.alphaMenu = newRoot.children.BrowseView.children.AlphaMenu = {
        view: view,
        parent: newRoot.children.BrowseView,
        type: "AlphaMenu",
        position: {
            x: 80,
            y: 80,
            z: 4,
            width: 760,
            height: 35
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            VideoThumbnailCarousel: null,
            ShowThumbnailCarousel: null,
            CompanyThumbnailCarousel: null
        }
    };
    
    this.vtc = newRoot.children.BrowseView.children.AlphaMenu.children.VideoThumbnailCarousel = {
        view: view,
        parent: newRoot.children.BrowseView.children.AlphaMenu,
        type: "VideoThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            
        }
    };
    
    this.stc = newRoot.children.BrowseView.children.AlphaMenu.children.ShowThumbnailCarousel = {
        view: view,
        parent: newRoot.children.BrowseView.children.AlphaMenu,
        type: "ShowThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SlidingMenu: null
        } 
    };

    this.ctc = newRoot.children.BrowseView.children.AlphaMenu.children.CompanyThumbnailCarousel = {
        view: view,
        parent: newRoot.children.BrowseView.children.AlphaMenu,
        type: "CompanyThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SlidingMenu: null
        } 
    };

    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 50,
            y: 475,
            z: 2,
            width: 93,
            height: 17
        },
        control: null
    };


    // attach nav_info
    
    newRoot.children.BrowseView.nav_info = {
        down: {
            type: "child_control"
        },
        up: {type: "pop_view"}
    };
    newRoot.children.BrowseView.children.ChannelThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.BrowseView
        }
    };
    newRoot.children.BrowseView.children.AlphaMenu.nav_info = {
        down: {
            type: "child_control"
        },
        up: {
            type: "control",
            node: newRoot.children.BrowseView
        }
    };
    newRoot.children.BrowseView.children.NonSlidingMenu.nav_info = {
        down: {
            type: "child_control"
        },
        up: {
            type: "control",
            node: newRoot.children.BrowseView
        }
    };
    newRoot.children.BrowseView.children.NonSlidingMenu.children.VideoThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.BrowseView.children.NonSlidingMenu
        }
    };
    newRoot.children.BrowseView.children.AlphaMenu.children.VideoThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.BrowseView.children.AlphaMenu
        }
    };
    newRoot.children.BrowseView.children.AlphaMenu.children.ShowThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.BrowseView.children.AlphaMenu
        }
    };
    newRoot.children.BrowseView.children.AlphaMenu.children.CompanyThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.BrowseView.children.AlphaMenu
        }
    };
    this._controls.push(this.topBar);
    this._controls.push(this.breadCrumb);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonMiddle);
    this._controls.push(newRoot);
    this._controls.push(newRoot.children.BrowseView);
    this._controls.push(newRoot.children.BrowseView.children.ChannelThumbnailCarousel);
    this._controls.push(newRoot.children.BrowseView.children.NonSlidingMenu);
    this._controls.push(newRoot.children.BrowseView.children.NonSlidingMenu.children.VideoThumbnailCarousel);
    this._controls.push(newRoot.children.BrowseView.children.AlphaMenu);
    this._controls.push(newRoot.children.BrowseView.children.AlphaMenu.children.VideoThumbnailCarousel);
    this._controls.push(newRoot.children.BrowseView.children.AlphaMenu.children.ShowThumbnailCarousel);
    this._controls.push(newRoot.children.BrowseView.children.AlphaMenu.children.CompanyThumbnailCarousel);
    this._controls.push(this.huluLogo); 
    
    this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.BrowseView.prototype = new $htv.Views.BaseView();

$htv.Views.ContentView = function () {
    var newRoot, view;
    this.viewName = "ContentView";
    
    this._initialize = function (options) {
        
        this._instanceOptions = options;
        this._platformCanvasHandle = options.canvas;
        this._activeNode = this._root.children.ContentView;
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();      
        this.breadCrumb.control = $htv.ControlPool.getObject("BreadCrumb");
        this.breadCrumb.control.initialize(this.breadCrumb.position, this.breadCrumb, "null", options);
        this.breadCrumb.control.show();
        this.loadingText.control = $htv.ControlPool.getObject("TextControl");
        this.loadingText.control.initialize(this.loadingText.position, this.loadingText, "", {text: "Loading...", styleName: $htv.Styles.CarouselCount});
        this.loadingText.control.show();
        // todo: siblingify horizons..
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-unfocused.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-center-unfocused.png", options);
        this.horizonBottom.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonBottom.control.initialize(this.horizonBottom.position, this.horizonBottom, "images/horizon-center-unfocused.png", options);
        this.horizonBottom.control.hide();
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-nav.png", options);
        this._loadChild(options.menu_url, "ContentView", this._root, options);
        this._activeNode.control.focus();
    };
    
    this._resetHorizonState = function () {
        if (this._instanceOptions.cmtype === "RatingControl" ||
            this._instanceOptions.cmtype === "SubscriptionControl" ||
            this._instanceOptions.cmtype === "TextControl" ||
            this._instanceOptions.cmtype === "ButtonHint") {
            this.horizonMiddle.control.hide();
            this.horizonBottom.control.show();
        } else {
            this.horizonMiddle.control.show();
            this.horizonBottom.control.hide();            
        }
    };
    
    this._selectionChanged = function (eventData) {
        // HACK: Twinkie returns a TextControl but we're now using a ButtonHint.
        if (eventData.cmtype === "TextControl" && !$htv.Utils.stringIsNullOrEmpty(eventData.options.child_text)) {
            eventData.cmtype = "ButtonHint";
            
            var hintText = eventData.options.child_text.split("[OK]");
            
            eventData.options.button_image_path = "images/home-hint.png";
            eventData.options.prefix_text = $htv.Utils.trim(hintText[0]);
            eventData.options.postfix_text = $htv.Utils.trim(hintText[1]);
        }
        
        
        this._instanceOptions.cmtype = eventData.cmtype;
        switch (eventData.cmtype) {
        case "NonSlidingMenu":
            // HACK: NSM only used for season right now
            eventData.options.max_items_visible = 6;
            break;
        case "VideoThumbnailCarousel":
        case "ShowThumbnailCarousel":
        case "RatingControl":
        case "SubscriptionControl":
            eventData.options.show_id = this._instanceOptions.show_id;
            eventData.options.show_name = this._instanceOptions.show_name;
            eventData.options.show_canonical_name = this._instanceOptions.show_canonical_name;
            eventData.options.total_seasons_count = this._instanceOptions.total_seasons_count;
            
            newRoot.children.ContentView.nav_info.down = {
                type: "child_control"
            };
            break;
        case "TextControl":
            // NOTE: child_text is specified in parent's menu app_data
            eventData.options.text = eventData.options.child_text;
            eventData.options.styleName = $htv.Styles.HomeMessage;
            delete newRoot.children.ContentView.nav_info.down;
            break;
        case "ButtonHint":
            break;
        }
        eventData.options.include_availability_notes = 
            (eventData.title === "Episodes" ||
            eventData.title === "Clips" ||
            eventData.title.indexOf("Season") === 0);
        
        this._resetHorizonState();
        this._loadChild(eventData.items_url, eventData.cmtype, eventData.target, eventData.options);
    };
    
    this._handleEvent = function (eventName, eventData) {

        switch (eventName) {
        case "VIEW_DID_REAPPEAR":
            this.loadingText.control.hide();
            this._resetHorizonState();
            if (this._activeNode === this.stc2 || this._activeNode === this.vtc2) {
                
                $htv.Controller.fireEvent("CONTENTVIEW_CAROUSEL2_FOCUSED", {});
            }
            break;
        case "USER_INPUT":
            if (eventData.action === "KEY_BLUE" && eventData.is_down === true) {
                this.horizonTop.control.hide();
                this.horizonMiddle.control.hide();
            }
            if (eventData.action === "KEY_YELLOW" && eventData.is_down === true) {
                this.horizonTop.control.show();
                this.horizonMiddle.control.show();
            }
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            
            if (this._activeNode === null) {
                //do nothing
            } else if (this._activeNode === this.nsm1 || this._activeNode === this.nsm2) {
                this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-unfocused.png");
                this.horizonBottom.control.setSource("images/horizon-center-unfocused.png");
            } else {
                this.horizonTop.control.setSource("images/horizon-top-focused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-focused.png");
                this.horizonBottom.control.setSource("images/horizon-center-focused.png");
            }
            
            if (this._activeNode === this.stc2 || this._activeNode === this.vtc2) {
                $htv.Controller.fireEvent("CONTENTVIEW_CAROUSEL2_FOCUSED", {});
            } else {
                $htv.Controller.fireEvent("CONTENTVIEW_NONCAROUSEL2_FOCUSED", {});
            }
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "MENU_ITEM_ACTIVATED":
            if (this._activeNode === this.homeHint) {
                $htv.Controller.popToHome();
            } else if (this._activeNode === this.nsm1 || this._activeNode === this.nsm2) {
                if (eventData.item.title === "Home") {
                    $htv.Controller.popToHome();
                }
                else if (eventData.item.title === "All From Show") {
                    if (this._instanceOptions.show_id !== null && this._instanceOptions.show_id !== undefined) {
                        if ($htv.Utils.stringIsNullOrEmpty(this._instanceOptions.feature_film_content_id)) {
                            $htv.Controller.pushView("ContentView", {
                                menu_url: "/menu/pd_show_page?show_id=" + this._instanceOptions.show_id,
                                view_title: this._instanceOptions.show_name,
                                show_id: this._instanceOptions.show_id,
                                show_name: this._instanceOptions.show_name,
                                show_canonical_name: this._instanceOptions.show_canonical_name,
                                previous_view_title: this._instanceOptions.previous_view_title
                            });    
                        }
                        else {
                            $htv.Controller.pushView("MovieDetailsView", {
                                view_title: this._instanceOptions.show_name,
                                content_id: this._instanceOptions.feature_film_content_id,
                                show_id: this._instanceOptions.show_id,
                                show_name: this._instanceOptions.show_name,
                                video_title: this._instanceOptions.feature_film_video_title,
                                video_id: this._instanceOptions.feature_film_video_id,
                                show_canonical_name: this._instanceOptions.show_canonical_name,
                                previous_view_title: this._instanceOptions.show_name,
                                clips_count: this._instanceOptions.clips_count
                            });                            
                        }
                    }
                }
                else if (eventData.item.title === "Log out") { 
                    var items = [{
                        text: "Yes",
                        callback: function () {
                            
                            $htv.Profile.logout();
                            $htv.Controller.popAllAndPushView("ActivationView", {});
                        },
                        receiver: this
                    }, {
                        text: "No",
                        callback: function () {
                            
                        },
                        receiver: this            
                    }];
                    
                    $htv.Controller.pushView("DialogBoxView", {
                        text: "Are you sure you want to log out?",
                        items: items
                    });
                }
                else { // just navigate downwards.
                    this._navigateBetweenControls({nav_dir: "down"});
                }
            }
            break;
        case "INITIALIZE_COMPLETE":
            
            if (this._activeNode === null) {
                
                describe(eventData.target);
            } else {
                this._activeNode.control.focus();
            }
            break;
        case "INITIALIZE_STARTED":
            
            if (eventData.target === this.vtc1 ||
                eventData.target === this.vtc2 ||
                eventData.target === this.stc1 ||
                eventData.target === this.stc2) {
                
                this.loadingText.control.hide();
            }
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        default: 
            
            break;
        }
    };
    
    view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 217,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.horizonBottom = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 327,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.loadingText = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 400,
            y: 220,
            z: 3,
            width: 160,
            height: 30
        },
        control: null
    };
    
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 50,
            y: 475,
            z: 2,
            width: 93,
            height: 17
        },
        control: null
    };
    
    this.breadCrumb = {
        view: view,
        parent: null,
        type: "BreadCrumb",
        position: {
            x: 4,
            y: 9,
            z: 4,
            width: 700,
            height: 40
        },
        control: null
    };
    
    newRoot = {
        view: view,
        parent: null,
        type: "None",
        position: {
            x: 0,
            y: 0,
            z: 3,
            width: 0,
            height: 0
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            ContentView: null
        }
    };
    
    this.nsm1 = newRoot.children.ContentView = {
        view: view,
        parent: newRoot,
        type: "NonSlidingMenu",
        position: {
            x: 40,
            y: 41,
            z: 4,
            width: 740,
            height: 35
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            VideoThumbnailCarousel: null,
            ShowThumbnailCarousel: null,
            NonSlidingMenu: null,
            RatingControl: null,
            ButtonHint: null
        }
    };
    
    this.ratingControl = newRoot.children.ContentView.children.RatingControl = {
        view: view,
        parent: this.nsm1,
        type: "RatingControl",
        position: {
            x: 0,
            y: 120,
            z: 3,
            width: 960,
            height: 420
        },
        siblings: [],
        activeChild: null,
        control: null
    };
    
    this.subscriptionControl = newRoot.children.ContentView.children.SubscriptionControl = {
        view: view,
        parent: this.nsm1,
        type: "SubscriptionControl",
        position: {
            x: 0,
            y: 120,
            z: 3,
            width: 960,
            height: 420
        },
        siblings: [],
        activeChild: null,
        control: null
    };
    
    this.homeHint = newRoot.children.ContentView.children.ButtonHint = {
        view: view,
        parent: this.nsm1,
        type: "ButtonHint",
        position: {
            x: 0,
            y: 250,
            z: 3,
            width: 960,
            height: 40
        },
        siblings: [],
        activeChild: null,
        control: null
    };
    
    this.vtc1 = newRoot.children.ContentView.children.VideoThumbnailCarousel = {
        view: view,
        parent: newRoot.children.ContentView,
        type: "VideoThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {}
    };
    
    this.stc1 = newRoot.children.ContentView.children.ShowThumbnailCarousel = {
        view: view,
        parent: newRoot.children.ContentView,
        type: "ShowThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
        } 
    };
    
    this.nsm2 = newRoot.children.ContentView.children.NonSlidingMenu = {
        view: view,
        parent: newRoot.children.ContentView,
        type: "NonSlidingMenu",
        position: {
            x: 70,
            y: 82,
            z: 4,
            width: 760,
            height: 35
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            VideoThumbnailCarousel: null,
            ShowThumbnailCarousel: null
        }
    };
    
    this.vtc2 = newRoot.children.ContentView.children.NonSlidingMenu.children.VideoThumbnailCarousel = {
        view: view,
        parent: newRoot.children.ContentView.children.NonSlidingMenu,
        type: "VideoThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            
        }
    };
    
    this.stc2 = newRoot.children.ContentView.children.NonSlidingMenu.children.ShowThumbnailCarousel = {
        view: view,
        parent: newRoot.children.ContentView.children.NonSlidingMenu,
        type: "ShowThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
        } 
    };
    // attach nav_info
    
    newRoot.children.ContentView.nav_info = {
        down: {
            type: "child_control"
        },
        up: {type: "pop_view"}
    };
    
    newRoot.children.ContentView.children.NonSlidingMenu.nav_info = {
        down: {
            type: "child_control"
        },
        up: {
            type: "control",
            node: newRoot.children.ContentView
        }
    };
    
    this.homeHint.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.ContentView
        }
    };
    
    this.ratingControl.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.ContentView
        }
    };
    
    this.subscriptionControl.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.ContentView
        }
    };

    newRoot.children.ContentView.children.VideoThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.ContentView
        }
    };
    
    newRoot.children.ContentView.children.ShowThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.ContentView
        }
    };
    newRoot.children.ContentView.children.NonSlidingMenu.children.VideoThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.ContentView.children.NonSlidingMenu
        }
    };
    newRoot.children.ContentView.children.NonSlidingMenu.children.ShowThumbnailCarousel.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.ContentView.children.NonSlidingMenu
        }
    };
    this._controls.push(this.topBar);
    this._controls.push(this.breadCrumb);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonMiddle);
    this._controls.push(this.horizonBottom);
    this._controls.push(this.huluLogo);
    this._controls.push(this.homeHint);
    this._controls.push(this.loadingText);
    this._controls.push(this.ratingControl);
    this._controls.push(this.subscriptionControl);
    this._controls.push(newRoot);
    this._controls.push(newRoot.children.ContentView);
    this._controls.push(newRoot.children.ContentView.children.VideoThumbnailCarousel);
    this._controls.push(newRoot.children.ContentView.children.ShowThumbnailCarousel);
    this._controls.push(newRoot.children.ContentView.children.NonSlidingMenu);
    this._controls.push(newRoot.children.ContentView.children.NonSlidingMenu.children.VideoThumbnailCarousel);
    this._controls.push(newRoot.children.ContentView.children.NonSlidingMenu.children.ShowThumbnailCarousel);
    
    this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.ContentView.prototype = new $htv.Views.BaseView();

/*jslint onevar: false */
$htv.Views.DialogBoxView = function () {
    var view;
    
    this.viewName = "DialogBoxView";
    this._overrideFirstSpotlightAnimation = true;
    this._overrideLastSpotlightAnimation = true;
    
    this._initialize = function (options) {
        
        this._controls = [];
        
        this._activeNode = this.background;
        this._instanceOptions = options;
        this._instanceOptions.buttonClosures = {};
        this.returnClosure = (options.return_closure !== undefined) ? options.return_closure : null;
        this.canCloseWithExit = (options.can_close_with_exit !== undefined) ? options.can_close_with_exit : true;
        
        this._controls.push(this.background);
        this._controls.push(this.message);
        this.background.control = $htv.ControlPool.getObject("ImageControl");
        this.background.control.initialize(this.background.position, this.background,
                (options.background !== undefined) ? options.background : "images/dialog-box-background.png", options);

        if (options.useHorizons === undefined || options.useHorizons === true) {
            this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
            this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-unfocused.png", options);
            this.horizonBottom.control = $htv.ControlPool.getObject("ImageControl");
            this.horizonBottom.control.initialize(this.horizonBottom.position, this.horizonBottom, "images/horizon-center-unfocused.png", options);
            this._controls.push(this.horizonTop);
            this._controls.push(this.horizonBottom);
        }
        
        var textStyle, textWidth, textXPadding, textYPadding, messagePosition;
        
        textStyle = (options.textStyle !== undefined) ? options.textStyle : $htv.Styles.DialogBoxMessageLarge;
        this.message.control = $htv.ControlPool.getObject("TextControl");
        textWidth = (options.textWidth !== undefined) ? options.textWidth : this.message.position.width;
        textXPadding = (options.textXPadding !== undefined) ? options.textXPadding : 0;
        textYPadding = (options.textYPadding !== undefined) ? options.textYPadding : 0;
        messagePosition = {
            x: this.message.position.x + textXPadding,
            y: this.message.position.y + textYPadding - 10,
            z: this.message.position.z,
            width: textWidth,
            height: this.message.position.height
        };
        this.message.control.initialize(messagePosition, this.message, null, { text: options.text, styleName: textStyle });
        
        if (options.titleText) {
            var titlePosition = {
                x: this.message.position.x,
                y: this.message.position.y - 10,
                z: this.message.position.z + 5,
                width: 560,
                height: 240
            };
            var title = {
                view: view,
                parent: null,
                type: "TextControl",
                position: titlePosition,
                control: null
            };
            title.control = $htv.ControlPool.getObject("TextControl");
            title.control.initialize(titlePosition, title, null, {
                text: options.titleText,
                styleName: options.titleStyle
            });
            this._controls.push(title);
        }
        
        var i, buttonNode, buttonItem, lastButtonNode, horizontalButtons;
        var DEFAULT_BUTTON_VERTICAL_SPACING = 13;
        var DEFAULT_BUTTON_HORIZONTAL_SPACING = 40;
        var DEFAULT_BUTTON_WIDTH = 90;
        var DEFAULT_BUTTON_HEIGHT = 29;
        var DEFAULT_BUTTON_X_INITIAL = 960 / 2;
        var DEFAULT_BUTTON_Y_INITIAL = 540 / 2;
        horizontalButtons = options.horizontalButtons !== undefined && options.horizontalButtons;
        
        for (i = 0; options.items && i < options.items.length; i++) {
            // Create button's control node
            buttonItem = options.items[i];
            
            var buttonWidth = (options.buttonWidth !== undefined) ? options.buttonWidth : DEFAULT_BUTTON_WIDTH;
            var buttonYInitial = (options.buttonYInitial !== undefined) ? options.buttonYInitial : DEFAULT_BUTTON_Y_INITIAL;
            
            var x = DEFAULT_BUTTON_X_INITIAL - buttonWidth / 2;
            var y = buttonYInitial + (DEFAULT_BUTTON_HEIGHT + DEFAULT_BUTTON_VERTICAL_SPACING) * i;
            if (horizontalButtons) {
                var totalWidth = options.items.length * buttonWidth + (options.items.length - 1) * DEFAULT_BUTTON_HORIZONTAL_SPACING;
                x = DEFAULT_BUTTON_X_INITIAL - totalWidth / 2 + (buttonWidth + DEFAULT_BUTTON_HORIZONTAL_SPACING) * i;
                y = buttonYInitial;
            }
            
            buttonNode = {
                view: view,
                parent: null,
                type: "ButtonControl",
                position: {
                    x: x,
                    y: y,
                    z: 2,
                    width: buttonWidth,
                    height: DEFAULT_BUTTON_HEIGHT
                },
                control: null
            };
            
            // Attach navigation between buttons
            buttonNode.nav_info = {};
            if (lastButtonNode) {
                // Horizontal navigation
                if (horizontalButtons) {
                    lastButtonNode.nav_info.right = {
                        type: "control",
                        node: buttonNode
                    };
                    buttonNode.nav_info.left = {
                        type: "control",
                        node: lastButtonNode
                    };
                }
                // Vertical navigation
                else {
                    lastButtonNode.nav_info.down = {
                        type: "control",
                        node: buttonNode
                    };
                    buttonNode.nav_info.up = {
                        type: "control",
                        node: lastButtonNode
                    };
                }
            }
            lastButtonNode = buttonNode;

            // Create button control
            buttonNode.control = $htv.ControlPool.getObject("ButtonControl");
            buttonNode.control.initialize(buttonNode.position, buttonNode, "null", {
                text: buttonItem.text,
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                focused_image: "images/btn-preview-marketing-back.jpg",
                unfocused_image: "images/btn-preview-marketing-back.jpg",
                include_brackets: true
            });
            
            // Add to View's controls list
            this._controls.push(buttonNode);
            // Record closure for activation handler
            this._instanceOptions.buttonClosures[buttonItem.text] = {
                callback: buttonItem.callback,
                receiver: buttonItem.receiver
            };
            
            // Focus first button
            if (i === 0) {
                this._activeNode = buttonNode;
                this._activeNode.control.focus();
            }
        }
    };

    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "RETURN_KEY_PRESSED": 
            if (this.returnClosure === null) {
                $htv.Controller.popView();
            } else {
                //Passing true because that is what is done for the button closures
                $htv.Controller.popView(true);
                this.returnClosure.callback.call(this.returnClosure.receiver);
            }
            // no closure call needed ?
            break;
        case "EXIT_KEY_PRESSED": 
            if (this.canCloseWithExit) {
                // no closure call needed ?
                if (this.returnClosure === null) {
                    $htv.Controller.popView();
                } else {
                    //Passing true because that is what is done for the button closures
                    $htv.Controller.popView(true);
                    this.returnClosure.callback.call(this.returnClosure.receiver);
                }
            }
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "BUTTON_ACTIVATED":
            if (this._instanceOptions.override_default_pop !== true) {
                // pop self before executing closure, passing flag to prevent exit, as the closure will still be executed.
                $htv.Controller.popView(true);
            }
            // "Close" dialog and take action if defined
            var closure = this._instanceOptions.buttonClosures[eventData.text];
            if (closure) {
                closure.callback.call(closure.receiver);
            } else {
                
            }
            
            break;
        default: 
            
            break;
        }
    };
    
    view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.background = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 0,
            z: 5,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 134,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonBottom = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 297,
            z: 1,
            width: 960,
            height: 111
        },
        control: null
    };
    
    this.message = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 200,
            y: 170,
            z: 1,
            width: 560,
            height: 240
        },
        control: null
    };
  

    
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.DialogBoxView.prototype = new $htv.Views.BaseView();
/*jslint onevar: true */

$htv.Views.HelpView = function () {
    this.viewName = "HelpView";
    this.menuItems = null;
    
    this._initialize = function (options) {
        
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        this.breadCrumb.control = $htv.ControlPool.getObject("BreadCrumb");
        this.breadCrumb.control.initialize(this.breadCrumb.position, this.breadCrumb, "null", options);
        this.breadCrumb.control.show();
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-unfocused.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-center-unfocused.png", options);
        this.horizonBottom.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonBottom.control.initialize(this.horizonBottom.position, this.horizonBottom, "images/horizon-center-unfocused.png", options);
        this.remoteHelpImages.control = $htv.ControlPool.getObject("ImageControl");
        this.remoteHelpImages.control.initialize(this.remoteHelpImages.position, this.remoteHelpImages, "images/help-nav-back.jpg", options);
        this.remoteHelpImages.control.hide();
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-nav.png", options);
        this._instanceOptions = options;
        
        var remotePseudonym, source;
        // Override the user-facing name for "Remote" on some platforms
        remotePseudonym = $htv.Platform.properties.hasOwnProperty("remote_pseudonym") ?
            $htv.Platform.properties.remote_pseudonym : "Remote";
        source = [{
            title: remotePseudonym,
            cmtype: 'NonSlidingMenu'
        }, {
            title: 'About / Version',
            cmtype: 'TextControl'
        }];
        if ($htv.Constants.Endpoints.hide_help_videos !== true) {
            source.unshift({
                title: 'Videos',
                cmtype: 'VideoThumbnailCarousel'
            });
        }
        
        this.menuItems = $htv.Utils.createGenericCollection(source);
        options.items = this.menuItems;
        this._activeNode = this.nsm1;
        this.nsm1.control = $htv.ControlPool.getObject("NonSlidingMenu");
        this.nsm1.control.initialize(this.nsm1.position, this.nsm1, "not used", options);
    };
    
    this._selectionChanged = function (eventData) {
        var options, versionStr;
        options = this._instanceOptions;
        if (eventData.target === this.nsm2) {
            if (eventData.title === "Playback") {
                this.remoteHelpImages.control.setSource("images/help-play-back.jpg");
            }
            else {
                this.remoteHelpImages.control.setSource("images/help-nav-back.jpg");
            }
            return;
        }
        
        if (this.vtc1.control !== null) {
            this.vtc1.control.hide();
        }
        if (this.nsm2.control !== null) {
            this.nsm2.control.hide();
        }
        if (this.remoteHelpImages.control !== null) {
            this.remoteHelpImages.control.hide();
        }
        if (this.versionText.control !== null) {
            this.versionText.control.hide();
        }
        
        this._instanceOptions.cmtype = eventData.cmtype;
        switch (eventData.cmtype) {
        case "VideoThumbnailCarousel":
            if (this.vtc1.control === null) {
                this.vtc1.control = $htv.ControlPool.getObject("VideoThumbnailCarousel");
                this.vtc1.control.initialize(this.vtc1.position, this.vtc1, $htv.Constants.Endpoints.menu + "/menu/" + $htv.Constants.MENU_PREFIX + "help_videos", eventData.options);
            }
            this.vtc1.control.show();
            this.horizonMiddle.control.show();
            this.horizonBottom.control.hide();
            this.nsm1.nav_info.down = {
                type: "control",
                node: this.vtc1
            };
            break;
        case "NonSlidingMenu":
            if (this.nsm2.control === null) {
                options.items = $htv.Utils.createGenericCollection([{
                    title: 'Navigation',
                    cmtype: 'ImageControl'
                }, {
                    title: 'Playback',
                    cmtype: 'ImageControl'
                }]);
                this.nsm2.control = $htv.ControlPool.getObject("NonSlidingMenu");
                this.nsm2.control.initialize(this.nsm2.position, this.nsm2, "not used", options);
            }
            this.nsm2.control.show();
            this.remoteHelpImages.control.show();
            this.horizonMiddle.control.hide();
            this.horizonBottom.control.show();
            this.nsm1.nav_info.down = {
                type: "control",
                node: this.nsm2
            };
            break;
        case "TextControl":
            if (this.versionText.control === null) {
                versionStr = "Name: " + $htv.Platform.properties.visible_friendly_name +
                    "\nPlatform: " + $htv.Platform.properties.distroplatform +
                    "\nVersion: " + $htv.Platform.properties.marketing_version +
                    "\nModel: " + $htv.Platform.properties.visible_model +
                    "\nDevice ID: " + $htv.Platform.properties.deviceid +
                    "\nTerms of Use: http://www.hulu.com/terms" +
                    "\nPrivacy Policy: http://www.hulu.com/privacy";
                if (!$htv.Utils.stringIsNullOrEmpty($htv.Constants.Endpoints.license_notice_url)) {
                    versionStr += "\nLicense Notices: " + $htv.Constants.Endpoints.license_notice_url;
                }
                this.versionText.control = $htv.ControlPool.getObject("TextControl");
                this.versionText.control.initialize(this.versionText.position, this.versionText, null, {
                    text: versionStr,
                    styleName: $htv.Styles.VersionText
                });
            }
            this.versionText.control.show();
            this.horizonMiddle.control.hide();
            this.horizonBottom.control.show();
            delete this.nsm1.nav_info.down;
            break;
        }
    };
       
    this._activatedItem = function (eventData) {
      
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "VIEW_DID_REAPPEAR":
            this._selectionChanged({cmtype: this._instanceOptions.cmtype});
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        default: 
            
            break;
        }
    };
    
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 217,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.horizonBottom = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 429,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.breadCrumb = {
        view: view,
        parent: null,
        type: "BreadCrumb",
        position: {
            x: 4,
            y: 9,
            z: 4,
            width: 700,
            height: 40
        },
        control: null
    };
    
    this.nsm1 = {
        view: view,
        type: "NonSlidingMenu",
        position: {
            x: 40,
            y: 47,
            z: 4,
            width: 700,
            height: 35
        },
        control: null
    };
    
    this.nsm2 = {
        view: view,
        type: "NonSlidingMenu",
        position: {
            x: 70,
            y: 82,
            z: 4,
            width: 860,
            height: 35
        },
        control: null
    };
    
    this.vtc1 = {
        view: view,
        type: "VideoThumbnailCarousel",
        siblings: [],
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null
    };
    
    this.remoteHelpImages = {
        view: view,
        type: "ImageControl",
        siblings: [],
        position: {
            x: 0,
            y: 101,
            z: 0,
            width: 960,
            height: 439
        },
        control: null
    };
    
    this.versionText = {
        view: view,
        type: "TextControl",
        siblings: [],
        position: {
            x: 90,
            y: 140,
            z: 0,
            width: 700,
            height: 320
        },
        control: null
    };
   
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 50,
            y: 475,
            z: 2,
            width: 93,
            height: 17
        },
        control: null
    };

    // attach nav_info
   
    
    this.nsm1.nav_info = {
        up: {
            type: "pop_view"
        },
        down: {
            type: "child_control"
        }
    };
    this.nsm2.nav_info = {
        up: {
            type: "control",
            node: this.nsm1
        }
    };
    this.vtc1.nav_info = {
        up: {
            type: "control",
            node: this.nsm1
        }
    };
    
    this._controls.push(this.topBar);
    this._controls.push(this.breadCrumb);
    this._controls.push(this.nsm1);
    this._controls.push(this.nsm2);
    this._controls.push(this.vtc1);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonMiddle);
    this._controls.push(this.horizonBottom);
    this._controls.push(this.remoteHelpImages);
    this._controls.push(this.versionText);
    this._controls.push(this.huluLogo);
    
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.HelpView.prototype = new $htv.Views.BaseView();

$htv.Views.LearnMoreView = function () {
    this.viewName = "LearnMoreView";
    this._overrideFirstSpotlightAnimation = true;
    
    this._initialize = function (options) {
        
        this._activeNode = this.sampleVideosButton;
        
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        
        this.marketingBackground.control = $htv.ControlPool.getObject("ImageControl");
        this.marketingBackground.control.initialize(this.marketingBackground.position, this.marketingBackground, $htv.Constants.Endpoints.mrkt_img, options);
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo.png", options);
        
        this.codeText.control = $htv.ControlPool.getObject("TextControl");
        this.codeText.control.initialize(this.codeText.position, this.codeText, null, {
            text: "",
            styleName: $htv.Styles.ReferralCode
        });

        this.sampleVideosButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.sampleVideosButton.control.initialize(this.sampleVideosButton.position, this.sampleVideosButton, null, {
            text: "View Sample Videos",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-preview-marketing-back.jpg",
            unfocused_image: "images/btn-preview-marketing-back.jpg",
            include_brackets: true
        });
        
        this.alreadySubscribedButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.alreadySubscribedButton.control.initialize(this.alreadySubscribedButton.position, this.alreadySubscribedButton, null, {
            text: "Already a Subscriber",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-preview-marketing-back.jpg",
            unfocused_image: "images/btn-preview-marketing-back.jpg",
            include_brackets: true
        });
        
        this.sampleVideosButton.control.focus();
        $htv.Profile.getAuthenticationCode(this, this.onCodeLoaded); 
    };
    
    this.onCodeLoaded = function (result) {
        if (result.success) {
            this.authenticationCode = result.code;

            if (this.codeText.control !== null) {
                this.codeText.control.setText("Referral Code:   " + this.authenticationCode);
            }
            $htv.Profile.enableAuthenticationPolling();
        }
    };
    
    this._handleButtonActivated = function (eventData) {
        switch (eventData.target) {
        case this.sampleVideosButton:
            $htv.Controller.pushView("SampleVideosView", {});
            break;
        case this.alreadySubscribedButton:
            $htv.Controller.pushView("ActivationView", {});
            break;
        default:
            break;
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "RETURN_KEY_PRESSED":
            $htv.Controller.popView();
            break;
        case "BUTTON_ACTIVATED":
            this._handleButtonActivated(eventData);
            break;
        case "VIEW_WILL_DISAPPEAR":
            $htv.Profile.disableAuthenticationPolling();
            break;
        case "VIEW_DID_REAPPEAR":
            $htv.Profile.enableAuthenticationPolling();
            break;
        default: 
            
            break;
        }
    };
    
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 54,
            y: 26,
            z: 3,
            width: 200,
            height: 34
        },
        control: null
    };
    
    this.codeText = {
        view: view,
        type: "TextControl",
        position: {
            x: 390,
            y: 415,
            z: 2,
            width: 680,
            height: 30
        },
        control: null
    };
    
    this.marketingBackground = {
        view: view,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 0,
            width: 960,
            height: 440
        },
        control: null
    };
    
    this.sampleVideosButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 260,
            y: 457,
            z: 1,
            width: 186,
            height: 29
        },
        control: null
    };
    
    this.alreadySubscribedButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 514,
            y: 457,
            z: 1,
            width: 186,
            height: 29
        },
        control: null
    };

    // attach nav_info
    
    this.sampleVideosButton.nav_info = {
        right: {
            type: "control",
            node: this.alreadySubscribedButton
        }
    };
    this.alreadySubscribedButton.nav_info = {
        left: {
            type: "control",
            node: this.sampleVideosButton
        }
    };
    
    this._controls.push(this.topBar);
    this._controls.push(this.huluLogo);
    this._controls.push(this.codeText);
    this._controls.push(this.marketingBackground);
    this._controls.push(this.sampleVideosButton);
    this._controls.push(this.alreadySubscribedButton);
    
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.LearnMoreView.prototype = new $htv.Views.BaseView();

$htv.Views.LoadingView = function () {
    this.viewName = "LoadingView";
    
    this._initialize = function (options) {
        
        this.loadingImage.control = $htv.ControlPool.getObject("ImageControl");
        this.loadingImage.control.initialize(this.loadingImage.position, this.loadingImage, "images/loading-back.png", options);
        this.loadingIndicator.control = $htv.ControlPool.getObject("LoadingIndicator");
        this.loadingIndicator.control.initialize(this.loadingIndicator.position, this.loadingIndicator, null, options);
        this._activeNode = this.loadingImage.control;
    };
    
    this._handleEvent = function (eventName, eventData) {
        
    };
    
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.loadingImage = {
        view: view,
        type: "ImageControl",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this.loadingIndicator = {
        view: view,
        type: "LoadingIndicator",
        position: {
            x: 410,
            y: 290,
            z: 1,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this._controls.push(this.loadingImage);
    this._controls.push(this.loadingIndicator);
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.LoadingView.prototype = new $htv.Views.BaseView();

$htv.Views.LoginView = function () {
    this.viewName = "LoginView";
    this._overrideFirstSpotlightAnimation = true;
    this.activeInput = null;
    
    this._initialize = function (options) {
        
        this._activeNode = this.keyboard;
        
        this.backgroundImage.control = $htv.ControlPool.getObject("ImageControl");
        this.backgroundImage.control.initialize(this.backgroundImage.position, this.backgroundImage, "images/login-dialog-background.png", options);
        this.titleText.control = $htv.ControlPool.getObject("TextControl");
        this.titleText.control.initialize(this.titleText.position, this.titleText, null, {
            text: "Log in to Hulu Plus",
            styleName: $htv.Styles.LoginViewTitle
        });
        this.emailLabel.control = $htv.ControlPool.getObject("TextControl");
        this.emailLabel.control.initialize(this.emailLabel.position, this.emailLabel, null, {
            text: "Email address",
            styleName: $htv.Styles.LoginFieldLabel
        });
        this.passwordLabel.control = $htv.ControlPool.getObject("TextControl");
        this.passwordLabel.control.initialize(this.passwordLabel.position, this.passwordLabel, null, {
            text: "Password",
            styleName: $htv.Styles.LoginFieldLabel
        });
        this.emailInput.control = $htv.ControlPool.getObject("TextInput");
        this.emailInput.control.initialize(this.emailInput.position, this.emailInput, null, {
            focused_image: "images/login-text-input-focused.png",
            unfocused_image: "images/login-text-input-unfocused.png",
            unfocused_selected_image: "images/login-text-input-unfocused-selected.png",
            styleName: $htv.Styles.LoginFieldLabel,
            label_offset_x: 4,
            label_offset_y: 6
        });
        this.emailInput.control.setActive(true);
        this.passwordInput.control = $htv.ControlPool.getObject("TextInput");
        this.passwordInput.control.initialize(this.passwordInput.position, this.passwordInput, null, {
            focused_image: "images/login-text-input-focused.png",
            unfocused_image: "images/login-text-input-unfocused.png",
            unfocused_selected_image: "images/login-text-input-unfocused-selected.png",
            mask_text: true,
            styleName: $htv.Styles.LoginFieldLabel,
            label_offset_x: 4,
            label_offset_y: 6
        });
        this.passwordInput.control.setActive(false);
        this.keyboard.control = $htv.ControlPool.getObject("Keyboard");
        this.keyboard.control.initialize(this.keyboard.position, this.keyboard, null, {login_setup: "email", can_wrap: true});
        this.loginFailedText.control = $htv.ControlPool.getObject("TextControl");
        this.loginFailedText.control.initialize(this.loginFailedText.position, this.loginFailedText, null, {
            text: "Login failed.  Please try again.",
            styleName: $htv.Styles.LoginFailedLabel
        });
        this.loginFailedText.control.hide();
        this.submitButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.submitButton.control.initialize(this.submitButton.position, this.submitButton, null, {
            text: "Next",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-sample-learn.png",
            unfocused_image: "images/btn-sample-learn.png",
            include_brackets: true
        });
        this.cancelButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.cancelButton.control.initialize(this.cancelButton.position, this.cancelButton, null, {
            text: "Cancel",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-sample-learn.png",
            unfocused_image: "images/btn-sample-learn.png",
            include_brackets: true
        });

        this.keyboard.nav_info.down.node = this.submitButton;
        this.cancelButton.nav_info.left.node = this.submitButton;
        this._switchActiveTextInput(this.emailInput);
        this.keyboard.control.focus();
    };
    
    this._handleButtonActivated = function (eventData) {
        switch (eventData.target) {
        case this.submitButton:
            if (this.activeInput === this.passwordInput) { 
                this._navigateBetweenControls({ nav_dir: "up" });
                this.keyboard.control.reset();
                this.keyboard.nav_info.down.node = this.cancelButton;
                this.cancelButton.nav_info.left.node = this.cancelButton;
                this.submitButton.control.setText("Waiting");
                this._login();
            }
            else {
                this._switchActiveTextInput(this.passwordInput);
                this._navigateBetweenControls({ nav_dir: "up" });
                this.keyboard.control.reset();
            }
            break;
        case this.cancelButton:
            $htv.Controller.popView();
            break;
        default:
            break;
        }
    };
    
    this._login = function () {
        // TODO: show activity/loading indicator
        // TODO: provide error callback
        $htv.Profile.login(this.emailInput.control.getText(), this.passwordInput.control.getText(),
            this, this._loginComplete, this._loginFailure, {});
    };
    
    this._loginComplete = function () {
        if (this.keyboard.control === null) {
            return;
        }
        
        if ($htv.Profile.isPlusUser()) {
            if ($htv.Profile.accountOnHold()) {
                $htv.Controller.showAccountOnHoldDialog();
            } else {
                $htv.Controller.popAllAndPushView("MainView", {});
            }
        } else {
            var items = [{
                text: "More Info",
                callback: function () {
                    $htv.Controller.popAllAndPushView("LearnMoreView", {});
                },
                receiver: this
            }, {
                text: "Try Again",
                callback: function () {
                    $htv.Controller.pushView("LoginView", {});
                },
                receiver: this
            }];
            
            $htv.Controller.popView();
            $htv.Controller.pushView("DialogBoxView", {
                text: "Sorry, this platform is only available for Hulu Plus subscribers.",
                items: items,
                textXPadding: 90,
                textWidth: 380
            });
        }
    };

    this._loginFailure = function () {
        if (this.keyboard.control === null) {
            return;
        }        
        
        this.passwordInput.control.setText("");
        this.loginFailedText.control.show();
        this.submitButton.control.setText("Login");
        this.keyboard.nav_info.down.node = this.submitButton;
        this.cancelButton.nav_info.left.node = this.submitButton;
    };
    
    this._switchActiveTextInput = function (target) {
        if (target === this.passwordInput) {
            this.submitButton.control.setText("Login");
            this.activeInput = this.passwordInput;
            this.emailInput.control.setActive(false);
            this.keyboard.control.setOptions({login_setup : "password"});
        }
        if (target === this.emailInput) {
            this.submitButton.control.setText("Next");            
            this.activeInput = this.emailInput;
            this.passwordInput.control.setActive(false);
            this.keyboard.control.setOptions({login_setup : "email"});
        }
        if (target === this.emailInput || target === this.passwordInput) {
            this.keyboard.nav_info.up.node = this.activeInput;
            this.activeInput.control.setActive(true);
        }
    };

    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            
            // If input was from a keyboard, navigate to the active input
            if ((eventData.action === "KEYBOARD" || eventData.action === "BACKSPACE") &&
                this._activeNode === this.keyboard &&
                this.activeInput !== null) {
                this._navigateToControl(this.activeInput);
            }
            
            this._activeNode.control.handleEvent(eventName, eventData);
            this._switchActiveTextInput(this._activeNode);
            break;
        case "RETURN_KEY_PRESSED": 
            $htv.Controller.popView();            
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "BUTTON_ACTIVATED":
            this._handleButtonActivated(eventData);
            break;
        case "KEYBOARD_INPUT":
            if (eventData.type === "SUBMIT") {
                this._handleButtonActivated({target: this.submitButton});
                // bring the control back down, after it focused the other textinput
                this._navigateBetweenControls({ nav_dir: "down" });
            } else if (eventData.type === "TAB") {
                if (this.activeInput === this.emailInput) {
                    this._switchActiveTextInput(this.passwordInput);
                    this._navigateToControl(this.passwordInput);
                } else if (this.activeInput === this.passwordInput) {
                    this._switchActiveTextInput(this.emailInput);
                    this._navigateToControl(this.emailInput);
                }
            } else {
                this.activeInput.control.handleKeyboardInput(eventData);
            }
            break;
        case "TEXT_INPUT_CHANGED":
            this.loginFailedText.control.hide();
            break;
        case "VIEW_DID_REAPPEAR":
            this.loginFailedText.control.hide();
            this._switchActiveTextInput(this.activeInput); 
            break;
        case "TEXT_INPUT_ACTIVATED":
            // If the active input is empty, navigate down to the keyboard
            if (!this.activeInput ||
                !this.activeInput.control ||
                $htv.Utils.stringIsNullOrEmpty(this.activeInput.control.getText())) {
                this._navigateBetweenControls({ nav_dir: "down" });
            // If email is selected, advance to password
            } else if (this._activeNode === this.emailInput) {
                this._switchActiveTextInput(this.passwordInput);
                this._navigateToControl(this.passwordInput);
            // If password is selected, submit login
            } else if (this._activeNode === this.passwordInput) {
                this._handleButtonActivated({target: this.submitButton});
                // bring the control back down, after it focused the other textinput
                this._navigateBetweenControls({ nav_dir: "down" });
            }
            break;
        default: 
            
            break;
        }
    };
    
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.backgroundImage = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this.titleText = {
        view: view,
        type: "TextControl",
        position: {
            x: 0,
            y: 85,
            z: 1,
            width: 960,
            height: 60
        },
        control: null
    };
   
    this.emailLabel = {
        view: view,
        type: "TextControl",
        position: {
            x: 94,
            y: 142,
            z: 2,
            width: 400,
            height: 60
        },
        control: null
    };
    
    this.passwordLabel = {
        view: view,
        type: "TextControl",
        position: {
            x: 497,
            y: 142,
            z: 2,
            width: 400,
            height: 60
        },
        control: null
    };
    
    this.emailInput = {
        view: view,
        type: "TextInput",
        position: {
            x: 94 - 25,
            y: 170 - 23,
            z: 1,
            width: 413,
            height: 81
        },
        control: null
    };
    
    this.passwordInput = {
        view: view,
        type: "TextInput",
        position: {
            x: 497 - 25,
            y: 170 - 23,
            z: 1,
            width: 413,
            height: 81
        },
        control: null
    };
    
    this.keyboard = {
        view: view,
        type: "Keyboard",
        position: {
            x: 269,
            y: 230,
            z: 3,
            width: 960,
            height: 150
        },
        control: null
    };
    
    this.submitButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 354,
            y: 430,
            z: 1,
            width: 90,
            height: 29
        },
        control: null
    };
 
    this.cancelButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 514,
            y: 430,
            z: 1,
            width: 90,
            height: 29
        },
        control: null
    };

    this.loginFailedText = {
        view: view,
        type: "TextControl",
        position: {
            x: 0,
            y: 117,
            z: 1,
            width: 960,
            height: 60
        },
        control: null
    };

    // attach nav_info
    
    this.emailInput.nav_info = {
        down: {
            type: "control",
            node: this.keyboard
        },
        right: {
            type: "control",
            node: this.passwordInput
        }
    };
    this.passwordInput.nav_info = {
        down: {
            type: "control",
            node: this.keyboard
        },
        left: {
            type: "control",
            node: this.emailInput
        }
    };
    this.keyboard.nav_info = {
        up: {
            type: "control",
            node: this.emailInput
        },
        down: {
            type: "control",
            node: this.submitButton
        }
    };
    this.submitButton.nav_info = {
        up: {
            type: "control",
            node: this.keyboard
        },
        right: {
            type: "control",
            node: this.cancelButton
        }
    };
    this.cancelButton.nav_info = {
        up: {
            type: "control",
            node: this.keyboard
        },
        left: {
            type: "control",
            node: this.submitButton
        }
    };
    
    this._controls.push(this.backgroundImage);
    this._controls.push(this.submitButton);
    this._controls.push(this.cancelButton);
    this._controls.push(this.titleText);
    this._controls.push(this.emailLabel);
    this._controls.push(this.passwordLabel);
    this._controls.push(this.emailInput);
    this._controls.push(this.passwordInput);
    this._controls.push(this.keyboard);
    this._controls.push(this.loginFailedText);
    
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.LoginView.prototype = new $htv.Views.BaseView();

$htv.Views.RequestInviteView = function () {
    this.viewName = "RequestInviteView";
    this._overrideFirstSpotlightAnimation = true;
    
    this._initialize = function (options) {
        
        this._activeNode = this.keyboard;
        
        var inviteUrl = "www.hulu.com/invite";
        if (!$htv.Utils.stringIsNullOrEmpty($htv.Constants.Endpoints.requestInviteURL)) {
            inviteUrl = $htv.Constants.Endpoints.requestInviteURL;
        }
        inviteUrl = inviteUrl.replace("http://", ""); // make user friendlier
        
        this.backgroundImage.control = $htv.ControlPool.getObject("ImageControl");
        this.backgroundImage.control.initialize(this.backgroundImage.position, this.backgroundImage, "images/login-dialog-background.png", options);
        this.barImage.control = $htv.ControlPool.getObject("ImageControl");
        this.barImage.control.initialize(this.barImage.position, this.barImage, "images/request-invite-bar.png", options);
        this.titleText.control = $htv.ControlPool.getObject("TextControl");
        this.titleText.control.initialize(this.titleText.position, this.titleText, null, {
            text: "Request your invite",
            styleName: $htv.Styles.RequestInviteTitle
        });
        this.boldText1.control = $htv.ControlPool.getObject("TextControl");
        this.boldText1.control.initialize(this.boldText1.position, this.boldText1, null, {
            text: "OR",
            styleName: $htv.Styles.RequestInviteTitle
        });
        this.boldText2.control = $htv.ControlPool.getObject("TextControl");
        this.boldText2.control.initialize(this.boldText2.position, this.boldText2, null, {
            text: inviteUrl,
            styleName: $htv.Styles.RequestInviteBold
        });
        this.normalText1.control = $htv.ControlPool.getObject("TextControl");
        this.normalText1.control.initialize(this.normalText1.position, this.normalText1, null, {
            text: "From your computer go to:",
            styleName: $htv.Styles.RequestInviteText
        });
        this.normalText2.control = $htv.ControlPool.getObject("TextControl");
        this.normalText2.control.initialize(this.normalText2.position, this.normalText2, null, {
            text: "and enter your\nreferral code:",
            styleName: $htv.Styles.RequestInviteText
        });
        this.referralCode.control = $htv.ControlPool.getObject("TextControl");
        this.referralCode.control.initialize(this.referralCode.position, this.referralCode, null, {
            text:  "(loading...)",
            styleName: $htv.Styles.RequestInviteTitle
        });
        this.emailLabel.control = $htv.ControlPool.getObject("TextControl");
        this.emailLabel.control.initialize(this.emailLabel.position, this.emailLabel, null, {
            text: "Email address:",
            styleName: $htv.Styles.RequestInviteLabel
        });
        this.emailInput.control = $htv.ControlPool.getObject("TextInput");
        this.emailInput.control.initialize(this.emailInput.position, this.emailInput, null, {
            focused_image: "images/request-text-input-focused.png",
            unfocused_image: "images/request-text-input-unfocused.png",
            unfocused_selected_image: "images/request-text-input-unfocused-selected.png",
            label_offset_x: 8,
            label_offset_y: 6
        });
        this.emailInput.control.setActive(true);
        this.keyboard.control = $htv.ControlPool.getObject("Keyboard");
        this.keyboard.control.initialize(this.keyboard.position, this.keyboard, null, {login_setup: "email", can_wrap: true});
        this.submitButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.submitButton.control.initialize(this.submitButton.position, this.submitButton, null, {
            text: "Submit",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-sample-learn.png",
            unfocused_image: "images/btn-sample-learn.png",
            include_brackets: true
        });
        this.closeButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.closeButton.control.initialize(this.closeButton.position, this.closeButton, null, {
            text: "Close",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-sample-learn.png",
            unfocused_image: "images/btn-sample-learn.png",
            include_brackets: true
        });
        
        this.keyboard.control.focus();

        //resets the nav info incase view is reused
        this.keyboard.nav_info.down.node = this.submitButton;
        this.closeButton.nav_info.left.node = this.submitButton;
        $htv.Profile.getAuthenticationCode(this, this.onCodeLoaded);
    };

    this.onCodeLoaded = function (result) {
        if (result.success) {
            this.authenticationCode = result.code;

            if (this.referralCode.control !== null) {
                this.referralCode.control.setText(this.authenticationCode);
            }
            
            $htv.Profile.enableAuthenticationPolling();
        }
    };
    
    this._handleButtonActivated = function (eventData) {
        switch (eventData.target) {
        case this.submitButton:
            if ($htv.Utils.stringIsNullOrEmpty($htv.Platform.properties.request_invite_legalese)) {
                this._makeInviteRequest();
            }
            else {
                $htv.Controller.pushView("DialogBoxView", {
                    text: $htv.Platform.properties.request_invite_legalese,
                    textStyle: $htv.Styles.DialogBoxMessageSmaller,
                    textWidth: 510,
                    textXPadding: 20,
                    buttonYInitial: 330,
                    horizontalButtons: true,
                    items: [{
                        text: "I Accept",
                        callback: this._makeInviteRequest,
                        receiver: this
                    }, {
                        text: "Cancel",
                        callback: function () {
                            
                        },
                        receiver: this
                    }]
                });
            }
            break;
        case this.closeButton:
            $htv.Controller.popView();
            break;
        default:
            break;
        }
    };
    
    this._makeInviteRequest = function () {
        
        $htv.Profile.makeInviteRequest(this, this._onInviteRequestResponse,
                this.authenticationCode, this.emailInput.control.getText(), {});
        this.submitButton.control.setText("Waiting");
        
        this._navigateBetweenControls({ nav_dir: "up" });
        this.keyboard.control.reset();
        this.keyboard.nav_info.down.node = this.closeButton;
        this.closeButton.nav_info.left.node = this.closeButton;
    };

    this._onInviteRequestResponse = function (result) {
        var items;
        if (this.keyboard.control === null) {
            return;
        }

        if (result) {               
            items = [{
                text: "OK",
                callback: function () {
                    $htv.Controller.popView();
                },
                receiver: this
            }];
            
            this.submitButton.control.setText("Submit");
            this.keyboard.nav_info.down.node = this.submitButton;
            this.closeButton.nav_info.left.node = this.submitButton;
            
            $htv.Controller.pushView("DialogBoxView", {
                text: "Thanks for your invite request.  We'll send you\nan invite as soon as one becomes available.\nThanks for your patience.",
                items: items
            });           
        } else {
            items = [{
                text: "OK",
                callback: function () {
                    $htv.Controller.popView();
                },
                receiver: this
            }];
            
            this.submitButton.control.setText("Submit");
            this.keyboard.nav_info.down.node = this.submitButton;
            this.closeButton.nav_info.left.node = this.submitButton;
            
            $htv.Controller.pushView("DialogBoxView", {
                text: "We're sorry, your invite request cannot be processed at this time.  Please try again later.",
                textYPadding: 20,
                textXPadding: 35,
                textWidth: 490,
                items: items
            });   
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "RETURN_KEY_PRESSED": 
            $htv.Controller.popView();
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "BUTTON_ACTIVATED":
            this._handleButtonActivated(eventData);
            break;
        case "KEYBOARD_INPUT":
            if (eventData.type === "SUBMIT") {
                this._handleButtonActivated({target: this.submitButton});
            } else {
                this.emailInput.control.handleKeyboardInput(eventData);
            }
            break;
        case "TEXT_INPUT_CHANGED":
            // Do nothing
            break;
        case "TEXT_INPUT_ACTIVATED":
            this._navigateBetweenControls({ nav_dir: "down" });
            break;
        case "VIEW_WILL_DISAPPEAR":
            $htv.Profile.disableAuthenticationPolling();
            break;
        case "VIEW_DID_REAPPEAR":
            $htv.Profile.enableAuthenticationPolling();
            break;
        default: 
            
            break;
        }
    };
    
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.backgroundImage = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this.barImage = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 566,
            y: 136,
            z: 1,
            width: 2,
            height: 332
        },
        control: null
    };
    
    this.titleText = {
        view: view,
        type: "TextControl",
        position: {
            x: 0,
            y: 75,
            z: 1,
            width: 960,
            height: 60
        },
        control: null
    };
   
    this.emailLabel = {
        view: view,
        type: "TextControl",
        position: {
            x: 93,
            y: 133,
            z: 2,
            width: 400,
            height: 60
        },
        control: null
    };

    this.boldText1 = {
        view: view,
        type: "TextControl",
        position: {
            x: 568,
            y: 169,
            z: 2,
            width: 339,
            height: 90
        },        
        control: null
    };

    this.boldText2 = {
        view: view,
        type: "TextControl",
        position: {
            x: 568,
            y: 237,
            z: 2,
            width: 339,
            height: 90
        },        
        control: null
    };

    this.normalText1 = {
        view: view,
        type: "TextControl",
        position: {
            x: 568,
            y: 218,
            z: 2,
            width: 339,
            height: 60
        },
        control: null
    };

    this.normalText2 = {
        view: view,
        type: "TextControl",
        position: {
            x: 568,
            y: 287,
            z: 2,
            width: 339,
            height: 60
        },
        control: null
    };

    this.referralCode = {
        view: view,
        type: "TextControl",
        position: {
            x: 640,
            y: 335,
            z: 2,
            width: 200,
            height: 35
        },
        control: null
    };
            
    this.emailInput = {
        view: view,
        type: "TextInput",
        position: {
            x: 65,
            y: 142,
            z: 1,
            width: 474,
            height: 81
        },
        control: null
    };
    
    this.keyboard = {
        view: view,
        type: "Keyboard",
        position: {
            x: 93,
            y: 224,
            z: 3,
            width: 960,
            height: 150
        },
        control: null
    };
    
    this.submitButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 258,
            y: 434,
            z: 1,
            width: 90,
            height: 29
        },
        control: null
    };

    this.closeButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 695,
            y: 430,
            z: 1,
            width: 90,
            height: 29
        },
        control: null
    };
 
    // attach nav_info
    
    this.emailInput.nav_info = {
        down: {
            type: "control",
            node: this.keyboard
        },
        right: {
            type: "control",
            node: this.closeButton
        }
    };
    this.keyboard.nav_info = {
        up: {
            type: "control",
            node: this.emailInput
        },
        down: {
            type: "control",
            node: this.submitButton
        }
    };
    this.submitButton.nav_info = {
        up: {
            type: "control",
            node: this.keyboard
        },
        right: {
            type: "control",
            node: this.closeButton
        }
    };
    this.closeButton.nav_info = {
        left: {
            type: "control",
            node: this.submitButton
        },
        up : {
            type: "control",
            node: this.keyboard
        } 
    };

    this._controls.push(this.backgroundImage);
    this._controls.push(this.barImage);
    this._controls.push(this.submitButton);
    this._controls.push(this.closeButton);
    this._controls.push(this.titleText);
    this._controls.push(this.boldText1);
    this._controls.push(this.boldText2);
    this._controls.push(this.normalText1);
    this._controls.push(this.normalText2);
    this._controls.push(this.referralCode);
    this._controls.push(this.emailLabel);
    this._controls.push(this.emailInput);
    this._controls.push(this.keyboard);
    
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.RequestInviteView.prototype = new $htv.Views.BaseView();

$htv.Views.MainView = function () {
    var newRoot, view;
    this.viewName = "MainView";
    
    this._initialize = function (options) {
        var userName, welcomeStr;
        this._platformCanvasHandle = options.canvas;
        this._loadChild("", "MainView", this._root);
        this._loadChild("/menu/" + $htv.Constants.MENU_PREFIX + "main_menu", "SlidingMenu", this._root.children.MainView, {show_down_arrow: true, indexHint: 4});
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-home.png", options);
        
        // TODO: use ContainerControl if/when we implement one; faster than getTextDimensions()
        userName = $htv.Profile.getFirstName();
        welcomeStr = ($htv.Utils.stringIsNullOrEmpty(userName) ? "" : "Welcome " + userName);
        this.welcomeText.control = $htv.ControlPool.getObject("TextControl");
        this.welcomeText.control.initialize(this.welcomeText.position, this.welcomeText, "null", {text: welcomeStr, styleName: $htv.Styles.WelcomeText});

        this.logoutButton.position.x = this.welcomeText.position.x + this.welcomeText.control.getTextDimensions().textWidth + 50;        
        this.logoutButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.logoutButton.control.initialize(this.logoutButton.position, this.logoutButton, "null", {
            text: "log out",
            focused_style: $htv.Styles.WelcomeLogoutFocused,
            unfocused_style: $htv.Styles.WelcomeLogoutUnfocused,
            include_brackets: true
        });
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-focused.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-center-focused.png", options);
        this._activeNode = this._root.children.MainView;
        this.initializationState = 0;
        this.resumeDetails = null;
        this._activeNode.control.focus();
    };
   
    this._activatedItem = function (eventData) {
        if (eventData.target === this._root.children.MainView.children.SlidingMenu) {
            $htv.Controller.pushView(eventData.item.view_name, {
                menu_url: eventData.item.items_url,
                view_title: eventData.item.title,
                login_required: eventData.item.login_required
            });
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS":
            if (this._activeNode === newRoot.children.MainView.children.SlidingMenu) {
                eventData.view_name = eventData.item.view_name;
                eventData.options = {
                    menu_url: eventData.item.items_url,
                    view_title: eventData.item.title,
                    login_required: eventData.item.login_required
                };
            }
            this._navigateBetweenControls(eventData);
            if (this.horizonMiddle.control !== null) {
                if (this._activeNode === newRoot.children.MainView) {
                    this.horizonTop.control.setSource("images/horizon-top-focused.png");
                    this.horizonMiddle.control.setSource("images/horizon-center-focused.png");
                }
                else {
                    this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
                    this.horizonMiddle.control.setSource("images/horizon-center-unfocused.png");
                }
            }
            break;
        case "MENU_ITEM_ACTIVATED":
            this._activatedItem(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            this.initializationState++;
            if (this.initializationState === 2) {
                
                $htv.Controller.fireEvent("MAIN_VIEW_INITIALIZE_COMPLETE", {});
                if (this.resumeDetails !== null) {
                    $htv.Controller.pushView("ResumeLastVideoView", this.resumeDetails);
                    this.resumeDetails = null;
                }
            }
            break;
        case "BUTTON_ACTIVATED":
            if (eventData.target === this.logoutButton) {
                var items = [{
                    text: "Yes",
                    callback: function () {
                        
                        $htv.Profile.logout();
                        $htv.Controller.popAllAndPushView("ActivationView", {});
                    },
                    receiver: this
                }, {
                    text: "No",
                    callback: function () {
                        
                    },
                    receiver: this
                }];
                
                $htv.Controller.pushView("DialogBoxView", {
                    text: "Are you sure you want to log out?",
                    items: items
                });
            }
            break;
        case "RETURN_KEY_PRESSED":
            if ($htv.Platform.properties.has_in_app_exit === false) {
                return;
            }
            $htv.Controller.showExitDialog();
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        case "STARTUP_SHOULD_RESUME":
            
            if (this.initializationState === 2) {                
                $htv.Controller.pushView("ResumeLastVideoView", eventData);
                this.resumeDetails = null;
            }
            else {
                this.resumeDetails = eventData;
            }
            break;
        default: 
            
            break;
        }
    };

    
    view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 48,
            y: 32,
            z: 2,
            width: 121,
            height: 23
        },
        control: null
    };
    
    this.welcomeText = {
        view: view,
        type: "TextControl",
        position: {
            x: 200,
            y: 40,
            z: 3,
            width: 920,
            height: 30
        },
        control: null
    };
    
    this.logoutButton = {
        view: view,
        type: "ButtonControl",
        position: {
            // NOTE: x position is updated by length of welcomeText
            x: 330,
            y: 40,
            z: 3,
            width: 45,
            height: 14
        },
        control: null
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 217,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    newRoot = {
        view: view,
        parent: null,
        type: "None",
        position: {
            x: 0,
            y: 0,
            width: 0,
            height: 0
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            MainView: null
        }
    };
    
    newRoot.children.MainView = {//1
        view: view,
        parent: newRoot,
        type: "Masthead",
        position: {
            x: 0,
            y: 127,
            z: 3,
            width: 960,
            height: 400
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SlidingMenu: null
        }
    };
    
    newRoot.children.MainView.children.SlidingMenu = {//1
        view: view,
        parent: newRoot.children.MainView,
        type: "SlidingMenu",
        position: {
            x: 15,
            y: 465,
            z: 4,
            width: 930,
            height: 40
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {}
    };
    
    // attach nav_info
    
    this.logoutButton.nav_info = {
        down: {
            type: "control",
            node: newRoot.children.MainView
        }
    };
    newRoot.children.MainView.nav_info = {
        up: {
            type: "control",
            node: this.logoutButton
        },
        down: {
            type: "control",
            node: newRoot.children.MainView.children.SlidingMenu
        }
    };
    newRoot.children.MainView.children.SlidingMenu.nav_info = {
        up: {
            type: "control",
            node: newRoot.children.MainView
        },
        down: {
            type: "push_view"
        }
    };
    
    this._controls.push(this.topBar);
    this._controls.push(this.huluLogo);
    this._controls.push(this.welcomeText);
    this._controls.push(this.logoutButton);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonMiddle);
    this._controls.push(newRoot);
    this._controls.push(newRoot.children.MainView);
    this._controls.push(newRoot.children.MainView.children.SlidingMenu);

    this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.MainView.prototype = new $htv.Views.BaseView();

 
$htv.Views.ResumeLastVideoView = function () {
    this.viewName = "ResumeLastVideoView";
    this.content_id = null;
    this._overrideFirstSpotlightAnimation = true;
    
    this._initialize = function (options) {
        
        

        this.content_id = options.content_id;
        
        this.background.control = $htv.ControlPool.getObject("ImageControl");
        this.background.control.initialize(this.background.position, this.background, "images/medium-dialog-background.png", options);
        
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-home.png", options);
        
        this.resumeDetails.control = $htv.ControlPool.getObject("ResumeDetails");
        this.resumeDetails.control.initialize(this.resumeDetails.position, this.resumeDetails, "null", options);
        
        this.message.control = $htv.ControlPool.getObject("TextControl");
        this.message.control.initialize(this.message.position, this.message, null, { text: "You have a video that you had already started watching.\nWould you like to resume it from where you left off?", styleName: $htv.Styles.ResumeDialogBoxMessage });

        this.resumeButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.resumeButton.control.initialize(this.resumeButton.position, this.resumeButton, null, {
                text: "Resume Video",
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                focused_image: "images/btn-preview-marketing-back.jpg",
                unfocused_image: "images/btn-preview-marketing-back.jpg",
                include_brackets: true
            });
        
        this.cancelButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.cancelButton.control.initialize(this.cancelButton.position, this.cancelButton, null, {
                text: "Cancel",
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                focused_image: "images/btn-preview-marketing-back.jpg",
                unfocused_image: "images/btn-preview-marketing-back.jpg",
                include_brackets: true
            });
        
        this._activeNode = this.resumeButton;
        this._activeNode.control.focus();
    };

    this._handleButtonActivated = function (eventData) {
        switch (eventData.target) {
        case this.resumeButton:
            $htv.Controller.popView();
            $htv.Controller.playVideo(this.content_id, {});
            break;
        case this.cancelButton:
            $htv.Profile.dismissResume(this.content_id);
            $htv.Controller.popView();
            break;
        default:
            break;
        }
    };

    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "RETURN_KEY_PRESSED":
            this._handleButtonActivated({target: this.cancelButton});
            break;
        case "EXIT_KEY_PRESSED":
            $htv.Controller.popView();
            $htv.Controller.showExitDialog();
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "BUTTON_ACTIVATED":
            this._handleButtonActivated(eventData);
            break;
        default: 
            
            break;
        }
    };
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.background = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 0,
            z: 5,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 220,
            y: 125,
            z: 2,
            width: 121,
            height: 23
        },
        control: null
    };
    
    this.message = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 220,
            y: 175,
            z: 2,
            width: 520,
            height: 120
        },
        control: null
    };
    
    this.resumeDetails = {
        view: view,
        type: "ResumeDetails",
        position: {
            x: 220,
            y: 255,
            z: 2,
            width: 520,
            height: 100
        },
        control: null
    };
    
    this.resumeButton = {
        view: view,
        parent: null,
        type: "ButtonControl",
        position: {
            x: 269,
            y: 383,
            z: 2,
            width: 186,
            height: 29
        },
        control: null
    };
    
    this.cancelButton = {
        view: view,
        parent: null,
        type: "ButtonControl",
        position: {
            x: 505,
            y: 383,
            z: 2,
            width: 186,
            height: 29
        },
        control: null
    };
    
    // attach nav_info
    
    this.resumeButton.nav_info = {
        right: {
            type: "control",
            node: this.cancelButton
        }
    };
    
    this.cancelButton.nav_info = {
        left: {
            type: "control",
            node: this.resumeButton
        }
    };
    
    this._controls.push(this.background);
    this._controls.push(this.huluLogo);
    this._controls.push(this.message);
    this._controls.push(this.resumeDetails);
    this._controls.push(this.resumeButton);
    this._controls.push(this.cancelButton);
    
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.ResumeLastVideoView.prototype = new $htv.Views.BaseView();

$htv.Views.SampleVideosView = function () {
    this.viewName = "SampleVideosView";
    this._overrideFirstSpotlightAnimation = true;
    
    this._initialize = function (options) {
        
        this._activeNode = this.carousel;
        
        this.backgroundImage.control = $htv.ControlPool.getObject("ImageControl");
        this.backgroundImage.control.initialize(this.backgroundImage.position, this.backgroundImage, "images/login-dialog-background.png", options);
        
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-unfocused.png", options);
        this.horizonBottom.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonBottom.control.initialize(this.horizonBottom.position, this.horizonBottom, "images/horizon-center-unfocused.png", options);



        this.carousel.control = $htv.ControlPool.getObject("VideoThumbnailCarousel");
        this.carousel.control.initialize(this.carousel.position, 
            // Replace Twinkie menu once sample videos are chosen
            this.carousel, $htv.Constants.Endpoints.menu + "/menu/" + $htv.Constants.MENU_PREFIX + "sample_videos",
            { carousel_name: "Hulu Plus Sample Videos", include_show_title: true,
            // Package_id 3 here for classic/front porch
              disable_down_override: true, package_id: 3,
            // Don't show expiration notices
              hide_expiration: true });

        this.sampleText.control = $htv.ControlPool.getObject("TextControl");
        this.sampleText.control.initialize(this.sampleText.position, this.sampleText, "null", {text: "Hulu Plus Sample Videos", styleName: $htv.Styles.SampleVideosHeader});
        
        this.exitButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.exitButton.control.initialize(this.exitButton.position, 
            this.exitButton, null, {
            text: "Exit sample videos",
            focused_style: $htv.Styles.ActivationButtonFocused,
            unfocused_style: $htv.Styles.ActivationButtonUnfocused,
            focused_image: "images/btn-exit-sample.png",
            unfocused_image: "images/btn-exit-sample.png",
            include_brackets: true
        });
        this._activeNode.control.focus();
        $htv.Profile.disableAuthenticationPolling();
    };
    
    this._handleButtonActivated = function (eventData) {
        if (eventData.target === this.exitButton) {
            $htv.Controller.popView();
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            if (eventData.action === "KEY_RETURN") {
                $htv.Controller.popView();
            } else {
                this._activeNode.control.handleEvent(eventName, eventData);
            }
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            if (this._activeNode === this.exitButton) {
                this.sampleText.control.hide();
            } else {
                this.sampleText.control.show();
            }
            break;
        case "RETURN_KEY_PRESSED":
            $htv.Controller.popView();
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "BUTTON_ACTIVATED":
            this._handleButtonActivated(eventData);
            break;
        default: 
            
            break;
        }
    };
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    
    this.backgroundImage = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 0,
            z: 5,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 53,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonBottom = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 377,
            z: 1,
            width: 960,
            height: 111
        },
        control: null
    };

    this.carousel = {
        view: view,
        type: "VideoThumbnailCarousel",
        position: {
            x: 50,
            y: 250,
            z: 1,
            width: 860,
            height: 230
        },
        control: null
    };
    
    this.sampleText = {
        view: view,
        type: "TextControl",
        position: {
            x: 70,
            y: 70,
            z: 3,
            width: 400,
            height: 40
        },
        control: null
    };
    
    this.exitButton = {
        view: view,
        type: "ButtonControl",
        position: {
            x: 960 / 2 - 186 / 2,
            y: 430,
            z: 1,
            width: 186,
            height: 29
        },
        control: null
    };
    
    // attach nav_info
    
    this.carousel.nav_info = {
        down: {
            type: "control",
            node: this.exitButton
        }
    };
    this.exitButton.nav_info = {
        up: {
            type: "control",
            node: this.carousel
        }
    };
    this._controls.push(this.sampleText);
    this._controls.push(this.backgroundImage);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonBottom);
    this._controls.push(this.carousel);
    this._controls.push(this.exitButton);
    
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.SampleVideosView.prototype = new $htv.Views.BaseView();

$htv.Views.SearchResultsView = function () {
    var view, newRoot;
    this.viewName = "SearchResultsView";
    this._overrideLastSpotlightAnimation = true;
    this.options = null;
    this.items = null;
    this.focusOnSTC = true;
    
    this.webOnlyAlertDialog = null;
        
        
    this._initialize = function (options) {
        
        this.focusOnSTC = true;
        this.options = options;
        this._platformCanvasHandle = options.canvas;
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-unfocused.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-center-unfocused.png", options);
        this.resultCountText.control = $htv.ControlPool.getObject("TextControl");
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-nav.png", options);      
        if (options.query.length > 50) {
            options.query = options.query.substring(0, 47) + "...";
        }
        this.resultCountText.control.initialize(this.resultCountText.position,
            this.resultCountText, null, { text: "Search: loading results for \"" + options.query + "\"", styleName: $htv.Styles.BreadCrumbFrontLabel });
        
        // item_type and video_type are used by SearchCollection to filter results
        var nsmOptions = $htv.Utils.copyObject(options); // todo: only copy what you need
        
        nsmOptions.items = $htv.Utils.createGenericCollection([{
            title: "All",
            item_type: null,
            video_type: null
        }, {
            title: "Shows",
            item_type: "show",
            video_type: null
        }, {
            title: "Networks",
            item_type: "company",
            video_type: null
        }, {
            title: "Episodes",
            item_type: "video",
            video_type: "episode"
        }, {
            title: "Movies",
            item_type: "video",
            video_type: "feature_film"
        }, {
            title: "Clips",
            item_type: "video",
            video_type: "clip"
        }, {
            title: "Trailers",
            item_type: "video",
            video_type: "film_trailer"
        }]);
                
        
        // Load NSM
        this._activeNode = this.nsm;
        this._loadChild("", "SearchResultsView", this._root, nsmOptions);
        this._activeNode.control.focus();
    };
    
    this._selectionChanged = function (eventData) {
        if (this._activeNode === this.nsm) {
            // Filter the results based on the nsm selection
            var item = this.nsm.control.items.getItemAt(this.nsm.control.activeIndex).item;
            this.options.item_type = item.item_type;
            this.options.video_type = item.video_type;
            this.options.items = $htv.Utils.createSearchCollection(this.options);
            this.options.carousel_name = "Search Results";
            this.options.include_show_title = true;
            this._loadChild("", "SearchThumbnailCarousel", this._root.children.SearchResultsView, this.options);
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS":
            this._navigateBetweenControls(eventData);
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "MENU_ITEM_ACTIVATED":
            this._navigateBetweenControls({
                nav_dir: "down"
            });
            break;
        case "INITIALIZE_COMPLETE":
            if (eventData.target === this.stc) {
                var num = this.stc.control.items.getLength();
                this.resultCountText.control.setText("Search: " + num +
                " result" +
                (num === 1 ? "" : "s") +
                " for \"" +
                this.options.query +
                "\"");
                
                if (this.focusOnSTC === true) {
                    this._navigateBetweenControls({
                        nav_dir: "down"
                    });
                    this.focusOnSTC = false;
                }
            }
            this._activeNode.control.focus();
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        case "WEBONLY_ITEM_ACTIVATED":
            if (this.webOnlyAlertDialog.control === null) {
                // this is our virgin error message
                
                this.webOnlyAlertDialog.control = $htv.ControlPool.getObject("AlertDialogControl");
                this.webOnlyAlertDialog.control.initialize(null, this.webOnlyAlertDialog, {title: "Availability", text: eventData.message});
                
            } else {
                this.webOnlyAlertDialog.control.show(eventData.message);
            }           
            
            this._activeNode = this.webOnlyAlertDialog;
            this._activeNode.control.focus();
            break;
        case "BUTTON_ACTIVATED":
            if (this._activeNode === this.webOnlyAlertDialog) {
                this.webOnlyAlertDialog.control.hide();
                
                this._activeNode = this.stc;
                this._activeNode.control.focus();
            }
            break;
        case "RETURN_KEY_PRESSED":
            if (this._activeNode === this.webOnlyAlertDialog) {
                this.webOnlyAlertDialog.control.hide();
                
                this._activeNode = this.stc;
                this._activeNode.control.focus();
            }
            break;
        default:
            
            break;
        }
    };
    
    view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    // web-only error pseudo-view
    
    this.webOnlyAlertDialog = {
        view: view,
        type: "AlertDialogControl",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 200,
            height: 29
        },
    
        control: null
    };
    
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 217,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.resultCountText = {
        view: view,
        type: "TextControl",
        position: {
            x: 40,
            y: 35,
            z: 3,
            width: 650,
            height: 30
        },
        control: null
    };
    
    newRoot = {
        view: view,
        parent: null,
        type: "None",
        position: {
            x: 0,
            y: 0,
            width: 0,
            height: 0
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SearchResultsView: null
        }
    };
    
    this.nsm = newRoot.children.SearchResultsView = {
        view: view,
        parent: newRoot,
        type: "NonSlidingMenu",
        position: {
            x: 40,
            y: 47,
            z: 4,
            width: 700,
            height: 35
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SearchThumbnailCarousel: null
        }
    };
    
    this.stc = newRoot.children.SearchResultsView.children.SearchThumbnailCarousel = {
        view: view,
        parent: newRoot.children.SearchResultsView,
        type: "SearchThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
        }
    };
   
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 50,
            y: 475,
            z: 2,
            width: 93,
            height: 17
        },
        control: null
    };

    // attach nav_info
    
    this.nsm.nav_info = {
        down: {
            type: "control",
            node: this.stc
        },
        up: {type: "pop_view"}
    };
    this.stc.nav_info = {
        up: {
            type: "control",
            node: this.nsm
        }
    };
    
    
    
    this._controls.push(this.topBar);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonMiddle);
    this._controls.push(this.resultCountText);
    this._controls.push(newRoot);
    this._controls.push(this.nsm);
    this._controls.push(this.stc);
    this._controls.push(this.huluLogo);
    
    this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.SearchResultsView.prototype = new $htv.Views.BaseView();

$htv.Views.SearchView = function () {
    var view, newRoot;
    this.viewName = "SearchView";
    
    this._initialize = function (options) {
        
        this._instanceOptions = options;
        this._platformCanvasHandle = options.canvas;
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        this.breadCrumb.control = $htv.ControlPool.getObject("BreadCrumb");
        this.breadCrumb.control.initialize(this.breadCrumb.position, this.breadCrumb, "null", options);
        this.breadCrumb.control.show();
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-focused.png", options);
        this.leftRightArrow.control = $htv.ControlPool.getObject("ImageControl");
        this.leftRightArrow.control.initialize(this.leftRightArrow.position, this.leftRightArrow, "images/masthead_arrow_right.png", options);
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-nav.png", options);
        
        // review: is there a reason for this hierarchy?  it seems like a manual one might be more flexible here
        // (could be old structure)
        
        // Create root (search query text input)
        this._loadChild(options.menu_url, "SearchView", this._root, options);
        
        // Create keyboard as a child of searchview
        this._loadChild(null, "Keyboard", this._root.children.SearchView, { go_label: "search", can_wrap: true });
        
        // Create suggestion results as a child of keyboard
        this._loadChild(null, "SuggestResults",  this._root.children.SearchView.children.Keyboard, {});

        this._activeNode = this.keyboard;
        this._activeNode.control.focus();
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            if (this.suggestions.control.hasSuggestions()) {
                this.keyboard.control.setOptions({can_wrap: false});
            }
            else {
                this.keyboard.control.setOptions({can_wrap: true});
            }
            
            // If input was from a keyboard, navigate to the active input
            if ((eventData.action === "KEYBOARD" || eventData.action === "BACKSPACE") &&
                this._activeNode === this.keyboard) {
                this._navigateToControl(this.textInput);
            }
            
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS":
            this._navigateBetweenControls(eventData);
            if (this._activeNode === null) {
                //do nothing
            } else if (this._activeNode === this.suggestions) {
                this.leftRightArrow.control.setSource("images/masthead_arrow_left.png");
            } else {
                this.leftRightArrow.control.setSource("images/masthead_arrow_right.png");
            }
            break;
        case "RETURN_KEY_PRESSED": 
            if (eventData.target === this.suggestions) {
                this._navigateToControl(this.textInput);
            } else {
                $htv.Controller.popView();
            }
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "KEYBOARD_INPUT":
            this.textInput.control.handleKeyboardInput(eventData);
            // do nothing for empty queries, but don't use stringIsNullOrEmpty
            // so that whitespace queries are allowed. (same behavior as hulu.com)
            if (eventData.type === "SUBMIT" && this.textInput.control.getText().length > 0) {
                $htv.Controller.pushView("SearchResultsView", {
                    query: this.textInput.control.getText()
                });
            }
            break;
        case "TEXT_INPUT_CHANGED":
            this.suggestions.control.fetchSuggestions(eventData.new_text);
            break;
        case "TEXT_INPUT_ACTIVATED":
            // If user presses OK on the query, do a search
            if (!$htv.Utils.stringIsNullOrEmpty(eventData.text)) {
                $htv.Controller.pushView("SearchResultsView", {
                    query: this.textInput.control.getText()
                });                
            }
            // Or if blank, go down to the keyboard 
            else if (this._activeNode === this.textInput) {
                this._navigateBetweenControls({ nav_dir: "down" });
            }
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        default: 
            
            break;
        }
    };
    
    view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.breadCrumb = {
        view: view,
        parent: null,
        type: "BreadCrumb",
        position: {
            x: 4,
            y: 9,
            z: 4,
            width: 700,
            height: 40
        },
        control: null
    };
    
    this.leftRightArrow = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 519,
            y: 296,
            z: 3,
            width: 23,
            height: 68
        },
        control: null
    };
    
    newRoot = {
        view: view,
        parent: null,
        type: "None",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 0,
            height: 0
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SearchView: null
        }
    };
    
    this.textInput = newRoot.children.SearchView = {
        view: view,
        parent: newRoot,
        type: "TextInput",
        position: {
            x: 47,
            y: 160,
            z: 0,
            width: 470,
            height: 81
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            Keyboard: null
        }
    };
    
    this.keyboard = newRoot.children.SearchView.children.Keyboard = {
        view: view,
        parent: newRoot.children.SearchView,
        type: "Keyboard",
        position: {
            x: 72,
            y: 239,
            z: 3,
            width: 960,
            height: 150
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
            SuggestResults: null
        }
    };
    
    this.suggestions = newRoot.children.SearchView.children.Keyboard.children.SuggestResults = {
        view: view,
        parent: newRoot.children.SearchView.children.Keyboard,
        type: "SuggestResults",
        position: {
            x: 560,
            y: 150,
            z: 0,
            width: 327,
            height: 308
        },
        control: null,
        activeChild: null,
        siblings: [],
        children: {
        }
    };

    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 50,
            y: 475,
            z: 2,
            width: 93,
            height: 17
        },
        control: null
    };
   

    // attach nav_info
    
    this.textInput.nav_info = {
        down: {
            type: "child_control"
        },
        up: {
            type: "pop_view"
        },
        right: {
            type: "control",
            node: this.suggestions
        }
    };
    this.keyboard.nav_info = {
        up: {
            type: "control",
            node: this.textInput
        },
        right: {
            type: "control",
            node: this.suggestions
        },
        left: {
            type: "control",
            node: this.suggestions
        }
    };
    this.suggestions.nav_info = {
        up: {
            type: "control",
            node: this.textInput
        },
        left: {
            type: "control",
            node: this.keyboard
        },
        right: {
            type: "control",
            node: this.keyboard
        }
    };
    
    this._controls.push(this.topBar);
    this._controls.push(this.breadCrumb);
    this._controls.push(this.horizonTop);
    this._controls.push(this.leftRightArrow);
    this._controls.push(newRoot);
    this._controls.push(this.textInput);
    this._controls.push(this.keyboard);
    this._controls.push(this.suggestions);
    this._controls.push(this.huluLogo);

    this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.SearchView.prototype = new $htv.Views.BaseView();

$htv.Views.VideoDetailsView = function () {
    this.viewName = "VideoDetailsView";
    this.menuItems = null;
    
    this._initialize = function (options) {
        var menuArray, pp, viewed, duration;
        
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        
        this.breadCrumb.control = $htv.ControlPool.getObject("BreadCrumb");
        this.breadCrumb.control.initialize(this.breadCrumb.position, this.breadCrumb, "null", options);
        this.breadCrumb.control.show();
        this._activeNode = this.nonSlidingMenu;
        this._instanceOptions = options;
        
        describe(options);
        menuArray = [{
            title: 'Watch Now'
        }, {
            title: 'Add to queue'
        }, {
            title: 'Rate',
            cmtype: 'RatingControl'
        }, {
            title: 'Related',
            cmtype: 'VideoThumbnailCarousel'
        }, {
            title: 'Series',
            cmtype: 'ButtonHint'
        }, {
            title: 'Home',
            cmtype: 'ButtonHint'
        }];
        if ($htv.Profile.isVideoInQueue(options.video_id)) {
            menuArray[1] = {
                title: 'Remove from queue'
            };
        } else {
            menuArray[1] = {
                title: 'Add to queue'
            };
        }
        
        // Only show Series details if came from a non-showpage carousel
        if (options.include_show_title !== true) { // REMOVE if no include_show_title
            menuArray.splice(4, 1);
        }
        
        pp = $htv.Profile.getPlaybackProgress(options.content_id);
        viewed = pp.viewed;
        duration = pp.duration;
        if (viewed > 0) {
            this.videoProgress.control = $htv.ControlPool.getObject("VideoProgress");
            this.videoProgress.control.initialize(this.videoProgress.position, this.videoProgress, "null", {
                viewed: viewed,
                duration: duration
            });
            if (viewed < duration) {
                menuArray.splice(0, 1, {
                    title: "Resume"
                }, {
                    title: "Restart"
                });
            }
        }
        this.menuItems = $htv.Utils.createGenericCollection(menuArray);
        options.items = this.menuItems;
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-focused.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-center-unfocused.png", options);
        this.horizonMiddle.control.hide();
        this.horizonBottom.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonBottom.control.initialize(this.horizonBottom.position, this.horizonBottom, "images/horizon-center-unfocused.png", options);
        this.horizonBottom.control.hide();
        this.nonSlidingMenu.control = $htv.ControlPool.getObject("NonSlidingMenu");
        this.nonSlidingMenu.control.initialize(this.nonSlidingMenu.position, this.nonSlidingMenu, "null", options);
        this.videoDetails.control = $htv.ControlPool.getObject("VideoDetails");
        this.videoDetails.control.initialize(this.videoDetails.position, this.videoDetails, "null", options);
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-nav.png", options);
    };
    
    this._selectionChanged = function (eventData) {
        
        this._instanceOptions.active_title = eventData.title;
        // hide all controls.
        if (this.ratingControl.control !== null) {
            this.ratingControl.control.hide();
        }
        if (this.relatedVideos.control !== null) {
            this.relatedVideos.control.hide();
        }
        if (this.videoDetails.control !== null) {
            this.videoDetails.control.hide();
        }
        if (this.seriesDetails.control !== null) {
            this.seriesDetails.control.hide();
        }
        if (this.videoProgress.control !== null) {
            this.videoProgress.control.hide();
        }
        if (this.homeHint.control !== null) {
            this.homeHint.control.hide();
        }
        delete this.nonSlidingMenu.nav_info.down;
        
        if (eventData.title === "Rate") {
            if (this.ratingControl.control === null) {
                this.ratingControl.control = $htv.ControlPool.getObject("RatingControl");
                eventData.options.video_id = this._instanceOptions.video_id;
                eventData.options.video_title = this._instanceOptions.video_title;
                eventData.options.show_id = this._instanceOptions.show_id;
                eventData.options.show_canonical_name = this._instanceOptions.show_canonical_name;
                this.ratingControl.control.initialize(this.ratingControl.position, this.ratingControl, "null", eventData.options);
            }
            this.ratingControl.control.show();
            this.videoDetails.control.hide();
            if (this.videoProgress.control !== null) {
                this.videoProgress.control.hide();
            }
            if (this.relatedVideos.control !== null) {
                this.relatedVideos.control.hide();
            }
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonMiddle.control.hide();
            this.horizonBottom.control.show();
            this.nonSlidingMenu.nav_info.down = {
                type: "control",
                node: this.ratingControl
            };
        } else if (eventData.title === "Related") {
            if (this.relatedVideos.control === null) {
                this.relatedVideos.control = $htv.ControlPool.getObject("VideoThumbnailCarousel");
            } else {
                this.relatedVideos.control.show();
            }
            
            if (this._instanceOptions.relatedVideosInitialized !== true) {
                eventData.options.video_id = this._instanceOptions.video_id;
                eventData.options.show_id = this._instanceOptions.show_id;
                eventData.options.show_canonical_name = this._instanceOptions.show_canonical_name;
                eventData.options.carousel_item_type = "videos";
                eventData.options.include_show_title = true;
                eventData.options.use_related_title = true;
                eventData.options.video_title = this._instanceOptions.video_title;
                eventData.options.show_name = this._instanceOptions.show_name;
                this.relatedVideos.control.initialize(this.relatedVideos.position, this.relatedVideos, $htv.Constants.Endpoints.menu + "/menu/" + $htv.Constants.MENU_PREFIX + "related_videos?video_id=" + this._instanceOptions.video_id, eventData.options);
            }
            
            this.nonSlidingMenu.nav_info.down = {
                type: "control",
                node: this.relatedVideos
            };
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonMiddle.control.show();
            this.horizonBottom.control.hide();
        } else if (eventData.title === "Series") {
            if (this.seriesDetails.control === null) {
                this.seriesDetails.control = $htv.ControlPool.getObject("ButtonHint");
                eventData.options.button_image_path = "images/home-hint.png";
                eventData.options.prefix_text = "Press";
                eventData.options.postfix_text = "to view the series details";
                this.seriesDetails.control.initialize(this.seriesDetails.position, this.seriesDetails, null, eventData.options);
            }
            this.seriesDetails.control.show();
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonMiddle.control.hide();
            this.horizonBottom.control.show();
        } else if (eventData.title === "Home") {
            if (this.homeHint.control === null) {
                this.homeHint.control = $htv.ControlPool.getObject("ButtonHint");
                eventData.options.button_image_path = "images/home-hint.png";
                eventData.options.prefix_text = "Press";
                eventData.options.postfix_text = "to return to the home screen";
                this.homeHint.control.initialize(this.homeHint.position, this.homeHint, null, eventData.options);
            }
            this.homeHint.control.show();
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonMiddle.control.hide();
            this.horizonBottom.control.show();
        } else {
            if (this.videoDetails.control !== null) {
                this.videoDetails.control.show();
            }
            if (this.videoProgress.control !== null) {
                this.videoProgress.control.show();
            }
            this.horizonTop.control.setSource("images/horizon-top-focused.png");
            this.horizonMiddle.control.hide();
            this.horizonBottom.control.hide();
        }
    };
    
    this._updateQueueItem = function () {
        var i, item;
        for (i = 0; i < this.menuItems.getLength(); i++) {
            item = this.menuItems.getItemAt(i).item;
            if (item && item.title.indexOf("queue") !== -1) {
                if ($htv.Profile.isVideoInQueue(this._instanceOptions.video_id)) {
                    this.menuItems.setItemAt(i, {
                        title: "Remove from queue"
                    });
                } else {
                    this.menuItems.setItemAt(i, {
                        title: "Add to queue"
                    });
                }
                this.nonSlidingMenu.control.setDataSource(this.menuItems);
                break;
            }
        }
    };
    
    this._onQueueResult = function (result) {
        
        this.queueWait = false;
        if (result.success === true) {
            this._updateQueueItem();
        }
    };
    
    this._activatedItem = function (eventData) {
        if (eventData.target === this.nonSlidingMenu) {
            switch (eventData.item.title) {
            case "Watch Now":
            case "Resume":
                
                $htv.Controller.playVideo(this._instanceOptions.content_id, {});
                break;
            case "Restart":
                
                $htv.Controller.playVideo(this._instanceOptions.content_id, {
                    start_at_beginning: true
                });
                break;
            case "Add to queue":
                $htv.Profile.addToQueue(this._instanceOptions.video_id, this, this._onQueueResult);
                this.queueWait = true;
                break;
            case "Remove from queue":
                $htv.Profile.removeFromQueue(this._instanceOptions.video_id, this, this._onQueueResult);
                this.queueWait = true;
                break;
            case "Series":
                if (this.videoDetails.control !== null) {
                    var metadata = this.videoDetails.control.getVideoMetadata();
                    if (metadata !== null) {
                        $htv.Controller.pushView("ContentView", {
                            menu_url: "/menu/" + $htv.Constants.MENU_PREFIX + "show_page?show_id=" + metadata.show_id,
                            view_title: metadata.show_name,
                            show_id: metadata.show_id,
                            show_name: metadata.show_name,
                            show_canonical_name: metadata.show_canonical_name,
                            previous_view_title: metadata.title
                        });
                    }
                }
                break;
            case "Home":
                $htv.Controller.popToHome();
                break;
            default:
                this._navigateBetweenControls({
                    nav_dir: "down"
                });
                break;
            }
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "VIEW_DID_REAPPEAR":
            // why do i need to selectionchanged on reappear?
            this._selectionChanged({
                title: this._instanceOptions.active_title
            });
            this._updateQueueItem();
            this._activeNode.control.focus();
            // todo: update progress bar?
            break;
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS":
            this._navigateBetweenControls(eventData);
            if (this._activeNode === null) {
                //do nothing
            } else if (this._activeNode === this.nonSlidingMenu) {
                this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-unfocused.png");
                this.horizonBottom.control.setSource("images/horizon-center-unfocused.png");
            } else {
                this.horizonTop.control.setSource("images/horizon-top-focused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-focused.png");
                this.horizonBottom.control.setSource("images/horizon-center-focused.png");
            }
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            if (eventData.target === this.relatedVideos) {
                this._instanceOptions.relatedVideosInitialized = true;
            }
            this._activeNode.control.focus();
            break;
        case "MENU_ITEM_ACTIVATED":
            this._activatedItem(eventData);
            break;
        case "PLAY_BUTTON_PRESSED":
            switch (eventData.item.title) {
            case "Watch Now":
            case "Resume":
                $htv.Controller.playVideo(this._instanceOptions.content_id, {});
                break;
            case "Restart":
                $htv.Controller.playVideo(this._instanceOptions.content_id, {
                    start_at_beginning: true
                });
                break;
            }
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        default:
            
            break;
        }
    };
    
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.breadCrumb = {
        view: view,
        parent: null,
        type: "BreadCrumb",
        position: {
            x: 4,
            y: 9,
            z: 4,
            width: 700,
            height: 40
        },
        control: null
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 217,
            z: 1,
            width: 960,
            height: 111
        },
        control: null
    };
    
    this.horizonBottom = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 327,
            z: 1,
            width: 960,
            height: 111
        },
        control: null
    };
    
    this.nonSlidingMenu = {
        view: view,
        type: "NonSlidingMenu",
        position: {
            x: 40,
            y: 41,
            z: 3,
            width: 700,
            height: 35
        },
        control: null
    };
    
    this.videoDetails = {
        view: view,
        type: "VideoDetails",
        position: {
            x: 40,
            y: 165,
            z: 3,
            width: 920,
            height: 300
        },
        control: null
    };
    
    this.seriesDetails = {
        view: view,
        type: "ButtonHint",
        position: {
            x: 0,
            y: 250,
            z: 3,
            width: 960,
            height: 40
        },
        control: null
    };
    
    this.videoProgress = {
        view: view,
        type: "VideoProgress",
        position: {
            x: 40,
            y: 145,
            z: 2,
            width: 512,
            height: 20
        },
        control: null
    };
    
    this.ratingControl = {
        view: view,
        type: "RatingControl",
        position: {
            x: 0,
            y: 120,
            z: 3,
            width: 960,
            height: 420
        },
        control: null
    };
    
    this.relatedVideos = {
        view: view,
        type: "VideoThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null
    };
    
    this.homeHint = {
        view: view,
        type: "ButtonHint",
        position: {
            x: 0,
            y: 250,
            z: 3,
            width: 960,
            height: 40
        },
        control: null
    };
    
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 50,
            y: 475,
            z: 2,
            width: 93,
            height: 17
        },
        control: null
    };
    
    // attach nav_info
    
    this.nonSlidingMenu.nav_info = {
        up: {
            type: "pop_view"
        }
    };
    
    
    this.ratingControl.nav_info = {
        up: {
            type: "control",
            node: this.nonSlidingMenu
        }
    };
    
    this.relatedVideos.nav_info = {
        up: {
            type: "control",
            node: this.nonSlidingMenu
        }
    };
    this._controls.push(this.topBar);
    this._controls.push(this.breadCrumb);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonMiddle);
    this._controls.push(this.horizonBottom);
    this._controls.push(this.nonSlidingMenu);
    this._controls.push(this.videoDetails);
    this._controls.push(this.seriesDetails);
    this._controls.push(this.videoProgress);
    this._controls.push(this.ratingControl);
    this._controls.push(this.relatedVideos);
    this._controls.push(this.homeHint);
    this._controls.push(this.huluLogo);
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.VideoDetailsView.prototype = new $htv.Views.BaseView();

$htv.Views.MovieDetailsView = function () {
    this.viewName = "MovieDetailsView";
    this.menuItems = null;

    this._initialize = function (options) {
        var menuArray, pp, viewed, duration;
        
        this.topBar.control = $htv.ControlPool.getObject("TopBar");
        this.topBar.control.initialize(this.topBar.position, this.topBar, "null", options);
        this.topBar.control.show();
        
        this.breadCrumb.control = $htv.ControlPool.getObject("BreadCrumb");
        this.breadCrumb.control.initialize(this.breadCrumb.position, this.breadCrumb, "null", options);
        this.breadCrumb.control.show();
        this._activeNode = this.nonSlidingMenu;
        
        this._instanceOptions = options;
        describe(this._instanceOptions);
        menuArray = [{
            title: 'Watch Now'
        }, {
            title: 'Add to queue'
        }, {
            title: 'Clips',
            cmtype: 'VideoThumbnailCarousel'
        }, {
            title: 'Rate',
            cmtype: 'RatingControl'
        }, {
            title: 'Related',
            cmtype: 'VideoThumbnailCarousel'
        }, {
            title: 'Home',
            cmtype: 'ButtonHint'
        }];
        
        if (!options.clips_count || parseInt(options.clips_count, 10) === 0) {
            menuArray.splice(2, 1);
        }
        
        if ($htv.Profile.isVideoInQueue(options.video_id)) {
            menuArray[1] = {title: "Remove from queue"};
        } else {
            menuArray[1] = {title: "Add to queue"};
        }
        pp = $htv.Profile.getPlaybackProgress(options.content_id);
        viewed = pp.viewed;
        duration = pp.duration;
        if (viewed > 0) {
            this.videoProgress.control = $htv.ControlPool.getObject("VideoProgress");
            this.videoProgress.control.initialize(this.videoProgress.position, this.videoProgress, "null", { viewed: viewed, duration: duration });
            if (viewed < duration) {
                menuArray.splice(0, 1, {title: "Resume"}, {title: "Restart"});
            }
            this.videoProgress.control.show();
        } 
        this.menuItems = $htv.Utils.createGenericCollection(menuArray);
        options.items = this.menuItems;
        this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-focused.png", options);
        this.horizonMiddle.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonMiddle.control.initialize(this.horizonMiddle.position, this.horizonMiddle, "images/horizon-center-unfocused.png", options);
        this.horizonMiddle.control.hide();
        this.horizonBottom.control = $htv.ControlPool.getObject("ImageControl");
        this.horizonBottom.control.initialize(this.horizonBottom.position, this.horizonBottom, "images/horizon-center-unfocused.png", options);
        this.horizonBottom.control.hide();
        this.nonSlidingMenu.control = $htv.ControlPool.getObject("NonSlidingMenu");
        this.nonSlidingMenu.control.initialize(this.nonSlidingMenu.position, this.nonSlidingMenu, "null", options);
        this.videoDetails.control = $htv.ControlPool.getObject("VideoDetails");
        this.videoDetails.control.initialize(this.videoDetails.position, this.videoDetails, "null", options);
        this.huluLogo.control = $htv.ControlPool.getObject("ImageControl");
        this.huluLogo.control.initialize(this.huluLogo.position, this.huluLogo, "images/hulu-plus-logo-nav.png", options);
    };

    // lazily loads other controls.  I think this is the right approach still..
    this._selectionChanged = function (eventData) {
        if (this.movieClips.control !== null) {
            this.movieClips.control.hide();
        }
        if (this.ratingControl.control !== null) {
            this.ratingControl.control.hide();
        }
        if (this.relatedVideos.control !== null) {
            this.relatedVideos.control.hide();
        }
        if (this.videoDetails.control !== null) {
            this.videoDetails.control.hide();
        }
        if (this.videoProgress.control !== null) {
            this.videoProgress.control.hide();
        }
        if (this.homeHint.control !== null) {
            this.homeHint.control.hide();
        }
        this.horizonMiddle.control.hide();
        this.horizonBottom.control.hide();
        delete this.nonSlidingMenu.nav_info.down;
        
        
        this._instanceOptions.active_title = eventData.title;
        if (eventData.title === "Rate") {
            if (this.ratingControl.control === null) {
                this.ratingControl.control = $htv.ControlPool.getObject("RatingControl");
                eventData.options.show_id = this._instanceOptions.show_id;
                eventData.options.show_name = this._instanceOptions.show_name;
                eventData.options.show_canonical_name = this._instanceOptions.show_canonical_name;
                this.ratingControl.control.initialize(this.ratingControl.position, this.ratingControl, "null", eventData.options);
            }
            this.ratingControl.control.show();
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonBottom.control.show();
            
            this.nonSlidingMenu.nav_info.down = {
                type: "control",
                node: this.ratingControl
            };
        } else if (eventData.title === "Clips") {
            if (this.movieClips.control === null) {
                this.movieClips.control = $htv.ControlPool.getObject("VideoThumbnailCarousel");
                this.movieClips.control.initialize(this.movieClips.position, this.movieClips, $htv.Constants.Endpoints.menu + "/menu/" + $htv.Constants.MENU_PREFIX + "movie_clips?show_id=" + this._instanceOptions.show_id, eventData.options);
            }
            this.movieClips.control.show();
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonMiddle.control.show();
            
            this.nonSlidingMenu.nav_info.down = {
                type: "control",
                node: this.movieClips
            };
        } else if (eventData.title === "Related") {
            if (this.relatedVideos.control === null) {
                this.relatedVideos.control = $htv.ControlPool.getObject("VideoThumbnailCarousel");
            } else {
                this.relatedVideos.control.show();
            }
            if (this._instanceOptions.relatedVideosInitialized !== true) {
                eventData.options.carousel_item_type = "movies";
                eventData.options.use_related_title = 1;
                eventData.options.show_id = this._instanceOptions.show_id;
                eventData.options.show_name = this._instanceOptions.show_name;
                this.relatedVideos.control.initialize(this.relatedVideos.position, this.relatedVideos, $htv.Constants.Endpoints.menu + "/menu/" + $htv.Constants.MENU_PREFIX + "related_videos?video_id=" + this._instanceOptions.video_id, eventData.options);
            }
            
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonMiddle.control.show();
            
            this.nonSlidingMenu.nav_info.down = {
                type: "control",
                node: this.relatedVideos
            };
        } else if (eventData.title === "Home") {
            if (this.homeHint.control === null) {
                this.homeHint.control = $htv.ControlPool.getObject("ButtonHint");
                eventData.options.button_image_path = "images/home-hint.png";
                eventData.options.prefix_text = "Press";
                eventData.options.postfix_text = "to return to the home screen";
                this.homeHint.control.initialize(this.homeHint.position, this.homeHint, null, eventData.options);
            }
            this.homeHint.control.show();
            this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
            this.horizonBottom.control.show();
        } else {
            this.horizonTop.control.setSource("images/horizon-top-focused.png");
            if (this.videoDetails.control !== null) {
                this.videoDetails.control.show();
            }
            if (this.videoProgress.control !== null) {
                this.videoProgress.control.show();
            }
        }
    };
    
    this._updateQueueItem = function () {
        var i, item;
        for (i = 0; i < this.menuItems.getLength(); i++) {
            item = this.menuItems.getItemAt(i).item;
            if (item && item.title.indexOf("queue") !== -1) {
                if ($htv.Profile.isVideoInQueue(this._instanceOptions.video_id)) {
                    this.menuItems.setItemAt(i, {
                        title: "Remove from queue"
                    });
                } else {
                    this.menuItems.setItemAt(i, {
                        title: "Add to queue"
                    });
                }
                this.nonSlidingMenu.control.setDataSource(this.menuItems);
                break;
            }
        }
    };
       
    this._onQueueResult = function (result) {
        
        this.queueWait = false;
        if (result.success === true) {
            this._updateQueueItem();
        }
    };
       
    this._activatedItem = function (eventData) {
        if (eventData.target === this.nonSlidingMenu) {
            switch (eventData.item.title) {
            case "Watch Now":
            case "Resume":
                $htv.Controller.playVideo(this._instanceOptions.content_id, {});
                break;
            case "Restart":
                
                $htv.Controller.playVideo(this._instanceOptions.content_id, {
                    start_at_beginning: true
                });
                break;
                
            case "Add to queue":
                $htv.Profile.addToQueue(this._instanceOptions.video_id, this, this._onQueueResult);
                this.queueWait = true;
                break;
            case "Remove from queue":
                $htv.Profile.removeFromQueue(this._instanceOptions.video_id, this, this._onQueueResult);
                this.queueWait = true;
                break;
            case "Home":
                $htv.Controller.popToHome();
                break;
            default:
                this._navigateBetweenControls({
                    nav_dir: "down"
                });
                break;
            }
        }
    };
    
    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "VIEW_DID_REAPPEAR":
            this._selectionChanged({title: this._instanceOptions.active_title});
            this._updateQueueItem();
            this._activeNode.control.focus();
            break;
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            this._activeNode.control.handleEvent(eventName, eventData);
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            if (this._activeNode === null) {
                //do nothing
            } else if (this._activeNode === this.nonSlidingMenu) {
                this.horizonTop.control.setSource("images/horizon-top-unfocused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-unfocused.png");
                this.horizonBottom.control.setSource("images/horizon-center-unfocused.png");
            } else {
                this.horizonTop.control.setSource("images/horizon-top-focused.png");
                this.horizonMiddle.control.setSource("images/horizon-center-focused.png");
                this.horizonBottom.control.setSource("images/horizon-center-focused.png");
            }
            break;
        case "MENU_SELECTION_CHANGED":
            this._selectionChanged(eventData);
            break;
        case "INITIALIZE_COMPLETE":
            if (eventData.target === this.relatedVideos) {
                this._instanceOptions.relatedVideosInitialized = true;
            }
            this._activeNode.control.focus();
            break;
        case "MENU_ITEM_ACTIVATED":
            this._activatedItem(eventData);
            break;
        case "PLAY_BUTTON_PRESSED":
            switch (eventData.item.title) {
            case "Watch Now":
            case "Resume":
                $htv.Controller.playVideo(this._instanceOptions.content_id, {});
                break;
            case "Restart":
                $htv.Controller.playVideo(this._instanceOptions.content_id, {
                    start_at_beginning: true
                });
                break;
            }
            break; 
        case "PLAYER_PLAYBACK_FINISHED":
            this.topBar.control.show();
            break;
        case "PLAYER_PLAYBACK_REQUESTED":
            this.topBar.control.hide();
            break;
        default: 
            
            break;
        }
    };
    
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.topBar = {
        view: view,
        parent: null,
        type: "TopBar",
        position: {
            x: 0,
            y: 0,
            z: 0,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.breadCrumb = {
        view: view,
        parent: null,
        type: "BreadCrumb",
        position: {
            x: 4,
            y: 9,
            z: 4,
            width: 700,
            height: 40
        },
        control: null
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 100,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonMiddle = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 217,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.horizonBottom = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 327,
            z: 1,
            width: 960,
            height: 111
        },
        control: null  
    };
    
    this.homeHint = {
        view: view,
        type: "ButtonHint",
        position: {
            x: 0,
            y: 250,
            z: 3,
            width: 960,
            height: 40
        },
        control: null
    };
    
    this.nonSlidingMenu = {
        view: view,
        type: "NonSlidingMenu",
        position: {
            x: 40,
            y: 41,
            z: 3,
            width: 700,
            height: 35
        },
        control: null
    };
    
    this.videoDetails = {
        view: view,
        type: "VideoDetails",
        position: {
            x: 40,
            y: 165,
            z: 3,
            width: 920,
            height: 300
        },
        control: null
    };
    
    this.videoProgress = {
        view: view,
        type: "VideoProgress",
        position: {
            x: 40,
            y: 145,
            z: 2,
            width: 512,
            height: 20
        },
        control: null
    };
    
    this.ratingControl = {
        view: view,
        type: "RatingControl",
        position: {
            x: 0,
            y: 120,
            z: 3,
            width: 960,
            height: 420
        },
        control: null
    };
    
    this.relatedVideos = {
        view: view,
        type: "VideoThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null
    };
    
    this.movieClips = {
        view: view,
        type: "VideoThumbnailCarousel",
        position: {
            x: 0,
            y: 328,
            z: 3,
            width: 960,
            height: 208
        },
        control: null
    };
 
    this.huluLogo = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 50,
            y: 475,
            z: 2,
            width: 93,
            height: 17
        },
        control: null
    };

    // attach nav_info
    
    this.nonSlidingMenu.nav_info = {
        up: {type: "pop_view"}
    };
    
        
    this.ratingControl.nav_info = {
        up: {
            type: "control",
            node: this.nonSlidingMenu
        }
    };
    
    this.relatedVideos.nav_info = {
        up: {
            type: "control",
            node: this.nonSlidingMenu
        }
    };
    this.movieClips.nav_info = {
        up: {
            type: "control",
            node: this.nonSlidingMenu
        }
    };
    this._controls.push(this.topBar);
    this._controls.push(this.breadCrumb);
    this._controls.push(this.horizonTop);
    this._controls.push(this.horizonMiddle);
    this._controls.push(this.horizonBottom);
    this._controls.push(this.homeHint);
    this._controls.push(this.nonSlidingMenu);
    this._controls.push(this.videoDetails);
    this._controls.push(this.ratingControl);
    this._controls.push(this.relatedVideos);
    this._controls.push(this.movieClips);
    this._controls.push(this.videoProgress);
    this._controls.push(this.huluLogo);
    // this._root = newRoot;
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.MovieDetailsView.prototype = new $htv.Views.BaseView();

$htv.Views.ModalPlatformErrorView = function () {
    this.viewName = "ModalPlatformErrorView";
    this.errors = null;
    this._overrideFirstSpotlightAnimation = true;
    
    this._initialize = function (options) {
        var textStyle, textWidth, textXPadding, textYPadding, messagePosition;
        
        
        this._controls = [];
        this.errors = [];
        
        this._activeNode = this.background;
        this._instanceOptions = options;
        this._controls.push(this.background);
        this._controls.push(this.message);
        this.background.control = $htv.ControlPool.getObject("ImageControl");
        this.background.control.initialize(this.background.position, this.background,
                (options.background !== undefined) ? options.background : "images/dialog-box-background.png", options);

        if (options.useHorizons === undefined || options.useHorizons === true) {
            this.horizonTop.control = $htv.ControlPool.getObject("ImageControl");
            this.horizonTop.control.initialize(this.horizonTop.position, this.horizonTop, "images/horizon-top-unfocused.png", options);
            this.horizonBottom.control = $htv.ControlPool.getObject("ImageControl");
            this.horizonBottom.control.initialize(this.horizonBottom.position, this.horizonBottom, "images/horizon-center-unfocused.png", options);
            this._controls.push(this.horizonTop);
            this._controls.push(this.horizonBottom);
        }
        
        textStyle = (options.textStyle !== undefined) ? options.textStyle : $htv.Styles.DialogBoxMessageLarge;
        this.message.control = $htv.ControlPool.getObject("TextControl");
        textWidth = (options.textWidth !== undefined) ? options.textWidth : this.message.position.width;
        textXPadding = (options.textXPadding !== undefined) ? options.textXPadding : 0;
        textYPadding = (options.textYPadding !== undefined) ? options.textYPadding : 0;
        messagePosition = {
            x: this.message.position.x + textXPadding,
            y: this.message.position.y + textYPadding - 10,
            z: this.message.position.z,
            width: textWidth,
            height: this.message.position.height
        };
        this.message.control.initialize(messagePosition, this.message, null, { text: "", styleName: textStyle });
            
        if ($htv.Platform.properties.has_in_app_exit === true) {
            this._controls.push(this.exitButton);
            this.exitButton.control = $htv.ControlPool.getObject("ButtonControl");
            this.exitButton.control.initialize(this.exitButton.position, this.exitButton, null, {
                text: "Exit",
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                focused_image: "images/btn-preview-marketing-back.jpg",
                unfocused_image: "images/btn-preview-marketing-back.jpg",
                include_brackets: true
            });
            this.exitButton.control.focus();
        }
        
        // Should be initialized with an error, so show it
        if (options.error_id !== undefined) {
            this._addError(options.error_id, options.error_text);
        }
        this._updateUI();
    };
    
    this._addError = function (errorId, errorText) {
        
        for (var i = 0; i < this.errors.length; i++) {
            if (this.errors[i].id === errorId) {
                return;
            }
        }
        
        this.errors.push({
            id: errorId,
            text: errorText
        });
    };
    
    this._removeError = function (errorId) {
        
        for (var i = 0; i < this.errors.length; i++) {
            if (this.errors[i].id === errorId) {
                this.errors.splice(i, 1);
                return;
            }
        }
    };
    
    this._updateUI = function () {
        var i, messages = "";
        for (i = 0; i < this.errors.length; i++) {
            
            describe(this.errors[i]);
            if (this.errors[i] && !$htv.Utils.stringIsNullOrEmpty(this.errors[i].text)) {
                messages += "\n - " + this.errors[i].text;
            }
        }
        
        if (messages.length > 0) {
            this.message.control.setText("System notifications:\n" + messages);
        }
        else {
            this.message.control.setText("An error has occurred. Sorry for the inconvenience.");
        }
    };

    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if ($htv.Platform.properties.has_in_app_exit === true) {
                if (eventData.action === "KEY_RETURN" || eventData.action === "KEY_EXIT" || eventData.action === "PRESS_OK") {
                    $htv.Controller.exit();
                }
            }
            break;
        case "PLATFORM_STATUS_CLEAR":
            if (eventData.error_id) {
                this._removeError(eventData.error_id);
            }
            
            if (this.errors.length === 0) {
                $htv.Controller.popView();
            }
            else {
                this._updateUI();
            }
            break;
        case "PLATFORM_STATUS_ERROR":
            if (eventData.error_id) {
                this._addError(eventData.error_id, eventData.error_text);
            }
            this._updateUI();
            break;
        default: 
            
            break;
        }
    };
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.background = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 0,
            z: 5,
            width: 960,
            height: 540
        },
        control: null
    };
    
    this.horizonTop = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 134,
            z: 1,
            width: 960,
            height: 100
        },
        control: null
    };
    
    this.horizonBottom = {
        view: view,
        parent: null,
        type: "ImageControl",
        position: {
            x: 0,
            y: 297,
            z: 1,
            width: 960,
            height: 111
        },
        control: null
    };
    
    this.message = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 200,
            y: 170,
            z: 1,
            width: 560,
            height: 240
        },
        control: null
    };
  
    this.exitButton = {
        view: view,
        parent: null,
        type: "ButtonControl",
        position: {
            x: 960 / 2 - 45,
            y: 350,
            z: 2,
            width: 90,
            height: 29
        },
        control: null
    };
    
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.ModalPlatformErrorView.prototype = new $htv.Views.BaseView();



$htv.Views.EndCreditsView = function () {
    this.viewName = "EndCreditsView";
    this._overrideFirstSpotlightAnimation = true;
    this.metadata = null;
    this.nextVideo = null;
    
    this._initialize = function (options) {
        
        
        this.metadata = $htv.Player.getMetadata();
        if (this.metadata === null) {
            this.metadata = {};
        }
        
        this.nextVideo = $htv.Player.getNextVideoMetadata();
        if (this.nextVideo.content_id === 0) {
            this.nextVideo = null;
        }
        
        this.nowPlayingBorderLeft.control = $htv.ControlPool.getObject("BoxControl");
        this.nowPlayingBorderLeft.control.initialize(this.nowPlayingBorderLeft.position, this.nowPlayingBorderLeft, "NextVideoBorder", options);
        
        this.nowPlayingBorderRight.control = $htv.ControlPool.getObject("BoxControl");
        this.nowPlayingBorderRight.control.initialize(this.nowPlayingBorderRight.position, this.nowPlayingBorderRight, "NextVideoBorder", options);
        
        this.nowPlayingBorderTop.control = $htv.ControlPool.getObject("BoxControl");
        this.nowPlayingBorderTop.control.initialize(this.nowPlayingBorderTop.position, this.nowPlayingBorderTop, "NextVideoBorder", options);
        
        this.nowPlayingBorderBottom.control = $htv.ControlPool.getObject("BoxControl");
        this.nowPlayingBorderBottom.control.initialize(this.nowPlayingBorderBottom.position, this.nowPlayingBorderBottom, "NextVideoBorder", options);
        
        this.nowPlayingLabel.control = $htv.ControlPool.getObject("TextControl");
        this.nowPlayingLabel.control.initialize(this.nowPlayingLabel.position, this.nowPlayingLabel, null, {
            text: "Now Playing: ",
            styleName: $htv.Styles.NowPlayingDetails
        });
        
        this.nowPlayingShow.control = $htv.ControlPool.getObject("TextControl");
        this.nowPlayingShow.control.initialize(this.nowPlayingShow.position, this.nowPlayingShow, null, {
            text: this.metadata.show_name,
            styleName: $htv.Styles.NowPlayingShow
        });
        
        this.nowPlayingTitle.control = $htv.ControlPool.getObject("TextControl");
        this.nowPlayingTitle.control.initialize(this.nowPlayingTitle.position, this.nowPlayingTitle, null, {
            text: this.metadata.title,
            styleName: $htv.Styles.NowPlayingTitle
        });
        
        this.nowPlayingDetails.control = $htv.ControlPool.getObject("TextControl");
        this.nowPlayingDetails.control.initialize({
            x: this.nowPlayingDetails.position.x,
            y: this.nowPlayingTitle.position.y + this.nowPlayingTitle.control.getTextDimensions().textHeight + 3,
            z: this.nowPlayingDetails.position.z,
            width: this.nowPlayingDetails.position.width,
            height: this.nowPlayingDetails.position.height 
        }, this.nowPlayingDetails, null, {
            text: $htv.Utils.formatVideoSubtitle(this.metadata),
            styleName: $htv.Styles.VideoDetailsTypeDuration
        });
        
        this.centerBar.control = $htv.ControlPool.getObject("BoxControl");
        this.centerBar.control.initialize(this.centerBar.position, this.centerBar, "NextVideoBorder", options);
        
        this.nextVideoLabel.control = $htv.ControlPool.getObject("TextControl");
        this.nextVideoLabel.control.initialize(this.nextVideoLabel.position, this.nextVideoLabel, null, {
            text: "Next Video:",
            styleName: $htv.Styles.VideoDetailsTypeDuration
        });
        
        if (this.nextVideo !== null) {
            this.nextVideoDetails.control = $htv.ControlPool.getObject("NextVideoDetails");
            this.nextVideoDetails.control.initialize(this.nextVideoDetails.position, this.nextVideoDetails, null, {
                metadata: this.nextVideo
            });    
        }
        
        this.autoPlayLabel.control = $htv.ControlPool.getObject("TextControl");
        this.autoPlayLabel.control.initialize(this.autoPlayLabel.position, this.autoPlayLabel, null, {
            text: "Autoplay",
            styleName: $htv.Styles.DialogBoxButtonUnfocused
        });
        
        this.autoPlayOnButton.control = $htv.ControlPool.getObject("RadioButtonControl");
        this.autoPlayOnButton.control.initialize(this.autoPlayOnButton.position, this.autoPlayOnButton, null, {
                text: "On",
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                include_brackets: true
            });
        
        this.autoPlayOffButton.control = $htv.ControlPool.getObject("RadioButtonControl");
        this.autoPlayOffButton.control.initialize(this.autoPlayOffButton.position, this.autoPlayOffButton, null, {
                text: "Off",
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                include_brackets: true
            });
            
        if ($htv.Profile.getPreference("autoplay_enabled") === true) {
            this.autoPlayOnButton.control.select();
            this.autoPlayOffButton.control.deselect();
        }
        else {
            this.autoPlayOffButton.control.select();
            this.autoPlayOnButton.control.deselect();
            this.nextVideoLabel.control.setText("Recommended:");
        }
        
        this.returnButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.returnButton.control.initialize(this.returnButton.position, this.returnButton, null, {
                text: "Return to Video",
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                focused_image: "images/btn-preview-marketing-back.jpg",
                unfocused_image: "images/btn-preview-marketing-back.jpg",
                include_brackets: true
            });
        
        this.browseButton.control = $htv.ControlPool.getObject("ButtonControl");
        this.browseButton.control.initialize(this.browseButton.position, this.browseButton, null, {
                text: "Browse",
                focused_style: $htv.Styles.DialogBoxButtonFocused,
                unfocused_style: $htv.Styles.DialogBoxButtonUnfocused,
                focused_image: "images/btn-preview-marketing-back.jpg",
                unfocused_image: "images/btn-preview-marketing-back.jpg",
                icon_image: "images/minimized-player-hint.png",
                icon_image_position: {
                    x: 55,
                    y: 3,
                    z: 2,
                    width: 19,
                    height: 19
                },
                include_brackets: true
            });

        if (this.nextVideo !== null) {
            this.autoPlayOnButton.nav_info.up = { type: "control", node: this.nextVideoDetails};
            this.autoPlayOffButton.nav_info.up = { type: "control", node: this.nextVideoDetails};
        }
        else {
            delete this.autoPlayOnButton.nav_info.up;
            delete this.autoPlayOffButton.nav_info.up;
        }

        if (this.nextVideo !== null) {
            this._activeNode = this.nextVideoDetails;    
        }
        else {
            this._activeNode = this.browseButton;
        }
        this._activeNode.control.focus();
    };
    
    this._handleButtonActivated = function (eventData) {
        switch (eventData.target) {
        case this.returnButton:
            $htv.Player.dismissEndCredits();
            $htv.Controller.resizePlayer($htv.Player.STATE_MAXIMIZED);
            break;
        case this.browseButton:
            this._handleEvent("USER_INPUT", { action: "PLAYER_TOGGLE", is_down: true });
            break;
        case this.nextVideoDetails:
            $htv.Player.stopVideo({force_autoplay: true});
            break;    
        default:
            break;
        }
    };

    this._handleRadioButtonActivated = function (eventData) {
        switch (eventData.target) {
        case this.autoPlayOnButton:
            this.autoPlayOnButton.control.select();
            this.autoPlayOffButton.control.deselect();
            this.nextVideoLabel.control.setText("Next Video:");
            $htv.Profile.setPreference("autoplay_enabled", true);
            break;
        case this.autoPlayOffButton:
            this.autoPlayOffButton.control.select();
            this.autoPlayOnButton.control.deselect();
            this.nextVideoLabel.control.setText("Recommended:");
            $htv.Profile.setPreference("autoplay_enabled", false);
            break;
        default:
            break;
        }
    };

    this._handleEvent = function (eventName, eventData) {
        switch (eventName) {
        case "USER_INPUT":
            if (this._allowInput(eventData) === false) {
                return;
            }
            if (eventData.action === "PLAYER_TOGGLE") {
                $htv.Controller.resizePlayer($htv.Player.STATE_MINIMIZED);
            }
            else if (eventData.action === "STOP") {
                $htv.Player.stopVideo({force_stop: true});
            }
            else {
                this._activeNode.control.handleEvent(eventName, eventData);    
            }
            break;
        case "LOSING_FOCUS": 
            this._navigateBetweenControls(eventData);
            break;
        case "RETURN_KEY_PRESSED":
            this._handleButtonActivated({target: this.returnButton});
            break;
        case "INITIALIZE_COMPLETE":
            this._activeNode.control.focus();
            break;
        case "BUTTON_ACTIVATED":
            this._handleButtonActivated(eventData);
            break;
        case "RADIO_BUTTON_ACTIVATED":
            this._handleRadioButtonActivated(eventData);
            break;
        case "PLAYER_PLAYBACK_FINISHED":
            $htv.Controller.popView();
            
            break; 
        default: 
            
            break;
        }
    };
    
    var view = {
        view: this,
        callback: this._handleEvent,
        fireEvent: function (eventName, eventData) {
            this.callback.call(this.view, eventName, eventData);
        }
    };
    
    this.nowPlayingBorderTop = {
        view: view,
        parent: null,
        type: "BoxControl",
        position: {
            x: 38,
            y: 28,
            z: 1,
            width: 484,
            height: 2
        }
    };
    
    this.nowPlayingBorderBottom = {
        view: view,
        parent: null,
        type: "BoxControl",
        position: {
            x: 38,
            y: 300,
            z: 1,
            width: 484,
            height: 2
        }
    };
    
    this.nowPlayingBorderLeft = {
        view: view,
        parent: null,
        type: "BoxControl",
        position: {
            x: 38,
            y: 30,
            z: 1,
            width: 2,
            height: 270
        }
    };
    
    this.nowPlayingBorderRight = {
        view: view,
        parent: null,
        type: "BoxControl",
        position: {
            x: 520,
            y: 30,
            z: 1,
            width: 2,
            height: 270
        }
    };
    
    this.nowPlayingLabel = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 40,
            y: 330,
            z: 2,
            width: 480,
            height: 20 
        },
        control: null
    };
    
    this.nowPlayingShow = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 40,
            y: 360,
            z: 2,
            width: 480,
            height: 25 
        },
        control: null
    };
    
    this.nowPlayingTitle = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 40,
            y: 388,
            z: 2,
            width: 480,
            height: 30 
        },
        control: null
    };
    
    this.nowPlayingDetails = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 40,
            y: 460,
            z: 2,
            width: 480,
            height: 20 
        },
        control: null
    };
    
    this.centerBar = {
        view: view,
        parent: null,
        type: "BoxControl",
        position: {
            x: 551,
            y: 30,
            z: 2,
            width: 2,
            height: 480
        },
        control: null
    };
    
    this.nextVideoLabel = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 596,
            y: 30,
            z: 2,
            width: 300,
            height: 30
        },
        control: null
    };
    
    this.nextVideoDetails = {
        view: view,
        parent: null,
        type: "NextVideoDetails",
        position: {
            x: 596,
            y: 59,
            z: 2,
            width: 300,
            height: 260
        },
        control: null
    };
    
    this.returnButton = {
        view: view,
        parent: null,
        type: "ButtonControl",
        position: {
            x: 650,
            y: 400,
            z: 2,
            width: 186,
            height: 29
        },
        control: null
    };
    
    this.browseButton = {
        view: view,
        parent: null,
        type: "ButtonControl",
        position: {
            x: 650,
            y: 450,
            z: 2,
            width: 186,
            height: 29
        },
        control: null
    };

    this.autoPlayLabel = {
        view: view,
        parent: null,
        type: "TextControl",
        position: {
            x: 610,
            y: 350,
            z: 2,
            width: 90,
            height: 29 
        },
        control: null
    };

    this.autoPlayOnButton = {
        view: view,
        parent: null,
        type: "RadioButtonControl",
        position: {
            x: 725,
            y: 350,
            z: 2,
            width: 45,
            height: 29
        },
        control: null
    };

    this.autoPlayOffButton = {
        view: view,
        parent: null,
        type: "RadioButtonControl",
        position: {
            x: 810,
            y: 350,
            z: 2,
            width: 50,
            height: 29
        },
        control: null
    };
    
    // attach nav_info
    this.nextVideoDetails.nav_info = {
        down: {
            type: "control",
            node: this.autoPlayOnButton
        }
    };
    this.returnButton.nav_info = {
        up: {
            type: "control",
            node: this.autoPlayOnButton
        },
        down: {
            type: "control",
            node: this.browseButton
        }
    };
    this.browseButton.nav_info = {
        up: {
            type: "control",
            node: this.returnButton
        }
    };
    this.autoPlayOnButton.nav_info = {
        up: {
            type: "control",
            node: this.nextVideoDetails
        },
        right : {
            type: "control",
            node: this.autoPlayOffButton
        },
        down: {
            type: "control",
            node: this.returnButton
        }
    };
    this.autoPlayOffButton.nav_info = {
        up: {
            type: "control",
            node: this.nextVideoDetails
        },
        left : {
            type: "control",
            node: this.autoPlayOnButton
        },
        down: {
            type: "control",
            node: this.returnButton
        }
    };
        
    this._controls.push(this.nowPlayingBorderTop);
    this._controls.push(this.nowPlayingBorderBottom);
    this._controls.push(this.nowPlayingBorderLeft);
    this._controls.push(this.nowPlayingBorderRight);
    this._controls.push(this.nowPlayingLabel);
    this._controls.push(this.nowPlayingShow);
    this._controls.push(this.nowPlayingTitle);
    this._controls.push(this.nowPlayingDetails);
    this._controls.push(this.centerBar);
    this._controls.push(this.returnButton);
    this._controls.push(this.browseButton);
    this._controls.push(this.autoPlayLabel);
    this._controls.push(this.autoPlayOnButton);
    this._controls.push(this.autoPlayOffButton);
    this._controls.push(this.nextVideoLabel);
    this._controls.push(this.nextVideoDetails);
    
    this._activeNode = null;
    this.initialize = this._initialize;
    this.handleEvent = this._handleEvent;
};

$htv.Views.EndCreditsView.prototype = new $htv.Views.BaseView();


$htv.Views.NamedViews = {
    ActivationView: new $htv.Views.ActivationView(),
    DialogBoxView: new $htv.Views.DialogBoxView(),
    BrowseView: new $htv.Views.BrowseView(),
    ContentView: new $htv.Views.ContentView(),
    EndCreditsView: new $htv.Views.EndCreditsView(),
    HelpView: new $htv.Views.HelpView(),
    LearnMoreView: new $htv.Views.LearnMoreView(),
    LoadingView: new $htv.Views.LoadingView(),
    LoginView: new $htv.Views.LoginView(),
    MainView: new $htv.Views.MainView(),
    ModalPlatformErrorView: new $htv.Views.ModalPlatformErrorView(),
    MovieDetailsView: new $htv.Views.MovieDetailsView(),
    RequestInviteView: new $htv.Views.RequestInviteView(),
    ResumeLastVideoView: new $htv.Views.ResumeLastVideoView(),
    SampleVideosView: new $htv.Views.SampleVideosView(),
    SearchResultsView: new $htv.Views.SearchResultsView(),
    SearchView: new $htv.Views.SearchView(),
    VideoDetailsView: new $htv.Views.VideoDetailsView()
};
