--[[
  DISCLAIMER: SCRIPT IS PROVIDED AS IS USE AT YOUR OWN RISK!
 
  Save this script as "hockey.lua"
  Place this script in:
    - Windows (all users):   %ProgramFiles%\VideoLAN\VLC\lua\sd\
    - Windows (current user):   %APPDATA%\VLC\lua\sd\
    - Linux (all users):     /usr/share/vlc/lua/sd/
    - Linux (current user):  ~/.local/share/vlc/lua/sd/
    - Mac OS X (all users):  VLC.app/Contents/MacOS/share/lua/sd/  
    --]]
require "simplexml"
 
API_USERNAME="rhockeyvlc"
 
function descriptor()
    return { title="/r/hockey" }
end
 
local function get_date_parts(date_str)
  _,_,y,m,d,h,M,s=string.find(date_str, "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)")
  return {year=tonumber(y),month=tonumber(m),day=tonumber(d),hour=tonumber(h),min=tonumber(M),sec=tonumber(s)}
end

local function get_et_date()
    local et_time_xml = simplexml.parse_url("http://api.geonames.org/timezone?lat=40.67&lng=-73.94&username=" .. API_USERNAME)
    local et_date = nil
    for _, child in ipairs( et_time_xml.children ) do
        if (child.name == "timezone") then
            for _, subchild in ipairs( child.children ) do
                if (subchild.name == "time") then
                    et_date = subchild.children[1] .. ":00"
                end
            end
        end
    end
    return et_date
end

local function get_et_diff()
    local status, et_date = pcall(get_et_date)
    if (status == false or et_date == nil) then
        vlc.msg.warn("Couldn't get ET time, showing default times: " .. et_date)
        return nil
    end
    local local_time = os.time()
    local et_time = os.time(get_date_parts(et_date))
    return os.difftime(local_time, et_time)
end

local function get_timezone()
    local time = os.time()
    local utcdate   = os.date("!*t", time)
    local localdate = os.date("*t", time)
    localdate.isdst = false -- this is the trick
    local time_diff = os.difftime(os.time(localdate), os.time(utcdate))
    local h, m = math.modf(time_diff / 3600)
    return string.format("%+.4d", 100 * h + 60 * m)
end

local function convert_to_local(date, diff, tz)
    local time = os.time(get_date_parts(date))
    if (diff == nil) then
        return os.date("%H:%M ET", time)
    end
    local local_time = time + diff;
    return os.date("%H:%M", local_time)
end

function main()
    local et_diff = get_et_diff()
    local timezone = get_timezone()
    local games = simplexml.parse_url("http://208.92.36.37/nlds/as3/get_games.php?client=nhl&playerclient=hop")
    local test_games = {}
    for _, game in ipairs( games.children ) do              
        if(game.name == "game") then           
            simplexml.add_name_maps( game )
            local game_date, home_team, away_team, title = getInfoForGame(game, et_diff, timezone)
            if string.find(home_team,"^T%d+$") or string.find (away_team,"^T%d+$") then
                table.insert(test_games, game)
            else
                local node = vlc.sd.add_node( { path = "", title = title } )
                addNodeForGame(node, game, home_team, away_team)
            end
        end
    end

    if table.getn(test_games) > 0 then
        local test_node = vlc.sd.add_node( { path = "", title = "Test Streams" } )
        for _, game in ipairs(test_games) do
            local game_date, home_team, away_team, title = getInfoForGame(game, et_diff, timezone)
            node = test_node:add_node({ title = title })
            addNodeForGame(node, game, home_team, away_team)
        end
    end
end

function getInfoForGame(game, et_diff, timezone)
    local game_date = convert_to_local(game.attributes["game_date"], et_diff, timezone)
    local home_team = full_name(game.children_map['home_team'][1].children[1])
    local away_team = full_name(game.children_map['away_team'][1].children[1])
    local title = game_date .. " - " .. away_team .. " @ " .. home_team
    return game_date, home_team, away_team, title
end

function addNodeForGame(parentNode, game, home_team, away_team)
    local quality = {400, 800, 1200, 1600, 2400, 3000, 4500}
    for _, ass in ipairs(game.children_map['assignments'][1].children) do
        local feed = ass.attributes["feed_display_name"]
        local feed_title = home_team
        if(feed == "away") then
            feed_title = away_team
        end
        local feed_node = parentNode:add_node({ title = feed_title })
        local ipad = ass.children_map['ipad_url'][1].children[1]
        for _, q in ipairs(quality) do
            local url = string.gsub(ipad, "ipad", q)
            feed_node:add_subitem({
                path = url,
                title = q .. ' kbps',
                options = {
                    "http-user-agent=AppleCoreMedia/1.0.0.8C148 (iPad; U; CPU OS 4_2_1 like Mac OS X; en_us)"
                }
            })
        end
    end
end

function full_name(abr)
    local all_names = {
        BOS = "Boston Bruins",
        BUF = "Buffalo Sabres",
        CGY = "Calgary Flames",
        CHI = "Chicago Blackhawks",
        DET = "Detroit Red Wings",
        EDM = "Edmonton Oilers",
        CAR = "Carolina Hurricanes",
        LOS = "Los Angeles Kings",
        MON = "Montreal Canadiens",
        DAL = "Dallas Stars",
        NJD = "New Jersey Devils",
        NYI = "New York Islanders",
        NYR = "New York Rangers",
        PHI = "Philadelphia Flyers",
        PIT = "Pittsburgh Penguins",
        COL = "Colorado Avalanche",
        STL = "St. Louis Blues",
        TOR = "Toronto Maple Leafs",
        VAN = "Vancouver Canucks",
        WSH = "Washington Capitals",
        PHX = "Phoenix Coyotes",
        SAN = "San Jose Sharks",
        OTT = "Ottawa Senators",
        TAM = "Tampa Bay Lightning",
        ANA = "Anaheim Ducks",
        FLA = "Florida Panthers",
        CMB = "Columbus Blue Jackets",
        MIN = "Minnesota Wild",
        NSH = "Nashville Predators",
        WPG = "Winnipeg Jets"
    }
    local name = all_names[abr]
    if name == nil then
        name = abr
    end
    return(name)
end