#!/usr/bin/env python3

import json
import math
import os
import subprocess
import sys

from lxml import etree
from PIL import Image

if getattr(sys, 'frozen', False): # we are running in a bundle
    bundle_dir = sys._MEIPASS
else: # we are running in a normal Python environment
    bundle_dir = os.path.dirname(os.path.abspath(__file__))

CARD_WIDTH = 181 * 4
CARD_HEIGHT = 253 * 4

def setText(tree, id, text):
    element = tree.find('.//*[@id="' + id + '"]')
    if element is None:
        print("id", id, "not found")
        return
    elif element.tag == "{http://www.w3.org/2000/svg}flowRoot":
        element.find("{http://www.w3.org/2000/svg}flowPara").text = text
    else:
        element[0].text = str(text)

def removeElement(tree, id):
    mark = tree.find('.//*[@id="' + id + '"]')
    if mark is not None:
        mark.getparent().remove(mark)

def makeSVG(base, properties):
    tree = etree.parse(base)
    for id, text in properties.items():
        if id not in ["count", "art"]:
            setText(tree, id, text)

    # remove HP mark if there is no hp
    if "hp" not in properties:
        removeElement(tree, "hpMark")

    if "art" in properties:
        art = tree.find('.//*[@id="art"]')
        if art is not None:
            art.set("{http://www.w3.org/1999/xlink}href",
                    "file://" + bundle_dir + "/" + properties["art"])
    return tree

def addCardToBase(svg, baseImg, baseX, cardNum):
    # TODO: possible to remove all this writing to temp files?
    dest = "out/fig" + str(cardNum)
    svg.write(dest + ".svg")
    subprocess.call(["inkscape", "-z", "-f", dest + ".svg", "-w",
                     str(CARD_WIDTH), "-e", dest + ".png"])
    cardImg = Image.open(dest + ".png")
    baseImg.paste(cardImg, ((cardNum % baseX) * cardImg.width,
                            int(cardNum / baseX) * cardImg.height))

def makeFace(baseImage, baseX, cardNum, base, card):
    fig = makeSVG(base, card)
    addCardToBase(fig, baseImage, baseX, cardNum)

def makeFaces(deckJson, outfile):
    baseX = math.ceil(math.sqrt(len(deckJson['deck']) + len(deckJson['character']) * 2))
    baseImage = Image.new('RGB', (CARD_WIDTH * baseX,
                                  CARD_HEIGHT * baseX))

    cardType = deckJson["type"]

    cardNum = 0
    # Make a card for each character card
    if cardType == "hero":
        for card in deckJson['character']:
            makeFace(baseImage, baseX, cardNum,
                     os.path.join("images", cardType, "charFront.svg"), card)
            cardNum += 1

            makeFace(baseImage, baseX, cardNum,
                     os.path.join("images", cardType, "charBack.svg"), card)
            cardNum += 1

    if cardType == "villain":
        pass

    # Make a card for each card
    for card in deckJson['deck']:
        makeFace(baseImage, baseX, cardNum,
                 os.path.join("images", cardType, "card.svg"), card)
        cardNum += 1

    baseImage.save(outfile + ".png", "PNG")
    return baseX

def makeJson(deckJson, imgWidth, outfile):
    with open(bundle_dir + "/templates/deck.json") as f:
        outJson = json.load(f)
    with open(bundle_dir + "/templates/card.json") as f:
        cardTemplate = json.load(f)

    # number of cards in x and y direction
    outJson['ObjectStates'][0]['CustomDeck']['1'].update(
        {"NumWidth": imgWidth,
         "NumHeight": imgWidth,
         #"FaceURL": "http://adam-desktop.dyn.wpi.edu:8000/" + outfile + ".png",
         "FaceURL": "file://" + os.getcwd() + "/" + outfile + ".png",
         "BackURL": "http://cloud-3.steamusercontent.com/ugc/156906385556221451/CE2C3AFE1759790CB0B532FFD636D05A99EC91F4/"})

    # decks start at (10 * deck id)
    cardNum = 100
    for card in deckJson['character']:
        outJson['ObjectStates'][0]['DeckIDs'].append(cardNum)

        # add front card with back as second state
        cardOutBack = cardTemplate.copy()
        cardOutBack.update({"Nickname": card['name'],
                            "Description": "Incapacitated",
                            "CardID": cardNum + 1})
        cardOut = cardTemplate.copy()
        cardOut.update({"Nickname": card['name'],
                        "Description": "Active",
                        "CardID": cardNum,
                        "States": {"2": cardOutBack}})
        outJson['ObjectStates'][0]['ContainedObjects'].append(cardOut)
        cardNum += 2

    for card in deckJson['deck']:
        for i in range(0, card['count']):
            outJson['ObjectStates'][0]['DeckIDs'].append(cardNum)

            # add a card object thing for each card, and give it a name
            cardOut = cardTemplate.copy()
            cardOut.update({"Nickname": card['name'],
                            "Description": card.get('type', ""),
                            "CardID": cardNum})
            outJson['ObjectStates'][0]['ContainedObjects'].append(cardOut)
        cardNum += 1

    with open(outfile + ".json", "w") as f:
        json.dump(outJson, f)

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print("not enough arguments!")
        inputJson = input("Input file: ")
        outfile = input("Output file (no suffix): ")
    else:
        inputJson = sys.argv[1]
        outfile = sys.argv[2]

    with open(inputJson) as f:
        deckJson = json.load(f)

    imgWidth = makeFaces(deckJson, outfile)
    makeJson(deckJson, imgWidth, outfile)
