// load dependent libraries
bam.loadSync(bam.homePath + "bam.cookies.js", bam.homePath + 'bam.gameId.js');




// if(!!bam.cookies.get("useNarrowBand"))document.location.replace(bam.mlbhome.narrowband);
// TO DO: verify these bam.cookies commands are working correctly
(function($) {
    var bwdetect = setTimeout(function() {
        if (window.confirm("To view the MLB.com broadband page, please click OK.  Or, to view the MLB.com narrowband page, please click cancel.")) {
            //		bam.cookies.remove('useNarrowBand');
        } else {
            //		bam.cookies.set('useNarrowBand', true, 365, '/', '.mlb.com');
            document.location.replace(bam.mlbhome.narrowband);
        }
    }, 30000);
    $(function() {
        clearTimeout(bwdetect);
    });
})(jQuery);






bam.mlbhome = (function($) {

    var _log = function(msg) {
        if (_self.debug && typeof console !== "undefined" && !! console.log && !! console.dir) {
            if (typeof msg === "string") console.log("mlbhome: " + msg);
            else if (typeof msg === "object") console.dir(msg);
            else console.log(msg);
        }
    },

        _setDebugging = function(component) {
            var d = bam.url.Location(window.location).getParam("debug");
            if (!bam.env.host.isProd && !! d && (d === "true" || ~d.indexOf(component))) return true;
            else
            return false;
        },


        _properties = {},
        _lang = $("html").attr("lang"),
        $doc = $(document),

        /**
         * 
         *
         * _videoModule
         *
         *
         */

        _videoModule = {
            init: function() {

                // hack to reposition MLBTV content if the tab has been moved			
                var mlbtvNavIdx = $("#vm_nav li h3").index($("#vm_nav li h3:contains('MLB.TV')"));

                if (mlbtvNavIdx !== 2) {
                    $("#videoContainer").find(".h_module_content").last().remove().insertBefore("#videoContainer .h_module_content:eq(" + mlbtvNavIdx + ")").find(".vm_slide_thumb, .vm_mlbtv img, img.vm_mlbtv").each(function() {
                        if (!$(this).attr("src")) {
                            $(this).attr("src", $(this).closest("*[thumb]").attr("thumb"));
                        }
                    });
                }

                $("#videoContainer .vm_slide a").click(function() {
                    var idx = $("#videoContainer .h_module_content").index($(this).parents(".h_module_content")),
                        tabtext = $("#videoContainer #vm_nav li:eq(" + idx + ")").text();
                    bam.tracking.track({
                        async: {
                            isDynamic: false,
                            compName: "MLB Video Content Module",
                            compActivity: "MLB VC " + tabtext + " Video Click",
                            actionGen: true
                        }
                    }, $(this)[0]);
                });
                $("#videoContainer .vm_ftr a").click(function() {
                    bam.tracking.track({
                        async: {
                            isDynamic: false,
                            compName: "MLB Video Content Module",
                            compActivity: "MLB VC Highlights More Highlights Link Click",
                            actionGen: true
                        }
                    }, $(this)[0]);
                });
                $("#videoContainer .vm_alt2_right_inner img, #videoContainer .vm_alt2_right_inner .bam-button").click(function() {
                    var zip = $("#videoContainer .vm_alt2_right_inner input").val();
                    popWin('http://getmlbnetwork2.viewerlink.tv/viewer_results.asp?zipcode=' + zip, 'channel_locator', 990, 550, 'scrollbars=yes,resizable=yes');
                    bam.tracking.track({
                        async: {
                            isDynamic: false,
                            compName: "MLB Video Content Module",
                            compActivity: "MLB VC: MLB Network Channel Find Click",
                            actionGen: true
                        }
                    }, $(this)[0]);
                }).css({
                    cursor: "pointer"
                });
                // show random ad
                var _rotatingads = $(".vm_rotate"),
                    _idx = Math.floor(Math.random() * _rotatingads.length);
                $(".vm_rotate:eq(" + _idx + ")").show();
                delete this.init;
            },

            setTab: function(e, idx) {
                if ( !! _videoModule.heartbeat) clearInterval(_videoModule.heartbeat);
                if (idx === 2) _videoModule.rotateAds();
                var $activeContent = $(".h_module_content:eq(" + idx + ")");
                // download the images only when the tab becomes active	
                $activeContent.find(".vm_slide_thumb, .vm_mlbtv img").each(function() {
                    if (!$(this).attr("src")) {
                        $(this).attr("src", $(this).closest(".vm_slide, .vm_mlbtv").attr("thumb"));
                    }
                });
            },

            rotateAds: function() {
                var elems = $(".vm_rotate"),
                    next = $(".vm_rotate:visible").next();
                if (next.length === 0) next = $(".vm_rotate:eq(0)");
                var idx = $(".vm_rotate").index(next);
                _videoModule.heartbeat = setInterval(

                function() {
                    $(".vm_rotate:eq(" + idx + ")").hide();
                    idx++;
                    if (idx > elems.length - 1) idx = 0;
                    var $theElem = $(".vm_rotate:eq(" + idx + ")");
                    if ($.browser.safari) $theElem.show("fast");
                    else $theElem.fadeIn("slow");
                }, 15000);
            }
        },




        /**
         * 
         *
         * _loadThumbs
         * 
         * utility function to lazy load images
         *
         *
         */
        _loadThumbs = function($container) {
            $container.find("img[thumb]").each(function() {
                var $t = $(this),
                    newSrc = $t.attr("thumb");
                $t.load(function() {
                    $t.fadeIn();
                }).attr("src", newSrc).removeAttr("thumb");
            });
        },

        /**
         * 
         *
         * _createCarousel
         * 
         * utility function for initializing a jCarousel
         *
         *
         */
        _createCarousel = function(props) {
            _log("creating carousel");
            var _c = props.container,
                maxItems = props.maxItems,
                listItems = _c.find(".carousel_container li");
            _c.find(".carousel_pag li:eq(0)").addClass("pagOn").end().find(".carousel_container").show();
            //Remove any extra li items 			
            if (listItems.length > maxItems) {
                listItems.slice(maxItems).each(function() {
                    $(this).remove();
                });
            }
            //Init JCarousel Lite
            $(_c.find(".carousel_container")).jCarouselLite({
                btnPrev: _c.find(".carousel_prev"),
                btnNext: _c.find(".carousel_next"),
                scroll: 1,
                visible: 1,
                speed: 350,
                start: props.start || 0,
                vertical: !! props.vertical,
                btnGo: [
                _c.find(".carousel_pag li:eq(0)"), _c.find(".carousel_pag li:eq(1)"), _c.find(".carousel_pag li:eq(2)")],
                beforeStart: function(item) {
                    _c.find(".carousel_pag li").removeClass("pagOn");
                },
                afterEnd: function(item, isAutoScroll) {
                    var allItems = item.parent().children(),
                        allNavItems = _c.find(".carousel_pag li"),
                        itemNum = allItems.index(item);
                    if (itemNum > allNavItems.length) itemNum = 1;
                    else if (itemNum === 0) itemNum = allNavItems.length;
                    itemNum--;
                    _c.find(".carousel_pag li:eq(" + itemNum + ")").addClass("pagOn");
                    _loadThumbs(item); // lazy load images		
                }
            });
            _c.find(".carousel_next, .carousel_prev").hover(

            function() {
                $(this).addClass("on");
            }, function() {
                $(this).removeClass("on");
            });
        },


        /**
         * 
         *
         * _twitter
         * 
         *
         */
        _twitter = {
            init: function() {
                this.load();
                var that = this;
                setInterval(function() {
                    that.load();
                }, 30000);
            },
            template: '<div class="tw_tweet"><div class="tw_avatar"><img src="{%= this.user.profile_image_url %}" /></div><div class="tw_text"><a href="{%= this.user.url %}">@{%= this.user.screen_name %}</a>:{%=this.text%}</div><div class="tw_time">{%=this.created_at%}</div></div>',
            load: function() {
                _log("loading twitter data");
                var tweets, $html, ify = this.ify,
                    timeAgo = this.timeAgo,
                    template = this.template;
                $.ajax("/gdcross/components/game/mlb/twitter/realMlbInsiderTweets.json", {
                    dataType: "json",
                    timeout: 5000
                }).done(function(r) {
                    tweets = $.ensureArray(r);
                    $html = $.template(template, tweets).find(".tw_tweet:lt(3)").find(".tw_text").each(function() {
                        $(this).html(ify.clean($(this).html()));
                    }).end().find(".tw_time").each(function() {
                        $(this).html(timeAgo($(this).text()));
                    }).end();
                    $("#twitter_container").html($html);
                }).fail(function(r) {
                    _log("Twitter error: " + r.status + " " + r.statusText);
                });
            },
            /**
             * The Twitalinkahashifyer!
             * http://www.dustindiaz.com/basement/ify.html
             * http://twitter.com/javascripts/widgets/widget.js
             */
            ify: {
                link: function(tweet) {
                    return tweet.replace(/\b(((https*\:\/\/)|www\.)[^\"\']+?)(([!?,.\)]+)?(\s|$))/g, function(link, m1, m2, m3, m4) {
                        var http = m2.match(/w/) ? 'http://' : '';
                        return '<a class="twtr-hyperlink" target="_blank" href="' + http + m1 + '">' + ((m1.length > 25) ? m1.substr(0, 24) + '...' : m1) + '</a>' + m4;
                    });
                },
                at: function(tweet) {
                    return tweet.replace(/\B[@@]([a-zA-Z0-9_]{1,20})/g, function(m, username) {
                        return '@<a target="_blank" class="twtr-atreply" href="http://twitter.com/' + username + '">' + username + '</a>';
                    });
                },
                list: function(tweet) {
                    return tweet.replace(/\B[@@]([a-zA-Z0-9_]{1,20}\/\w+)/g, function(m, userlist) {
                        return '@<a target="_blank" class="twtr-atreply" href="http://twitter.com/' + userlist + '">' + userlist + '</a>';
                    });
                },
                hash: function(tweet) {
                    return tweet.replace(/(^|\s+)#(\w+)/gi, function(m, before, hash) {
                        return before + '<a target="_blank" class="twtr-hashtag" href="http://twitter.com/search?q=%23' + hash + '">#' + hash + '</a>';
                    });
                },
                clean: function(tweet) {
                    return this.hash(this.at(this.list(this.link(tweet))));
                }
            },
            /**
             * relative time calculator
             * http://twitter.com/javascripts/widgets/widget.js
             * @param {string} twitter date string returned from Twitter API
             * @return {string} relative time like "2 minutes ago"
             */
            timeAgo: function(dateString) {
                var rightNow = new Date();
                var then = new Date(dateString);
                if ($.browser.msie) {
                    // IE can't parse these crazy Ruby dates		
                    // @TODO: feature detection instead of browser
                    then = Date.parse(dateString.replace(/( \+)/, ' UTC$1'));
                }
                var diff = rightNow - then;
                var second = 1000,
                    minute = second * 60,
                    hour = minute * 60,
                    day = hour * 24,
                    week = day * 7;
                if (isNaN(diff) || diff < 0) {
                    return ""; // return blank string if unknown
                }
                if (diff < second * 2) {
                    // within 2 seconds
                    return "right now";
                }
                if (diff < minute) {
                    return Math.floor(diff / second) + " seconds ago";
                }
                if (diff < minute * 2) {
                    return "about 1 minute ago";
                }
                if (diff < hour) {
                    return Math.floor(diff / minute) + " minutes ago";
                }
                if (diff < hour * 2) {
                    return "about 1 hour ago";
                }
                if (diff < day) {
                    return Math.floor(diff / hour) + " hours ago";
                }
                if (diff > day && diff < day * 2) {
                    return "yesterday";
                }
                if (diff < day * 365) {
                    return Math.floor(diff / day) + " days ago";
                } else {
                    return "over a year ago";
                }
            }


        },


        /**
         * 
         *
         * _photogalleries
         * 
         *
         */
        _photogalleries = {
            curIndex: 0,
            init: function() {
                var that = this;
                $("#ph_prev").hover(

                function() {
                    $(this).css({
                        "background-position": "0px -37px"
                    });
                }, function() {
                    $(this).css({
                        "background-position": "0px -71px"
                    });
                }).click(function() {
                    that.showphoto(that.curIndex - 1);
                });
                $("#ph_next").hover(

                function() {
                    $(this).css({
                        "background-position": "0px 0px"
                    });
                }, function() {
                    $(this).css({
                        "background-position": "0px -108px"
                    });
                }).click(function() {
                    that.showphoto(that.curIndex + 1);
                });
                that.showphoto(0);
            },
            showphoto: function(index) {
                var strIndex, pics = bam.mlbhome.photogalleries || [];
                if (index < 0) this.curIndex = pics.length - 1;
                else if (index > pics.length - 1) this.curIndex = 0;
                else this.curIndex = index;
                strIndex = this.curIndex + 1;
                var pic = pics[this.curIndex];
                if (pic) {
                    $("#ph_slide").attr("href", pic.url).css("background-image", "url(" + pic.src + ")");
                    $("#ph_num").html(strIndex.toString() + " of " + pics.length + " galleries");
                    if (pic.gameid) {
                        var g = bam.gameId.game(pic.gameid);
                        var gDate = g.gameDate.formatDate("M/d");
                        var gAwayTeam = g.awayTeam.display_code.toUpperCase();
                        var gHomeTeam = g.homeTeam.display_code.toUpperCase();
                        $("#ph_caption").html(gDate + ": " + gAwayTeam + " @ " + gHomeTeam);
                        if (g.gameNum === "2") $("#ph_caption").append(", Game 2");
                    } else {
                        $("#ph_caption").html(pic.title);
                    }
                }
            }
        },


        /**
         *
         *
         *
         * HEADLINE STACKS
         *
         * components:
         * createStack,  setTab, teamBeats, teamHeadlines
         *
         *	
         **/
        _headlines = {

/*
        * @createStack 	
        *
        * @function
        * @args: 
        * 	url : "/gen/news/headlines.json"	[json]
        * 	container : "ul#someID"				[selector]
        *	endAt : 6							[number]
        * 	callback : function(){}				[function]
        *
        * @requires
        * 	$.template
        *
        * AK: added support for startAt config option used to avoid dupes in team beats
        * 
        * @TODO: fix bug that exists when piped links at the end of the index cause numFlotaed to be calculated incorrectly
        * 
        */
            createStack: function(p) {
                var tpl = "/mlb/components/home/y2011/headlines.tpl";
                $.ajax({
                    url: p.url,
                    type: "get",
                    timeout: 5000,
                    dataType: "json",
                    error: function(xhr) {
                        _log("Error: " + xhr.status + " " + xhr.statusText);
                    },
                    success: function(json) {
                        var arr = bam.util.ensureArray(json.members),
                            $html = $.template(tpl, arr),
                            numFloated = $html.find(".hl_float").length,
                            startAt = p.startAt || 0,
                            endAt = p.endAt + Math.floor(numFloated / 2),
                            // increment number of headlines displayed if there are any floats			
                            $headlines = $html.find("dd").slice(startAt, endAt);
                        $(p.container).empty().append($headlines).find(".hl_float:odd").addClass("hl_float_odd").after("<dd class='hl_clear' />");
                        if ($.isFunction(p.success)) {
                            p.success(json);
                        }
                    },
                    complete: function() {
                        if ($.isFunction(p.callback)) {
                            p.callback();
                        }
                    }
                });
            },

            createHeadlinesCarousel: function() {
                _log("creating headlines carousel");
                var btnNext = "#hl_carousel_right",
                    btnPrev = "#hl_carousel_left",
					random = $("#hl_carousel #hl_carousel_container ul").data("random");
                $("#hl_carousel #hl_carousel_container").jCarouselLite = null;

                _log("random is on: " + random);


				$(btnNext).unbind("click");
                $(btnPrev).unbind("click");


                var rand = Math.round(Math.random());
                _log("rand=" + rand);
				
                $("#hl_carousel #hl_carousel_container").jCarouselLite({
                    btnNext: btnNext,
                    btnPrev: btnPrev,
                    visible: 1,
                    start: (random) ? rand : 0,
                    easing: "easeOutCirc",
                    afterEnd: function(elem) {
                        var imgsrc = "";
                        elem.find("img[thumb]").each(function() {
                            imgsrc = $(this).attr("thumb");
                            $(this).hide().attr("src", imgsrc).removeAttr("thumb").fadeIn();
                        });
                    },
                    afterInit: function(elem) {
                        var
                        imgsrc = "",
                            tracking = {
                                isDynamic: false,
                                compName: "MLB Headline Stack",
                                actionGen: true
                            },
                            aNext = {
                                compActivity: "MLB Headline Stack: Carousel Next Click"
                            },
                            aPrev = {
                                compActivity: "MLB Headline Stack: Carousel Previous Click"
                            };
                        $(btnPrev).click(function() {
                            bam.tracking.track({
                                async: $.extend(aPrev, tracking)
                            });
                        });
                        $(btnNext).click(function() {
                            bam.tracking.track({
                                async: $.extend(aNext, tracking)
                            });
                        });
                        elem.find("img[thumb]").each(function() {
                            imgsrc = $(this).attr("thumb");
                            $(this).hide().attr("src", imgsrc).removeAttr("thumb").fadeIn();
                        });
                    }
                });
            },

            // _headlines.setTab
            setTab: function(e, idx) {
                var datasources = ["/gen/news/headlines.json", "/gen/home/featured.json"],
                    container = "#headlinesContainer .h_module_content:eq(" + idx + ") dl.hl_list",
                    $footer_right = $("#headlinesContainer .hl_ftr_right");
                if ($(container + " li").length === 0 && idx < 2) {
                    _headlines.createStack({
                        url: datasources[idx],
                        container: container,
                        endAt: 8,
                        callback: _headlines.createHeadlinesCarousel
                    });
                }
            }
        },


        /**
         * 
         *
         * _navbuttons
         * 
         * utility function for setting up generic tabbed navigation for content modules
         *
         *
         */
        _navbuttons = function() {
            $('#homepage_container ul.navbuttons li:first-child').addClass('first');
            $('#homepage_container ul.navbuttons li:last-child').addClass('last');
            var isfirstclick = true,
                setContent = function(e, idx, cb) {
                    var $target = $(e.target),
                        $container = $target.closest(".h_module"),
                        $activeContent = $container.find(".h_module_content:eq(" + idx + ")"),
                        compName = $container.find(".navbuttons").attr("compName");
                    if (!compName) compName = "MLB Tab Navigation";
                    $activeContent.siblings(".h_module_content").hide();
                    $activeContent.fadeIn(cb());
                    if (!isfirstclick) {
                        bam.tracking.track({
                            async: {
                                isDynamic: true,
                                compName: ((compName === "MLB VC Module") ? "MLB Video Content Module" : compName),
                                compActivity: compName + ": " + $target.closest("li").find("h3").text() + " Tab Click",
                                actionGen: true
                            }
                        }, $target);
                    }
                },
                actions = {
                    "vm_nav": _videoModule.setTab,
                    "hl_nav": _headlines.setTab
                }; // add custom functions here. the property name must equal the id of the container ul			
            $doc.selector = "ul.navbuttons li";
            $doc.live("click", function(e) {
                var $li = $(this);
                if ($li.parent().children().length > 1) {
                    var idx = $li.parent().children("li").index($li);
                    $li.find("div").andSelf().addClass("tb_on");
                    $li.siblings().removeClass("tb_on").find("li,div").removeClass("tb_on");
                    setContent(e, idx, function() {
                        var key = $li.parent().attr("id");
                        var action = actions[key];
                        if ($.isFunction(action)) {
                            action(e, idx);
                        }

                    });
                }
            });
            $("ul.navbuttons li").show();
            $("ul.navbuttons").each(function() {
                var $container = $(this),
                    $items = $container.find("li");
                if ($items.length > 1) {
                    isfirstclick = true;
                    var $default_tab = $container.find("li.h_module_nav_default");
                    if ($default_tab.length > 0) {
                        $container.find("li").css("cursor", "pointer");
                        $default_tab.find("h3").click();
                        isfirstclick = false;
                    } else {
                        var rand = Math.floor(Math.random() * $items.length);
                        $container.find("li").css("cursor", "pointer").end().find("li:eq(" + rand + ")").find("h3").click();
                        isfirstclick = false;
                    }
                } else {
                    $(this).closest(".h_module").find(".h_module_content").fadeIn();
                }
            });

        },





        /**
         * 
         *
         * _miniStandings
         * 
         * New Dynamic Mini-Standings code <Sam>
         *
         *
         */
        _miniStandings = (function() {
            var bhp = bam.homePath;

            //Load dependencies
            bam.loadSync(bhp + "bam.datetime.js", bhp + "bam.cookies.js", bhp + "bam.datagrid2.js", bhp + "bam.ajaxHelper.js");

            // Helper Functions
            //Cached jQuery selector getter


            function $get(selector) {
                return $get.cache[selector] = $get.cache[selector] || $(selector);
            }
            $get.cache = {};
            //Formats a string by replacing positional $n placeholders with arguments
            //ex: formatString("this is a %0", "test") -> this is a test


            function formatString() { // Args: str, $0, $1 ....
                if (arguments[1]) {
                    var args = Array.prototype.slice.apply(arguments, [1]),
                        rx = /%([0-9])/g;
                    return arguments[0].replace(rx, function($0, $1) {
                        return args[~~ + $1] || '';
                    });
                }
            }
            // End Helper Functions 
            var RESULTS_MAX = 6,
                SYS_YEAR = 2010,
                //overwriten in mvc.init
                DEFAULT_TEAM = bam.cookies.get('mlbteamcookie'),
                SEASON_LEAGUES = {
                    regular: [103, 104],
                    spring: [103, 104, 114, 115]
                },
                LEAGUES = {
                    AL: 103,
                    NL: 104,
                    CL: 114,
                    GL: 115
                },
                DIVISIONS = {
                    103: {
                        West: 200,
                        East: 201,
                        Central: 202
                    },
                    //AL
                    104: {
                        West: 203,
                        East: 204,
                        Central: 205
                    } //NL
                },
                DIVISION_TEAMS = {
                    200: {
                        oak: 0,
                        ana: 0,
                        sea: 0,
                        tex: 0
                    },
                    //AL - West
                    201: {
                        bos: 0,
                        bal: 0,
                        nyy: 0,
                        tb: 0,
                        tor: 0
                    },
                    //AL - East
                    202: {
                        cws: 0,
                        cle: 0,
                        det: 0,
                        kc: 0,
                        "min": 0
                    },
                    //AL - Central
                    203: {
                        ari: 0,
                        col: 0,
                        la: 0,
                        sd: 0,
                        sf: 0
                    },
                    //NL - West
                    204: {
                        was: 0,
                        fla: 0,
                        nym: 0,
                        phi: 0,
                        atl: 0
                    },
                    //NL - East
                    205: {
                        chc: 0,
                        cin: 0,
                        hou: 0,
                        mil: 0,
                        pit: 0,
                        stl: 0
                    } //NL - Central
                },
                SHOW_PREFIX_LEGEND = false,
                DIVISION_NAMES = {
                    East: "East",
                    Central: "Central",
                    West: "West",
                    0: "East",
                    1: "Central",
                    2: "West"
                },
                SEASON_STATUS_URI = "/lookup/named.properties_info_events_season.bam?season=%0&sport_code='mlb'&org_id=1",
                SPRING_SEASON_URI = "/lookup/named.standings_spring_repeater.bam?" + "season=%0&" + $.param({
                    league_id: SEASON_LEAGUES.spring
                }, true),
                REGULAR_SEASON_URI = "/lookup/named.standings_all_league_repeater.bam?" + "sit_code='h0'&season=%0&standings_all.col_in=division_champ,place,wild_card,playoffs_sw,division_id,division,team_short,file_code,w,l,pct,gb&" + $.param({
                    league_id: SEASON_LEAGUES.regular
                }, true),
                WILD_CARD_URI = "/lookup/named.standings_wild_card_league_repeater.bam?" + "sit_code='h0'&season=%0&results=5&standings_wild_card.col_in=team_short,file_code,w,l,pct,gb,wild_card&" + $.param({
                    league_id: SEASON_LEAGUES.regular
                }, true),
                EXHIBITION_LINK = "/mlb/standings/exhibition.jsp",
                NO_DATA_MSG = "Data is currently unavailable",
                ACTIVE = "active",
                REL = "rel",
                XML = "xml",
                COMMON_COL_WIDTH = "25px",
                CLUB_PROPS, COLUMN_DEFS = [{
                    title: "Team",
                    width: "135px",
                    dataField: "team_short",
                    decorator: function() {
                        var prefixedName = mvc.view.setTeamPrefix.apply(this, arguments),
                            file_code = this.rawData.file_code,
                            clubUrl;
                        if (CLUB_PROPS && (file_code in CLUB_PROPS)) {
                            clubUrl = CLUB_PROPS[file_code].club_common_url;
                            prefixedName = "<a href=\"http://" + clubUrl + "\">" + prefixedName + "</a>";
                        }
                        return prefixedName;
                    }
                }, {
                    title: "W",
                    width: COMMON_COL_WIDTH,
                    dataField: "w"
                }, {
                    title: "L",
                    width: COMMON_COL_WIDTH,
                    dataField: "l"
                }, {
                    title: "PCT",
                    width: COMMON_COL_WIDTH,
                    dataField: "pct"
                }, {
                    title: "GB",
                    width: COMMON_COL_WIDTH,
                    dataField: "gb"
                }, {
                    title: "wc",
                    visible: false,
                    dataField: "wild_card"
                }, {
                    title: "dc",
                    visible: false,
                    dataField: "division_champ"
                }, {
                    title: "po",
                    visible: false,
                    dataField: "playoffs_sw"
                }],
                DATAGRID_BASE = {
                    tableClass: "ministandings",
                    noResultsMessage: NO_DATA_MSG,
                    sortable: false,
                    columns: COLUMN_DEFS
                },
                AL_GRID = new bam.datagrid.DataGrid(DATAGRID_BASE),
                NL_GRID = new bam.datagrid.DataGrid(DATAGRID_BASE),
                // CL/GL - to come 
                utils = {

                    //	Returns a random number from a range of numbers
                    //	@from - starting number
                    //	@to - ending number
                    getRandomNumber: function(from, to) {
                        from = ~~ + from;
                        to = ~~ + to;
                        return Math.floor(Math.random() * to - from + 1) + from;
                    },

                    //	Retrieves objec data nested deep inside an object
                    //	@obj - object that contains data (i.e. {foo:[{test:{inside:'data'}]} )
                    //	@pattern - members data inline pattern (i.e. "foo[0].test.inside")
                    getDeep: function(obj, pattern) {
                        if (obj && typeof(pattern) === "string") {
                            var tokens = pattern.split('.'),
                                rxIndex = /(.+)\[([0-9]+)\]/,
                                parts, index, out;
                            $.each(tokens, function(i, token) {
                                parts = token.match(rxIndex);
                                if (parts) {
                                    token = parts[1];
                                    index = ~~ + parts[2];
                                    if (token in (out || obj) && typeof((out || obj)[token][index]) !== "undefined") {
                                        out = (out || obj)[token][index];
                                    }
                                } else if (token in (out || obj)) {
                                    out = (out || obj)[token];
                                }
                            });
                            return out;
                        }
                    }
                },
                dao = {
                    //Lookup service wrapper for Season Schedule
                    seasonScheduleLookup: bam.ajaxHelper.createInstance({
                        traditional: true,
                        cache: {},
                        seasonStart: 0,
                        springTrainingStart: 0,
                        springTrainingEnd: 0,
                        allStarEnd: 0,
                        dataType: XML,
                        load: function(season, cb) {
                            var that = this;
                            this.url = formatString(SEASON_STATUS_URI, season);
                            if ($.isFunction(cb)) {
                                this.makeRequest(function(data) {
                                    that.cache = data;
                                    cb();
                                });
                            }
                        },
                        // Helpers 
                        //Returns regular season start date (cached)
                        getSeasonStartDate: function() {
                            var out = 0,
                                date;
                            if (this.cache) {
                                if (this.seasonStart) {
                                    out = this.seasonStart;
                                } else {
                                    var root = this.cache;
                                    date = utils.getDeep(root, "org_history[0].queryResults[0].row[0].first_date_seas");
                                    out = this.seasonStart = date && bam.datetime.parseISODate(date);
                                }
                            }
                            return out;
                        },
                        // Returns Date based on schedule event name <Date>
                        //	@eventName - name of the event to filter by (i.e.Spring Training Start) 
                        getScheduleEventDate: function(eventName) {
                            if (this.cache) {
                                var root = this.cache,
                                    evt = utils.getDeep(root, "root.schedule_event_info[0].queryResults[0].row"),
                                    date = evt && evt.getNodesByAttribute("event", eventName),
                                    out = date && date.length && bam.datetime.parseISODate(date[0].game_date);
                                return out;
                            }
                        },
                        // Returns Spring Training Start date <Date> 
                        getSpringTrainingStart: function() {
                            var out = 0,
                                date;

                            if (this.springTrainingStart) {
                                out = this.springTrainingStart;
                            } else {
                                date = this.getScheduleEventDate("Spring Training Start");
                                out = this.springTrainingStart = date;
                            }
                            return out;
                        },
                        // Returns Spring Training End date <Date> 
                        getSpringTrainingEnd: function() {
                            var out = 0,
                                date;

                            if (this.springTrainingEnd) {
                                out = this.springTrainingEnd;
                            } else {
                                date = this.getScheduleEventDate("Spring Training End");
                                out = this.springTrainingEnd = date;
                            }
                            return out;
                        },
                        // Returns All-Star Start date <Date> 
                        getAllStarEnd: function() {
                            var out = 0,
                                date;

                            if (this.allStarEnd) {
                                out = this.allStarEnd;
                            } else {
                                date = this.getScheduleEventDate("All-Star End");
                                out = this.allStarEnd = date;
                            }
                            return out;
                        },

                        //	Returns a season year that should be used for all lookups
                        //	@now - system date for today
                        getSeason: function(now) {
                            if (this.cache) {
                                var season_start = this.getSeasonStartDate(),
                                    spring_training_start = this.getSpringTrainingStart(),
                                    earliest = Math.min(this.seasonStart, this.springTrainingStart);

                                return now.valueOf() < earliest ? season_start.getFullYear() - 1 : season_start.getFullYear();
                            }
                        },

                        //	Returns true if Spring training is in affect
                        //	@now - system date for today				
                        isSpringTraining: function(now) {
                            if (now) {
                                var spring_training_start = this.getSpringTrainingStart(),
                                    spring_training_end = this.getSpringTrainingEnd(),
                                    season_start = this.getSeasonStartDate();
                                //If now is within a spring training range and reg. season start is greater then spring season end.
                                return now.valueOf() >= spring_training_start.valueOf() && now.valueOf() <= spring_training_end.valueOf() && season_start.valueOf() > spring_training_end.valueOf();
                            }
                        },

                        //	Returns true if wildcard filter tab should be showing
                        //	@now - system date for today
                        isWildcardShowing: function(now) {
                            if (now) {
                                var all_star_end = this.getAllStarEnd();
                                return all_star_end && now.valueOf() >= all_star_end.valueOf();
                            }
                        }
                    }),
                    //Lookup service wrapper for regular season data
                    regSeasonLookup: bam.ajaxHelper.createInstance({
                        traditional: true,
                        cache: {},
                        dataType: XML,
                        load: function(cb) {
                            var that = this;
                            this.url = formatString(REGULAR_SEASON_URI, SYS_YEAR);
                            if ($.isFunction(cb)) {
                                this.makeRequest(function(data) {
                                    that.cache = data;
                                    cb();
                                });
                            }
                        },
                        getStandings: function(league) {
                            return mvc.model.extractLeagueData.call(this, "standings_all", league);
                        },
                        getDivisionStandings: function(league, div) {
                            league = this.getStandings(league);
                            return mvc.model.filterByDivision(div, league);
                        },
                        onFail: function() {
                            mvc.events.onDataError();
                        }
                    }),
                    //Lookup service wrapper for Spring Training season data
                    springSeasonLookup: bam.ajaxHelper.createInstance({
                        traditional: true,
                        cache: {},
                        dataType: XML,
                        load: function(cb) {
                            var that = this;
                            this.url = formatString(SPRING_SEASON_URI, SYS_YEAR);
                            if ($.isFunction(cb)) {
                                this.makeRequest(function(data) {
                                    that.cache = data;
                                    cb();
                                });
                            }
                        },
                        getStandings: function(league) {
                            return mvc.model.extractLeagueData.call(this, "standings_spring", league);
                        },
                        onFail: function() {
                            mvc.events.onDataError();
                        }
                    }),
                    //Lookup service wrapper for Wild Card data
                    wildcardLookup: bam.ajaxHelper.createInstance({
                        traditional: true,
                        cache: {},
                        dataType: XML,
                        load: function(cb) {
                            var that = this;
                            this.url = formatString(WILD_CARD_URI, SYS_YEAR);
                            if ($.isFunction(cb)) {
                                this.makeRequest(function(data) {
                                    that.cache = data;
                                    cb();
                                });
                            }
                        },
                        getStandings: function(league) {
                            return mvc.model.extractLeagueData.call(this, "standings_wild_card", league);
                            //return mvc.model.extractWCData.call(this, "standings_wild_card");
                        }
                    })
                },
                mvc = {
                    model: {
                        //Extracts Wild Card data from a lookup service
                        extractWCData: function(dataset) {
                            var out = [];
                            if (this.cache && (dataset in this.cache)) {
                                out = this.cache[dataset].queryResults.row;
                            }
                            return out;
                        },
                        //Extracts League data from lookup service
                        extractLeagueData: function(dataset, league) {
                            var out = [];
                            if (this.cache && (dataset in this.cache) && !! league) {
                                league = this.cache[dataset].getNodesByAttribute("league_id", String(league));
                                if ( !! league && !! league.length) {
                                    out = utils.getDeep(league[0], "queryResults[0].row");
                                }
                            }
                            return out;
                        },
                        //Applies division filter to a league data
                        filterByDivision: function(division, data) {
                            var out = [];
                            if (data && data.length) {
                                out = data.getNodesByAttribute("division_id", String(division));
                            }
                            return out;
                        },
                        //Populates datagrid with data
                        fillDatagrid: function(dgObj, data, userLimit) {
                            if (data && data.length) {
                                dgObj.clearData();
                                $.each(data.slice(0, (~~ + userLimit || RESULTS_MAX)), function(i, row) {
                                    dgObj.insertRow(row);
                                });
                            }
                        }
                    },
                    view: {
                        //Pre-pends a prefix to the team name (runs in the scope of the datagrid.row)
                        setTeamPrefix: function(o) {
                            var out = o.value,
                                wild_card = this.cell("wild_card").val(),
                                division_champ = this.cell("division_champ").val(),
                                playoffs_sw = this.cell("playoffs_sw").val(),
                                prefix = (division_champ === 'Y') ? "y-" : (division_champ === 'N' && (playoffs_sw === 'Y' || playoffs_sw === 'C')) ? "x-" : (wild_card === 'Y') ? "w-" : "";

                            if ( !! prefix) {
                                SHOW_PREFIX_LEGEND = true;
                            }

                            return prefix + out;
                        },
                        //Render a single standings grid
                        renderGrid: function(dgObj, data, to) {
                            mvc.model.fillDatagrid(dgObj, data);
                            dgObj.render(to);
                        },
                        //Refreshes grid content
                        refreshGrid: function(dgObj, data) {
                            mvc.model.fillDatagrid(dgObj, data);
                            dgObj.refreshView();
                        },
                        //Hide division links above grid (east, west, etc..)
                        hideDivisionFilters: function() {
                            $get("div.divisionLinks").hide();
                        },
                        //Show Wild Card filter
                        showWCFilters: function() {
                            /*
							$get("div.divisionLinks li.wc").css({
                                display: "inline"
                            });
							*/
                        },
                        //Show prefixes legend
                        showLegend: function() {
                            $get("#standingsLegend").show();
                        },
                        //Restes href for a Full Standings link (spring is diffrent then regular)
                        setFullStandingsLink: function(href) {
                            if (href) {
                                $get("#standingsFullLink").attr("href", href);
                            }
                        },
                        //Clears active class fom filter links
                        resetActiveLinks: function(parent) {
                            if (parent) {
                                $get(parent + " div.divisionLinks li").removeClass(ACTIVE);
                            }
                        },
                        //Sets default division link as active (by rel value)
                        setDefaultDivisionActive: function() {
                            $.each(arguments, function(i, div) {
                                if (div) {
                                    $get("div.divisionLinks li[rel=" + div + "]").addClass(ACTIVE);
                                }
                            });
                        }
                    },
                    controller: {
                        //Main function that initializes the component
                        init: function(sysdateStr, narrowband) {
                            var sysdate = bam.datetime.parseYMD(sysdateStr),
                                sysyear = sysdate.getFullYear(),
                                defDivAL, defDivNL, isSpringTraining = false,
                                isWildCardShowing = false;
                            CLUB_PROPS = bam.mlbhome.getClubProperties();
                            // @TODO: 
                            //1 - Load season schedule
                            dao.seasonScheduleLookup.load(sysyear, function() {
                                //2 - Determine/set season year
                                SYS_YEAR = dao.seasonScheduleLookup.getSeason(sysdate);
                                //3 - Determine Season Mode (Regular | Spring)
                                isSpringTraining = dao.seasonScheduleLookup.isSpringTraining(sysdate);
                                if (isSpringTraining) {
                                    dao.springSeasonLookup.load(function() {
                                        RESULTS_MAX = 5;
                                        mvc.view.hideDivisionFilters();
                                        mvc.view.renderGrid(AL_GRID, dao.springSeasonLookup.getStandings(LEAGUES.AL), "standingsTableAL");
                                        mvc.view.renderGrid(NL_GRID, dao.springSeasonLookup.getStandings(LEAGUES.NL), "standingsTableNL");
                                        mvc.view.setFullStandingsLink(EXHIBITION_LINK);
                                    });
                                } else {
                                    defDivAL = mvc.controller.getDefaultDivision(LEAGUES.AL);
                                    defDivNL = mvc.controller.getDefaultDivision(LEAGUES.NL);
                                    mvc.view.setDefaultDivisionActive(defDivAL, defDivNL);
                                    if (defDivAL && defDivNL) {
                                        dao.regSeasonLookup.load(function() {
                                            mvc.view.renderGrid(AL_GRID, dao.regSeasonLookup.getDivisionStandings(LEAGUES.AL, defDivAL), "standingsTableAL");
                                            mvc.view.renderGrid(NL_GRID, dao.regSeasonLookup.getDivisionStandings(LEAGUES.NL, defDivNL), "standingsTableNL");
                                            //4 - Determine Wildcard Mode
                                            isWildCardShowing = dao.seasonScheduleLookup.isWildcardShowing(sysdate);
                                            if (isWildCardShowing) {
                                                dao.wildcardLookup.load(function() {
                                                    mvc.view.showWCFilters();
                                                });
                                            }
                                            //5 - Render Leagues
                                            if (SHOW_PREFIX_LEGEND) {
                                                mvc.view.showLegend();
                                            }
                                        });
                                    }
                                }
                            });
                        },
                        //Retrieves default division based on cookie data
                        getDefaultDivision: function(league) {
                            var rnd = utils.getRandomNumber(0, 2),
                                out = DIVISION_NAMES[rnd];

                            if (DEFAULT_TEAM in DIVISION_TEAMS[DIVISIONS[league].East]) {
                                out = DIVISION_NAMES.East;
                            } else if (DEFAULT_TEAM in DIVISION_TEAMS[DIVISIONS[league].Central]) {
                                out = DIVISION_NAMES.Central;
                            } else if (DEFAULT_TEAM in DIVISION_TEAMS[DIVISIONS[league].West]) {
                                out = DIVISION_NAMES.West;
                            }

                            return DIVISIONS[league][out];
                        },
                        //Sets division filter based on rel data stored in a link
                        setDivision: function(league, division) {
                            var divData, dgObj = (league === LEAGUES.AL) ? AL_GRID : NL_GRID;
                            if (division === "wc") {
                                divData = dao.wildcardLookup.getStandings(league);
                                mvc.view.refreshGrid(dgObj, divData);
                            } else {
                                divData = dao.regSeasonLookup.getDivisionStandings(league, ~~ + division);
                                mvc.view.refreshGrid(dgObj, divData);
                            }
                        }
                    },
                    events: {
                        //Fires if data could not be retrieved
                        onDataError: function() {
                            $get("#standingsTableAL, #standingsTableNL").html(NO_DATA_MSG);
                        }
                    }
                };

            //Window load events
            $doc.selector = "#standingsAL div.divisionLinks li";
            $doc.live("click", function(e) {
                if (!e.button) {
                    mvc.view.resetActiveLinks("#standingsAL");
                    var $this = $(this).addClass(ACTIVE),
                        div = $this.attr(REL);
                    mvc.controller.setDivision(LEAGUES.AL, div);
                }
            });
            $doc.selector = "#standingsNL div.divisionLinks li";
            $doc.live("click", function(e) {
                if (!e.button) {
                    mvc.view.resetActiveLinks("#standingsNL");
                    var $this = $(this).addClass(ACTIVE),
                        div = $this.attr(REL);
                    mvc.controller.setDivision(LEAGUES.NL, div);
                }
            });
            //Expose mvc.controller interface to public
            return mvc.controller;
        })(),
        /* Mini-Standings End */


        /**
         * 
         *
         * _leaders
         * 
         *
         */





        _leaders = (function() {
            var $doc = $(document),
                _pitchingStats = ["w", "sv", "so", "era", "whip"],
                _battingStats = ["avg", "r", "hr", "rbi", "sb"],
                _season = 2011,
                _isSpringTraining = false,
                _isRegularSeason = true,
                _isPostseason = false,
                _isOffseason = false,
                _cache = {
                    mlb: {},
                    al: {},
                    nl: {}
                },
                _gameType = (_isPostseason) ? ["'D'", "'L'", "'W'"] : (_isSpringTraining) ? "'S'" : "'R'",
                _numResults = 5,
                _currentBattingStat = "",
                _currentPitchingStat = "",
                _currentLeague = "",

                _wrapArrValuesWithQuotes = function(arr) {
                    return $.map(arr, function(n) {
                        return "'" + n + "'";
                    });
                },

                _getLeaderHTML = function(leader, stat) {
                    var leaderID = leader.player_id,
                        leaderName = leader.name_last,
                        leaderTeam = leader.team_abbrev,
                        leaderHTML;
                    leaderHTML = "<a class='headshot' href='/team/player.jsp?player_id=" + leaderID + "'>";
                    leaderHTML += "<img alt='" + leaderName + "' src='/images/players/assets/68_" + leaderID + ".png' border='0' />";
                    leaderHTML += "</a>";
                    leaderHTML += "<div class='leader_text'><a href='/team/player.jsp?player_id=" + leaderID + "'><b>" + leaderName + "</b></a><br />" + leaderTeam + "</div>";
                    leaderHTML += "<div class='leader_value'>" + leader[stat] + "</div>";
                    return leaderHTML;
                },


                _getRunnersUpHTML = function(players, stat) {
                    var i = 1,
                        rowHTML = "",
                        rLen = players.length,
                        place = 1,
                        player, previousPlayer = players[0],
                        tieValue, tieText = "players",
                        numTies = 0,
                        statValue;
                    if (rLen > _numResults) {
                        _log("Invoking tie logic. tieValue=" + tieValue);
                        tieValue = players[_numResults][stat];
                        if (players[_numResults - 1][stat] === players[_numResults - 2][stat]) tieText = "others";
                    }
                    for (; i < rLen; i++) {
                        player = players[i];
                        statValue = player[stat];
                        if (statValue === tieValue) numTies++;
                        if (statValue !== previousPlayer[stat]) place = i + 1;
                        if (i < _numResults) {
                            if (i % 2) rowHTML += "<tr>";
                            else rowHTML += "<tr class='stripe'>";
                            rowHTML += "<td>" + place + ".</td>";
                            if (i === (_numResults - 1) && !! numTies) {
                                rowHTML += "<td colspan='2'>" + (rLen - (_numResults - 1)) + " " + tieText + " tied</td>";
                            } else {
                                rowHTML += "<td><a class='player_link' href='/team/player.jsp?player_id=" + player.player_id + "'>" + player.name_last + "</a></td>";
                                rowHTML += "<td>" + player.team_abbrev + "</td>";
                            }
                            rowHTML += "<td>" + statValue + "</td>";
                            rowHTML += "</tr>";
                        }
                        previousPlayer = player;
                    }
                    return rowHTML;
                },


                _write = function(stat, league) {
                    _log("_write. stat=" + stat + ", league=" + league);
                    var side = (~$.inArray(stat, _battingStats)) ? "batting" : "pitching",
                        rows = _cache[league][stat];
                    $c = $("#league_leaders_" + side).find(".main_stats");
                    if (side === "batting") _currentBattingStat = stat;
                    else _currentPitchingStat = stat;
                    $c.hide().find(".leader_container").html(_getLeaderHTML(rows[0], stat)).end().find("table tbody").html(_getRunnersUpHTML(rows, stat)).end().fadeIn();
                },



                _getData = function(stat, league, callback) {
                    _log("_getData. stat=" + stat + ",league=" + league);
                    var repeater_columns, sort_columns, serviceURL = "/lookup/json/named.",
                        cacheKey = ( !! league && league != "mlb") ? league : "mlb",
                        league_code = ( !! league && league != "mlb") ? {
                            "league_code": "'" + league.toUpperCase() + "'"
                        } : {
                            "sport_code": "'mlb'"
                        },
                        serviceParams = {
                            "results": _numResults,
                            "season": _season,
                            "game_type": _gameType
                        },
                        side = (~$.inArray(stat, _battingStats)) ? "batting" : (~$.inArray(stat, _pitchingStats)) ? "pitching" : "",
                        pitching_repeater = (_isSpringTraining) ? "leader_spring_pitching_rptr" : "leader_pitching_repeater",
                        batting_repeater = (_isSpringTraining) ? "leader_spring_hitting_rptr" : "leader_hitting_repeater",
                        player_info = ["name_last", "team_abbrev", "player_id"];
                    if (!side) return false;
                    if (side === "batting") {
                        serviceURL += batting_repeater + ".bam";
                        repeater_columns = (_isSpringTraining) ? {
                            "leader_spring_hitting_rptr.col_in": _battingStats.concat(player_info)
                        } : {
                            "leader_hitting_repeater.col_in": _battingStats.concat(player_info)
                        };
                        sort_columns = {
                            "sort_column": _wrapArrValuesWithQuotes(_battingStats)
                        };
                    } else {
                        serviceURL += pitching_repeater + ".bam";
                        repeater_columns = (_isSpringTraining) ? {
                            "leader_spring_pitching_rptr.col_in": _pitchingStats.concat(player_info)
                        } : {
                            "leader_pitching_repeater.col_in": _pitchingStats.concat(player_info)
                        };
                        sort_columns = {
                            "sort_column": _wrapArrValuesWithQuotes(_pitchingStats)
                        };
                    }
                    $.extend(serviceParams, repeater_columns, sort_columns, league_code);
                    $.ajax({
                        url: serviceURL,
                        data: serviceParams,
                        dataType: "json",
                        error: function(data, status, e) {
                            _log("error");
                        },
                        beforeSend: function() {
                            $("#league_leaders_" + side).find(".main_stats").hide().end().addClass("loadingMask");
                        },
                        success: function(json) {
                            var i = 0,
                                statName, curr, parentObj = (side === "batting") ? json[batting_repeater].leader_hitting_mux : json[pitching_repeater].leader_pitching_mux;
                            for (; i < parentObj.length; i++) {
                                curr = parentObj[i];
                                statName = curr.sort_column.replace(/\'/g, "");
                                _cache[cacheKey][statName] = curr.queryResults.row;
                            }
                            _log("Data loaded. Stat = " + stat + ". League = " + league + ". Displaying cache below");
                            _log(_cache);
                            $("#league_leaders_" + side).removeClass("loadingMask");
                            if ($.isFunction(callback)) callback();
                        }
                    });

                },

				


                _writeNav = function() {
                    var b = 0,
                        p = 0,
                        liStr = "",
                        stat = "",
                        $batting = $("#league_leaders_batting").find(".nav"),
                        $pitching = $("#league_leaders_pitching").find(".nav");
                    for (; b < _battingStats.length; b++) {
                        stat = _battingStats[b];
                        liStr += "<li data-stat='" + stat + "'>" + stat + "</li>";
                    }
                    $batting.append(liStr);
                    liStr = "";
                    for (; p < _pitchingStats.length; p++) {
                        stat = _pitchingStats[p];
                        liStr += "<li data-stat='" + stat + "'>" + stat + "</li>";
                    }
                    $pitching.append(liStr);
                },


                _self = {
                    init: function(cfg) {
                        var bRand = Math.floor(Math.random() * _battingStats.length),
                            pRand = Math.floor(Math.random() * _pitchingStats.length);
                        _writeNav();
                        $("#league_leaders_batting .nav li:eq(" + bRand + ")").addClass("active");
                        $("#league_leaders_pitching .nav li:eq(" + pRand + ")").addClass("active");
                        _self.load(_battingStats[bRand]);
                        _self.load(_pitchingStats[pRand]);
                    },
                    load: function(stat, league) {
                        if (!league) league = "mlb";
                        _log("loading " + stat + " for " + league);
                        _currentStat = stat;
                        _currentLeague = league;
                        if (_cache[league] && _cache[league][stat]) {
                            _write(stat, league);
                        } else {
                            _getData(stat, league, function() {
                                _write(stat, league);
                            });
                        }
                    }
                };


            // Events
            $doc.selector = "#league_leaders_container .nav li";
            $doc.live("click", function(e) {
                var stat = $(this).data("stat");
                $(this).siblings().removeClass("active").end().addClass("active");
                _self.load(stat, _currentLeague);
            });


            $doc.selector = "#league_leaders_batting .league_links li";
            $doc.live("click", function(e) {
                var league = $(this).data("league");
                $(this).siblings().removeClass("active").end().addClass("active");
                _self.load(_currentBattingStat, league);
            });

            $doc.selector = "#league_leaders_pitching .league_links li";
            $doc.live("click", function(e) {
                var league = $(this).data("league");
                $(this).siblings().removeClass("active").end().addClass("active");
                _self.load(_currentPitchingStat, league);
            });

            return _self;

        })(),
        // end _leaders


        /**
         * 
         *
         * _track
         * 
         * @TODO: bind all tracking with live() to *[data-tracking]. can copy gameticker tracking.
         *
         */
        _track = function() {

            _log("_track");

            //headlines
            $doc.selector = "#headlinesContainer .hl_ftr_right, #headlinesContainer .h_module_content a";
            $doc.live("click", function(e) {
                var $target = $(e.target).closest("a"),
                    $container = $target.closest("#headlinesContainer"),
                    $activetab = $target.closest(".h_module_content"),
                    idx = $container.find(".h_module_content").index($activetab),
                    component = "MLB Headline Stack",
                    tabtext = $container.find(".navbuttons li:eq(" + idx + ")").find("h3").text(),
                    clicktext = "Headline Click",
                    activity = "";
                if ($target.hasClass("hl_ftr_left")) clicktext = "More Click";
                activity = component + ": " + tabtext + " " + clicktext;
                if ($target.hasClass("hl_ftr_right")) activity = component + ": RSS Click";
                else if ($target.hasClass("hl_carousel_link")) activity = component + ": Carousel Content Click";
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: component,
                        compActivity: activity,
                        actionGen: true
                    }
                });
            });


            //standings
            $doc.selector = "#standingsContent .divisionLinks";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Standings/Leaders',
                        compActivity: 'MLB Standings/Leaders: Standings: Division Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#standingsFullLink";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Standings/Leaders',
                        compActivity: 'MLB Standings/Leaders: Standings: Full Standings Click',
                        actionGen: true
                    }
                });
            });


            //leaders
            $doc.selector = "#league_leaders_batting .nav";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Standings/Leaders',
                        compActivity: 'MLB Standings/Leaders: Leaders: Batting Stat Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#league_leaders_pitching .nav";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Standings/Leaders',
                        compActivity: 'MLB Standings/Leaders: Leaders: Pitching Stat Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#league_leaders_more_links";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Standings/Leaders',
                        compActivity: 'MLB Standings/Leaders: Leaders: More Stats Click',
                        actionGen: true
                    }
                });
            });

            //twitter
            $doc.selector = "#twitter_container .twitter_blurb";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Twitter',
                        compActivity: 'MLB Twitter: Content Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#twitter_container .more a";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Twitter',
                        compActivity: 'MLB Twitter: Join Click',
                        actionGen: true
                    }
                });
            });


            //spotlight		
            $("#h_spotlight .carousel_next").click(function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Spotlight',
                        compActivity: 'MLB Spotlight: Next Click',
                        actionGen: true
                    }
                });
            });
            $("#h_spotlight .carousel_prev").click(function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Spotlight',
                        compActivity: 'MLB Spotlight: Previous Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#h_spotlight .carousel_container";
            $doc.live("click", function(e) {
                var $target = $(e.target);
                var items = $target.closest("ul").find(".carousel_item");
                var idx = items.index($target.closest(".carousel_item"));
                idx = idx - 2;
                if ($target.closest("li").hasClass("isClone")) {
                    idx = (idx < 1) ? idx + 9 : idx - 9;
                }
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Spotlight',
                        compActivity: 'MLB Spotlight: Panel ' + idx + ' Click',
                        actionGen: true
                    }
                });
            });
            $("#h_spotlight .carousel_pag li").click(function() {
                var items = $(this).closest("ul").find("li");
                var idx = items.index($(this));
                ++idx;
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Spotlight',
                        compActivity: 'MLB Spotlight: Circle ' + idx + ' Click',
                        actionGen: true
                    }
                });
                return false;
            });

            // initiatives
            $("#h_initiatives .carousel_next").click(function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Initiatives',
                        compActivity: 'MLB Initiatives: Next Click',
                        actionGen: true
                    }
                });
            });
            $("#h_initiatives .carousel_prev").click(function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Initiatives',
                        compActivity: 'MLB Initiatives: Previous Click',
                        actionGen: true
                    }
                });
            });
            $("#h_initiatives .carousel_container li").click(function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Initiatives',
                        compActivity: 'MLB Initiatives: Panel Click',
                        actionGen: true
                    }
                });
            });

            //photos
            $doc.selector = "#h_photos #ph_prev";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Photos',
                        compActivity: 'MLB Photos: Previous Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#h_photos #ph_next";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: true,
                        compName: 'MLB Photos',
                        compActivity: 'MLB Photos: Next Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#h_photos #ph_slide";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Photos',
                        compActivity: 'MLB Photos: Gallery Click',
                        actionGen: true
                    }
                });
            });
            $doc.selector = "#h_photos #ph_more";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Photos',
                        compActivity: 'MLB Photos: More Click',
                        actionGen: true
                    }
                });
            });

            // Hot Stove Headline Click
            $doc.selector = "#hot_stove_container ul li a";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Hot Stove Notes',
                        compActivity: 'MLB Hot Stove Notes: Headline Click',
                        actionGen: true
                    }
                });
            });

            // "More Player Notes" Click
            $doc.selector = "#hot_stove_container .more";
            $doc.live("click", function(e) {
                bam.tracking.track({
                    async: {
                        isDynamic: false,
                        compName: 'MLB Hot Stove Notes',
                        compActivity: 'MLB Hot Stove Notes: More Notes Click',
                        actionGen: true
                    }
                });
            });

        },



        /**
         * 
         *
         * _self
         * 
         * root object
         * all modules are initialized here
         *
         *
         */

        _self = {
            debug: _setDebugging("mlbhome"),

            narrowband: "/mlb/homepage/narrowband.jsp",

            // setter/getter
            set: function(key, value) {
                if (key && typeof(value) !== "undefined") {
                    _properties[key] = value;
                }
                _log("setting property: " + key + ". Displaying _properties below:");
                _log(_properties);
            },
            get: function(key) {
                _log("getting " + key);
                return (key && key in _properties) ? _properties[key] : null;
            },


            init: function() {
                _track();
                _videoModule.init();
                _navbuttons();
                sysdate = typeof(sysdate) !== "undefined" ? sysdate : bam.datetime.DateTime().toYMD();
                _twitter.init();
                _createCarousel({
                    container: $("#h_spotlight"),
                    maxItems: 3
                });
                _miniStandings.init(sysdate, false);
                _leaders.init();
                var initiatives = $("#h_initiatives .carousel_container li").length;
                _createCarousel({
                    container: $("#h_initiatives"),
                    maxItems: initiatives
                });
                _photogalleries.init();				
				
                //BTSModule.init();
                // 30 minute refresh
                setTimeout(function() {
                    document.location.reload(true);
                }, 1800000);
            },

            getClubProperties: function() {
                var out = this.get('clubprops');
                if (!out) {
                    $.ajax({
                        async: false,
                        url: "/scripts/club_properties.jsp",
                        dataType: 'json',
                        data: {
                            responseType: "json"
                        },
                        success: function(json) {
                            out = json;
                            bam.mlbhome.set("clubprops", json);
                        },
                        error: function(xhr) {
                            _log("Error accessing club properties: " + xhr.status + " " + xhr.statusText);
                        }
                    });
                }
                return out;
            }
        };


    // MiniSB calculations	
    // calculates the height of minisb and write ads below it accordingly	
    //if(_lang === "en") {
    if (_lang === "en") { 
        $.available("#row1 .sbMini > div", true, function() {
            // get available space
            var colHeight = $("#row1 #column2").outerHeight(true) - 5,
                // there's 5px extra room at the bottom of column 2
                minisbHeight = $("#row1 #column1 .sbMini").outerHeight(true),
                $mlbn = $("#minisb_mlbn"),
                $ad60 = $("#column1 .ad174x60"),
                $ad120 = $("#column1 .ad174x120"),
                $mobile = $("#mobileContainer"),
                space = colHeight - minisbHeight,
                componentHeight = 0,
                numComponents = 0,
                calculatedMarginTop = "5px",
                addIt = function(elem) {
                    componentHeight += elem.outerHeight(); // use outerHeight() instead of height() to include padding
                    numComponents++;
                };

            _log("MiniSB calculations: colHeight=" + colHeight + ", minisbHeight=" + minisbHeight + ", space=" + space);

/*	
            MLBN is 70 px high + 5px top margin = 75px
            ad60 is 60 px height + 5px top margin = 65px
            ad120 is 120 px height + 5px top margin = 125px
            mobile is 100 px height	 + 5px top margin = 105px
            default margin is 5px top
            */

            if (space >= 75) {
                $mlbn.show();
                addIt($mlbn);
            }

            if (space > 400) {
                var
                promoImg = "<img src='/mlb/images/homepage/y2011/atbat_184x336.jpg' width='184' height='336'>",
                    promoLink = "/mobile/atbat/",
                    promoHTML = promoImg.link(promoLink),
                    //@TODO: move these styles into mlb.css
                    $ad336 = $(promoHTML).css({
                        "display": "block",
                        "padding-left": "2px"
                    }).insertBefore($mlbn);
                addIt($ad336);				
            } else {
                if (space >= 140 && space < 200) {
                    $ad60.show().dcRefreshableAd({
                        interval: 0
                    });
                    addIt($ad60);
                }
                if (space >= 200) {
                    $ad120.show().dcRefreshableAd({
                        interval: 0
                    });
                    addIt($ad120);
                }
                if (space >= 305) {
                    $mobile.show();
                    addIt($mobile);
                }
            }

            calculatedMarginTop = Math.floor((space - componentHeight) / numComponents);
            _log("MiniSB calculations: componentHeight=" + componentHeight + ", numComponents=" + numComponents + ", calculatedMarginTop=" + calculatedMarginTop);
            $("#column1 .minisbAd").css("margin-top", calculatedMarginTop);

        });
        // end MiniSB calculations	
    }

    $.bindable(_self, "onPageLoad");
    _self.bind("onPageLoad", _self.init);
    return _self;

})(jQuery);





$(function() {
    //bam.mlbhome.init();
    bam.mlbhome.trigger("onPageLoad");
});
