FANDOM


local Item = {}
----------------------------
-- Libraries of functions --
----------------------------
-- Loads high frequency functions
local HF = require('Module:HF')
-- Parses invocation and template parameters, trims whitespace, and removes blanks.
local getArgs = require('Dev:Arguments').getArgs
-- Language functions for the default language
local lang = mw.language.getContentLanguage()
 
local yesno = require( 'Module:Yesno' )
local addcommas = require( 'Module:Addcommas' )._add
 
-----------------------
-- Libraries of data --
-----------------------
 
------------------------------------------------
-- Local functions (used only in this Module) --
------------------------------------------------
 
-- Makes sure first letter of item is uppercase
-- Automatically handles any redirects
local function checkTitle( item )
    -- upper case first letter to make sure we can find a valid item page
    item = lang:ucfirst(item)
 
    -- map redirects to their correct pages
    local geRedirects = {
        ['1/2 anchovy pizza'] = '½ anchovy pizza',
        ['1/2 meat pizza'] = '½ meat pizza',
        ["1/2 p'apple pizza"] = "½ p'apple pizza",
        ['1/2 plain pizza'] = '½ plain pizza',
        ['1/3 evil turnip'] = '⅓ evil turnip',
        ['2/3 cake'] = '⅔ cake',
        ['2/3 chocolate cake'] = '⅔ chocolate cake',
        ['2/3 evil turnip'] = '⅔ evil turnip'
    }
 
    return geRedirects[item] or item
end
 
-- mw.loadData wrapper used to access data located on module subpages
local function load( item )
    local datamodule = 'Module:Exchange/' .. checkTitle( item )
    return assert( 
        mw.loadData(datamodule),
        datamodule .. ' could not be loaded.'
    )
end
 
----------------------------------------------------------
-- Public functions (called from a Template or article) --
----------------------------------------------------------
-- ExchangePrice
function Item.ExchangePrice(frame)
    local args = getArgs(frame)
    local tradeable = args['tradeable'] and args['tradeable']:lower() or ''
    local exchange = args['exchange'] and args['exchange']:lower() or 'unknown'
    local item = args['gemwname'] or args['name'] or mw.title.getCurrentTitle().prefixedText
    local options = {
        ['unknown'] = 'Unknown',
        ['no'] = 'Not sold'
    }
    local output = {}
    if options[exchange] then 
        table.insert(output, options[exchange])
    elseif exchange == 'gemw' then
        local priceform = item
        table.insert(output, ('<span id="GEPrice"><span class="GEItem"><span>%s</span></span> coins</span>')
            :format( Item._price( item, 1, true, nil) )
        )
        table.insert(output, (' (%s)'):format(HF.Link('Exchange:'..(item), 'info')))
        table.insert(output, HF.Category('Items with GE modules'))
    else
        table.insert(output, ('%s%s'):format(exchange, exchange == tonumber(exchange) and ' coins' or ''))
    end
 
    return (mw.title.getCurrentTitle().isContentPage 
            and tradeable ~= 'no') 
        and table.concat(output) or nil
end
 
-- BuyLimit
function Item.BuyLimit(frame)
    local args = getArgs(frame)
    local tradeable = args['tradeable'] and args['tradeable']:lower() or ''
    local exchange = args['exchange'] and args['exchange']:lower() or 'unknown'
    local test = args['gemwname'] or args['name'] or mw.title.getCurrentTitle().prefixedText
    local limit = ( Item._exists(test) and Item._view(test, 'limit') ) 
        and lang:formatNum(Item._view(test, 'limit'))
        or nil
    return (mw.title.getCurrentTitle().isContentPage 
            and tradeable ~= 'no'
            and exchange == 'gemw') 
        and limit or nil
end
 
 
-- GE Chart
-- GEData = ExchangeData|data
-- GEMH Chart == GEChart = ExchangeData|chart
--- Outer
function Item.GEData_Wrapper(frame)
    local args = getArgs(frame)
    local test = args['gemwname'] or args['name'] or mw.title.getCurrentTitle().prefixedText
    -- TODO: use native Lua instead of calling templates
    if (mw.title.getCurrentTitle().isContentPage 
            and args['exchange'] == 'gemw'
            and Item._exists( test..'/Data')) then
        local GEData = frame:newTemplateParserValue{ 
            title = 'GEData',
            args = { test, ['size'] = 'small' }
            }
        local IED = mw.html.create('div')
            :addClass('infobox-exchange-data')
            :addClass('hidden')
            :css('display','inline-block')
            :css('font-weight','normal')
            :wikitext(GEData:expand())
            :allDone()
        return tostring(IED)
    elseif (mw.title.getCurrentTitle().isContentPage 
            and args['gemwname']
            and args['exchange'] ~= 'no') then
        local GEChart = frame:newTemplateParserValue{ 
            title = 'GEChart',
            args = {
                args['gemwname'],
                ['size'] = 'small',
                ['else'] = '<!--May need placeholder chart-->'
                }
            } 
        local IGC = mw.html.create('div')
            :addClass('infobox-gemw-chart')
            :addClass('hidden')
            :css('display','inline-block')
            :css('font-weight','normal')
            :wikitext(GEChart:expand())
            :allDone()
        return tostring(IGC)
    end
