from __future__ import division
import locale
locale.setlocale(locale.LC_ALL, '')

from eve import skilltree

class Mineral:
    def __init__(self, buy=None, sell=None):
	self._buy = buy
	self._sell = sell

    def buy(self, quantity):
	return self._buy * quantity

    def sell(self, quantity):
	return self._sell * quantity

class Ore:
    def __init__(self, volume, portion, minerals):
	self.volume = volume
	self.portion = portion
	self.minerals = minerals

    def refine(self, volume, yieldr):
	return ((mineral, amount * yieldr / self.volume / self.portion * volume) for mineral, amount in self.minerals.iteritems())

minerals = {
    'isogen': Mineral(buy=82.00, sell=81.10),
    'mexallon': Mineral(buy=0.00, sell=20.01),
    'nocxium': Mineral(buy=450.00, sell=380.02),
    'pyerite': Mineral(buy=8.99, sell=8.71),
    'tritanium': Mineral(buy=2.50, sell=2.50),
}

ores = {
    'veldspar': Ore(
	volume=0.1,
	portion=333,
	minerals={'tritanium': 1000},
    ),
    'concentrated veldspar': Ore(
	volume=0.1,
	portion=333,
	minerals={'tritanium': 1050},
    ),
    'dense veldspar': Ore(
	volume=0.1,
	portion=333,
	minerals={'tritanium': 1100},
    ),
    'scordite': Ore(
	volume=0.15,
	portion=333,
	minerals={'tritanium': 833, 'pyerite': 416},
    ),
    'condensed scordite': Ore(
	volume=0.15,
	portion=333,
	minerals={'tritanium': 875, 'pyerite': 437},
    ),
    'massive scordite': Ore(
	volume=0.15,
	portion=333,
	minerals={'tritanium': 916, 'pyerite': 458},
    ),
    'pyroxeres': Ore(
	volume=0.3,
	portion=333,
	minerals={'tritanium': 844, 'pyerite': 59, 'mexallon': 120, 'nocxium': 11},
    ),
    'solid pyroxeres': Ore(
	volume=0.3,
	portion=333,
	minerals={'tritanium': 886, 'pyerite': 62, 'mexallon': 126, 'nocxium': 12},
    ),
    'viscous pyroxeres': Ore(
	volume=0.3,
	portion=333,
	minerals={'tritanium': 928, 'pyerite': 65, 'mexallon': 132, 'nocxium': 12},
    ),
    'kernite': Ore(
	volume=1.2,
	portion=400,
	minerals={'tritanium': 386, 'mexallon': 773, 'isogen': 386},
    ),
    'luminous kernite': Ore(
	volume=1.2,
	portion=400,
	minerals={'tritanium': 405, 'mexallon': 812, 'isogen': 405},
    ),
    'fiery kernite': Ore(
	volume=1.2,
	portion=400,
	minerals={'tritanium': 425, 'mexallon': 850, 'isogen': 425},
    ),
    'jaspet': Ore(
	volume=2,
	portion=500,
	minerals={'tritanium': 259, 'pyerite': 259, 'mexallon': 518, 'nocxium': 259},
    ),
    'pure jaspet': Ore(
	volume=2,
	portion=500,
	minerals={'tritanium': 272, 'pyerite': 272, 'mexallon': 544, 'nocxium': 272},
    ),
    'pristine jaspet': Ore(
	volume=2,
	portion=500,
	minerals={'tritanium': 285, 'pyerite': 285, 'mexallon': 570, 'nocxium': 285},
    ),
}

def iskPerCM(ore, yieldr):
    yields = ores[ore].refine(1, yieldr)
    return sum(minerals[mineral].sell(amount) for mineral, amount in yields)

class Miner:
    def __init__(self, character, minerIIs=0, stripMiners=0, ospreySkill=0):
	multiplier = 1 + 0.05 * character.getSkill(u'Mining')
        multiplier *= 1 + 0.05 * character.getSkill(u'Astrogeology')
        multiplier *= 1 + 0.2 * ospreySkill

        stripMultiplier = 1 + 0.03 * character.getSkill(u'Mining Barge')

	laserRate = minerIIs * 1 * multiplier
	stripRate = stripMiners * 3 * multiplier * stripMultiplier
	self.rate = laserRate + stripRate

def formatIsk(isk):
    return locale.format('%0.2f', isk, True)

def minmax(value, min_, max_):
    return min(max(value, min_), max_)

def getYield(standing, refining, refineryEfficiency, oreEfficiency=0, stationEquipment=50, recyclingConstant=37.5):
    skillMultiplier = (1 + refining * 0.02) * (1 + refineryEfficiency * 0.04) * (1 + oreEfficiency * 0.05)
    baseYield = minmax(stationEquipment + recyclingConstant * skillMultiplier, 0, 100)
    stationFee = max(5 - standing * 0.75, 0)
    return baseYield / 100 * (1 - stationFee / 100)

YIELD = getYield(standing=1.7675774979, refining=5, refineryEfficiency=4, oreEfficiency=1)
print YIELD

def iskPerHour(miner, ore):
    perSecond = iskPerCM(ore, YIELD) * miner.rate
    return formatIsk(perSecond * 60 * 60)

mithrandi = skilltree.getCharacters(file('skills.xml').read()).next()

retriever = Miner(mithrandi, stripMiners=2)
covetor = Miner(mithrandi, stripMiners=3)
#maller = Miner('maller', 4, 3, minerIIs=5)
#armageddon = Miner('armageddon', 4, 3, minerIIs=7)
#prophecy = Miner('prophecy', 4, 3, minerIIs=6)

profit = [(ore, iskPerCM(ore, YIELD)) for ore in ores]
profit.sort(key=lambda x: x[1], reverse=True)

for ore, perVolume in profit:
    print '%s: %s / m^3, %s / can' % (ore, formatIsk(perVolume), formatIsk(perVolume * 27500))

def showProfit(miner, ore):
    print '%s: %s isk / hour' % (ore, iskPerHour(miner, ore))

def showCanRate(name, miner):
    print '%s: %0.2f minutes / can' % (name, 27500 / miner.rate / 60)

def showLoadRate(name, miner, load):
    print '%s - %s: %0.2f minutes / load' % (name, load, load / miner.rate / 60)

print '-----'

showCanRate('covetor', covetor)
showProfit(covetor, 'massive scordite')
