var standings = (function() {
  var bhp = bam.homePath;


  //Load dependencies
  var _properties = {};
  bam.loadSync(bhp + "bam.datetime.js", bhp + "bam.cookies.js", bhp + "bam.datagrid2.js");

  var cache, TODAY = bam.datetime.parseYMD(bam.datetime.DateTime().toYMD()),
      //TODO set this to TODAY.getFullYear() for opening day
      //this is to fix off season bug
      SYS_YEAR = TODAY.getFullYear()-1,
      DATE = SYS_YEAR + TODAY.formatDate("/MM/dd"),
      STANDINGS_TYPE = ['standings_all', 'standings_spring', 'standings_wildcard'],
      RESULTS_MAX = 16,
      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,
      isRegularSeason, DIVISION_NAMES = {
      East: "East",
      Central: "Central",
      West: "West",
      0: "East",
      1: "Central",
      2: "West"
      },
      SEASON_STATUS_URI = "/lookup/json/named.properties_info_events_season.bam?season=%0&sport_code='mlb'&org_id=1",
      SPRING_SEASON_URI = "/lookup/json/named.standings_spring_repeater.bam?season=%0&league_id=103&league_id=104&league_id=114&league_id=115&version=2",
      REGULAR_SEASON_URI = "/lookup/json/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_id,team_short,file_code,w,l,pct,gb,elim,runs,opp_runs,x_wl,streak,last_ten,home,away," + "vs_division,vs_east,vs_central,vs_west,interleague,vs_left,vs_right,extra_inn,one_run,gb_wildcard,elim_wildcard," + "runs,opp_runs,x_wl&" + $.param({
      league_id: SEASON_LEAGUES.regular
    }),
      WILD_CARD_URI = "/lookup/json/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
    }),
      SUPER_URI = "/lookup/json/named.standings_schedule_date.bam?season=2010&game_date=%272010/05/06%27&sit_code=%27h0%27&league_id=103&" + "league_id=104&all_star_sw=%27N%27",
      SEASON_DATES = "/lookup/json/named.org_history.bam?org_code=%27mlb%27",
      SEASONS = {},
      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, makeYearMenu = function() {
      var menuItems = "";
      for (var i = 2011, j = 2005; i > j; i--) {
        menuItems = menuItems + '<option value="' + i + '">' + i + '</option>';
      }
      $("#standing_year").append(menuItems);
      },
      
      
      DECORATOR_PREFIX_NAME = function() {
      var prefixedName, team_code, team_id = this.rawData.team_id,
          clubUrl;
      if (CLUB_PROPS && (team_id in CLUB_PROPS)) {
        prefixedName = CLUB_PROPS[team_id].name_display_short;
        clubUrl = CLUB_PROPS[team_id].club_common_url;
        team_code = CLUB_PROPS[team_id].team_code;
        prefixedName = "<a href=\"http://" + clubUrl + "\" class=\"" + team_code + "\">" + prefixedName + "</a>";
      }
      return prefixedName;

      },
      
      
      //defautl team title
      COLUMN_TITLE_DEFAULT = [{
      title: "Team",
      dataField: "team_short",
      decorator: DECORATOR_PREFIX_NAME
    }],
      
      
      //division titles
      COLUMN_TITLE_EAST = [{
      title: DIVISION_NAMES.East,
      dataField: "team_short",
      decorator: DECORATOR_PREFIX_NAME
    }],
      COLUMN_TITLE_CENTRAL = [{
      title: DIVISION_NAMES.Central,
      dataField: "team_short",
      decorator: DECORATOR_PREFIX_NAME
    }],
      COLUMN_TITLE_WEST = [{
      title: DIVISION_NAMES.West,
      dataField: "team_short",
      decorator: DECORATOR_PREFIX_NAME
    }],
      
      
      //default column definitions
      COLUMN_DEFS = [{
      title: "W",
      dataField: "w"
    }, {
      title: "L",
      dataField: "l"
    }, {
      title: "PCT",
      dataField: "pct"
    }, {
      title: "GB",
      dataField: "gb"
    }, {
      title: "wc",
      visible: false,
      dataField: "wild_card"
    }, {
      title: "dc",
      visible: false,
      dataField: "division_champ"
    }, {
      title: "po",
      visible: false,
      dataField: "playoffs_sw"
    }],
      COLUMN_DEFS_DEFAULT = {
      columns: $.merge(COLUMN_TITLE_DEFAULT, COLUMN_DEFS)
      },
      
      /*
            * merge division title defintion with default COLUMN_DEFS 
            * so grid displays East, Central, West 
            */
      
      COLUMN_DEFS_EAST = {
      columns: $.merge(COLUMN_TITLE_EAST, COLUMN_DEFS)
      },
      COLUMN_DEFS_CENTRAL = {
      columns: $.merge(COLUMN_TITLE_CENTRAL, COLUMN_DEFS)
      },
      COLUMN_DEFS_WEST = {
      columns: $.merge(COLUMN_TITLE_WEST, COLUMN_DEFS)
      },
      
      
      //base grid
      DATAGRID_BASE = {
      tableClass: "stats_table data_grid",
      noResultsMessage: NO_DATA_MSG,
      sortable: false,
      columns: COLUMN_DEFS,
      dataType: "json"
      },
      
      
      //generic grid with team title
      DEFAULT_GRID = new bam.datagrid.DataGrid($.extend(DATAGRID_BASE, COLUMN_DEFS_DEFAULT)),
      
      
      //division grids with division titles extend base grid with new column definitions
      EAST_GRID = new bam.datagrid.DataGrid($.extend(DATAGRID_BASE, COLUMN_DEFS_EAST)),
      CENTRAL_GRID = new bam.datagrid.DataGrid($.extend(DATAGRID_BASE, COLUMN_DEFS_CENTRAL)),
      WEST_GRID = new bam.datagrid.DataGrid($.extend(DATAGRID_BASE, COLUMN_DEFS_WEST));

  //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] || '';
      });
    }
  }


  //todo rewrite object
  var springSeasonLookUp = $.loadable({
    url: formatString(SPRING_SEASON_URI, SYS_YEAR),
    dataType: 'text',
    beforeSend: function() {
      $(".standingsSpringAL").fadeTo("slow", 0.33);
      $(".standingsSpringNL").fadeTo("slow", 0.33);
      $(".standingsSpringGL").fadeTo("slow", 0.33);
      $(".standingsSpringCL").fadeTo("slow", 0.33);
    },
    dataFilter: function(data, type) {
      var info = $.parseJSON(data);
      var league = info.standings_spring_repeater.standings_spring;
      return league;
    }
  });