end
 
--- 
 
 
--
-- {{GEExists}}
--
function Item.exists( frame )
    local args = getArgs(frame, { parentOnly = true })
    local item = args[1] or ''
    return Item._exists( item ) and 1 or 0
end
 
--
-- {{GEP}}
-- {{GEPrice}}
--
-- @example {{GEPrice|<item>|<format>|<multi>}}
-- @example {{GEPrice|<item>|<multi>}}
-- @example {{GEP|<item>|<multi>}}
--
function Item.price( frame )
    -- usage: {{foo|item|format|multi}} or {{foo|item|multi}}
    local args = getArgs(frame, { frameOnly = true })
    local pargs = getArgs(frame, { parentOnly = true })
    local item = assert(
        pargs[1] and mw.text.trim( pargs[1] ),
        '"item" argument not specified'
    )
    local format = pargs[3] and pargs [2] or nil
    local multi = pargs[3] == nil and pargs[2] or pargs[3] or 1
    local expr = mw.ext.ParserFunctions.expr
    local round = tonumber( pargs['round'] )
 
    -- format is set with #invoke
    -- so set it first to allow it to be overridden by template args
    -- default to formatted for backwards compatibility with old GE templates
    local format = args['format'] and yesno( args['format'] ) or true
    local multi = 1
 
 
    if tonumber( pargs[2] ) then
        multi = tonumber( pargs[2] )
 
    -- indicated someone is trying to pass an equation as a mulitplier
    -- known use cases are fractions, but pass it to #expr to make sure it's handled correctly
    elseif pargs[2] and mw.ustring.find( pargs[2], '[/*+-]' ) then
        multi = tonumber( expr( pargs[2] ) )
 
    -- uses elseif to prevent something like {{GEP|Foo|1}}
    -- causing a formatted output, as 1 casts to true when passed to yesno
    elseif type( yesno( pargs[2] ) ) == 'boolean' then
        format = yesno( pargs[2] )
 
        if tonumber( pargs[3] ) then
            multi = tonumber( pargs[3] )
        end
    end 
 
    return Item._price( item, multi, format, round )
end
 
--
-- {{ExchangeItem}}
-- {{GEDiff}}
-- {{GELimit}}
-- {{GEValue}}
-- {{GEId}}
--
-- @example {{ExchangeItem|<item>}}
-- @example {{GEDiff|<item>}}
-- @example {{GELimit|<item>}}
-- @example {{GEValue|<item>}}
-- @example {{GEId|<item>}}
--
function Item.view( frame )
    local fargs = getArgs(frame, { frameOnly = true })
    local pargs = getArgs(frame, { parentOnly = true })
    local item = assert(
        pargs[1] and mw.text.trim( pargs[1] ),
        '"item" argument not specified'
    )
    local view = fargs['view'] and mw.ustring.lower( fargs['view'] ) or nil
    return Item._view( item, view )
end
---------------------------------------------------------
-- Internal functions (used in this and other Modules) --
---------------------------------------------------------
-- Checks for Exchange module
function Item._exists( item )
    local datamodule = 'Module:Exchange/' .. checkTitle( item )
    return pcall( mw.loadData, datamodule ) and true or nil
end
 
-- Returns the price of an item
function Item._price( item, multi, format, round )
    local price = load( item ).price
    local multi = type( multi ) == 'number' and multi or 1
    local format = type( format ) == 'boolean' and format or false
    local ret = price * multi
 
    -- round the number to X d.p.
    if round then
        local multi = 10^( round )
        ret = math.floor( ret * multi + 0.5 ) / multi
    end
 
    if format then
        return addcommas( ret )
    end
 
    return ret
end
 
-- Calculates the difference between the current price and the last price of an item
function Item._diff( item, format )
    local data = load( item )
    local diff = (data['price'] and data['last']) 
        and (format 
            and addcommas( data['price'] - data['last'] ) 
            or (data['price'] - data['last'])
            )
        or 0
    return diff
end
 
function Item._view( item, view )
    local view = view and mw.ustring.lower( view ) or nil
    local loadView = {
        limit=true,
        value=true,
        itemId=true,
        itemid='itemId'
    }
 
    if view == 'diff' then
        return Item._diff( item )
 
    elseif loadView[view] then
        return load( item )[view]
 
    else
        local default = require( 'Module:ExchangeDefault' )
        -- handle redirects and casing of item before passing it on
        return default.main( checkTitle( item ) )
    end
end
 
-------------------------------------------------
-- Output (send it back to whatever called it) --
-------------------------------------------------
return Item
Community content is available under CC-BY-SA unless otherwise noted.