/*
        * Look up for season start/end dates
        */
  var seasonDatesLookUp = $.loadable({
    url: SEASON_DATES,
    dataType: 'text',
    async: false,
    dataFilter: function(data, type) {
      var info = $.parseJSON(data);
      var seasonDates = info.org_history.queryResults;
      return seasonDates;
    }
  });
  seasonDatesLookUp.onLoadSuccess(function(evt, data) {
    SEASONS = data;
  });
  seasonDatesLookUp.load();


  //todo rewrite object
  var seasonStatusLookUp = $.loadable({
    url: formatString(SEASON_STATUS_URI, SYS_YEAR),
    dataType: 'text',
    dataFilter: function(data, type) {
      var info = $.parseJSON(data);
      var schedule = info.properties_info_events_season.schedule_event_info;
      return schedule;
    }
  });

  var model = {

    fillDatagrid: function(dgObj, data, userLimit) {
      if (data && data.length) {
        dgObj.clearData();
        $.each(data.slice(0, (~~ + userLimit || RESULTS_MAX)), function(i, row) {
          dgObj.insertRow(row);
        });
      }
      return dgObj;
    },
    //Applies division filter to a league data
    filterByDivision: function(division, data) {
      var out = [];
      if (data && data.length) {
        for (var i = 0; i < data.length; i += 1) {
          if (data[i].division_id == division) {
            out[i] = data[i];
          }
        }

      }
      return out;
    },
    extractScheduleData: function(schedule, league) {
      var data = league.queryResults.row,
          team_id, out = [],
          x = 0;
      for (var i = 0; i <= data.length - 1; i += 1) {
        team_id = data[i].team_id;
        for (var j = 0; j <= schedule.length - 1; j += 1) {
          var sched_teamId = schedule[j].team_id;
          if (sched_teamId === team_id) {
            out[x] = schedule[j];
            x += 1;
          }
        }
      }
      return out;
    },

    extractGameDates: function(schedule) {
      var out = [];
      for (var i = 0; i <= schedule.length - 1; i += 1) {
        var obj = {},
            date, last, next;

        //last game
        date = schedule[i].schedule_game_date.queryResults.row[0].game_time_away.split("/", 2);
        last = date[0] + "/" + date[1];
        if (schedule[i].team_id === schedule[i].schedule_game_date.queryResults.row[0].away_team_id) {
          last = last + " @ " + schedule[i].schedule_game_date.queryResults.row[0].home_team_abbrev + ", " + schedule[i].schedule_game_date.queryResults.row[0].away_result + " " + schedule[i].schedule_game_date.queryResults.row[0].away_score + "-" + schedule[i].schedule_game_date.queryResults.row[0].home_score;
        } else {
          last = last + " vs " + schedule[i].schedule_game_date.queryResults.row[0].away_team_abbrev + ", " + schedule[i].schedule_game_date.queryResults.row[0].home_result + " " + schedule[i].schedule_game_date.queryResults.row[0].home_score + "-" + schedule[i].schedule_game_date.queryResults.row[0].away_score;
        }

        //next game
        date = schedule[i].schedule_game_date.queryResults.row[1].game_time_away.split("/", 2);
        next = date[0] + "/" + date[1];
        if (schedule[i].team_id === schedule[i].schedule_game_date.queryResults.row[1].away_team_id) {
          next = next + " @ " + schedule[i].schedule_game_date.queryResults.row[1].home_team_abbrev + ", " + schedule[i].schedule_game_date.queryResults.row[1].away_result + " " + schedule[i].schedule_game_date.queryResults.row[1].away_score + "-" + schedule[i].schedule_game_date.queryResults.row[1].home_score;
        } else {
          next = next + " vs " + schedule[i].schedule_game_date.queryResults.row[1].away_team_abbrev + ", " + schedule[i].schedule_game_date.queryResults.row[1].home_result + " " + schedule[i].schedule_game_date.queryResults.row[1].home_score + "-" + schedule[i].schedule_game_date.queryResults.row[1].away_score;
        }

        obj.last_game = last; //last game i.e. 5/6 @ LAA, L 4-5
        obj.next_game = next; //next game i.e. 5/7 vs LAA, L 4-5
        obj.team_id = schedule[i].team_id; //add team_id to use as key
        out[i] = obj;
      }
      return out;
    },
    mergeDates: function(dates, league) {
      var out = [],
          x = 0;
      for (var i = 0; i <= dates.length - 1; i += 1) {
        if (dates[i].team_id === league.queryResults.row[i].team_id) {
          out[x] = $.extend(league.queryResults.row[i], dates[i]);
          x += 1;
        }
      }
      return out;
    },
    setDates: function(data) {
      SEASONS = data;
    }
  };

  var view = {
    //Pre-pends a prefix to the team name (runs in the scope of the datagrid.row)
    setTeamPrefix: function(o) {
      var out = o.value;
      return out;
    },
    //Render a single standings grid
    renderGrid: function(dgObj, el) {
      dgObj.render(el);
    },
/*
    * onchange takes year and performs a new lookup
    *
    */
    onChangeYear: function(year) {
      $('#standing_year').change(function() {
        var year = $('#standing_year').val();
        var uri = formatString(SPRING_SEASON_URI, year);
        view.setViewLinksRegular(year);
        springSeasonLookUp.load({
          url: uri
        });
        bam.tracking.simStatsPgView({
          pageName: "Major League Baseball: Standings: Spring Training Standings",
          channel: "Standings",
          source: "Spring Training Standings",
          control: "Standings: Year Select"
        });
      });
    },
    setViewLinksRegular: function(year) {
      var regularLink = $('.topnav_regular').find('a').attr("href");
      var ymd = "?ymd=";
      var seasonEnd;
      for (var i = 0, j = SEASONS.row.length; i < j; i++) {
        if (SEASONS.row[i].year == year) {
          seasonEnd = bam.datetime.parseISODate(SEASONS.row[i].last_date_seas);
        }
      }
      $('.topnav_wildcard').css('display', 'inline'); //set to none for pre allstar break
      if (year == TODAY.getFullYear()-1) {
        $('#standingsContainer').addClass('currentYear');
      } else {
        $('#standingsContainer').removeClass('currentYear');
      }
      if (year < TODAY.getFullYear()) {
        $('.topnav_wildcard').css('display', 'inline');
        var wildcardLink = $('.topnav_wildcard').find('a').attr("href");
        wildcardLink = wildcardLink.split("?");
        wildcardLink = wildcardLink[0] + ymd + seasonEnd.formatDate("yyyyMMdd");
        location.hash = seasonEnd.formatDate("yyyyMMdd");
        $('.topnav_wildcard').find('a').attr("href", wildcardLink);
      } else {
        $('.topnav_wildcard').css('display', 'inline'); //set to none for pre allstar break
      }
      regularLink = regularLink.split("?");
      regularLink = regularLink[0] + ymd + seasonEnd.formatDate("yyyyMMdd");
      $('.topnav_regular').find('a').attr("href", regularLink);
      location.hash = seasonEnd.formatDate("yyyyMMdd");
      $("#standing_year").selectmenu({
        width: 120
      });
      $("#standing_year").val(year);
      $('.ui-selectmenu-status').text(year);
      $('#split').hide();
    },
    setToolTips: function() {
      var tipCfg = {
        content: "",
        style: {
          name: 'light',
          // Inherit the rest of the attributes from the preset dark style
          tip: 'bottomMiddle',
          border: {
            width: 2,
            radius: 5
          }
        },
        show: {
          when: {
            event: "click"
          },
          //show it on the click
          ready: true,
          solo: true,
          // Only show one tooltip at a time
          delay: 0
        },
        position: {
          corner: {
            target: 'topMiddle',
            tooltip: 'bottomMiddle'
          }
        }
      };

      $("th.dg-gb").live("click", function() {
        var content = {
          content: 'Games behind, the average of the differences between the leading team wins and the trailing team wins, and the leading team losses and trailing team losses'
        };
        $(this).qtip($.extend(tipCfg, content));
      });

    }

  };

  var controller = {
    renderSpringStandings: function(data) {
      var CL_league = data[0].queryResults.row;
      var GL_league = data[1].queryResults.row;
      var NL_league = data[2].queryResults.row;
      var AL_league = data[3].queryResults.row;
      controller.sendToView(DEFAULT_GRID, CL_league, "clStandingsData");
      controller.sendToView(DEFAULT_GRID, GL_league, "glStandingsData");
      controller.sendToView(DEFAULT_GRID, NL_league, "nlStandingsData");
      controller.sendToView(DEFAULT_GRID, AL_league, "alStandingsData");
      $(".standingsSpringAL").fadeTo("slow", 1);
      $(".standingsSpringNL").fadeTo("slow", 1);
      $(".standingsSpringGL").fadeTo("slow", 1);
      $(".standingsSpringCL").fadeTo("slow", 1);
    },

    sendToView: function(dgObj, data, el) {
      model.fillDatagrid(dgObj, data);
      view.renderGrid(dgObj, el);
    },
    // 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;
    },

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

    init: function(date) {
      var year, _date;
      if (date) {
        _date = date + "";
        year = _date.substr(0, 4);
        //TODO remove for opening day
        //set default year to 2011 
        if(year === '2012'){
        	year = '2011';
        }

      }
      CLUB_PROPS = controller.getClubProperties();
      makeYearMenu();
      view.onChangeYear(); //Year change handler 
      view.setViewLinksRegular(year);
      view.setToolTips();
/*
        * all of the loadable onLoadSuccess handlers
        */
      springSeasonLookUp.onLoadSuccess(function(evt, data) {
        controller.renderSpringStandings(data);
      });
/*
        * call for the look up service
        */
      var uri = formatString(SPRING_SEASON_URI, year);
      springSeasonLookUp.load({
        url: uri
      });
    }
  };

  return controller;

})();
