"""
VN Scene Script Ext - vnframe12
Provide functions to call VNFrame acts and anime functions

f_stinit, f_acts, f_actm, f_act, f_anime

1.2 - added f_actm_j for call with JSON serialized str
1.3 - added loadclothesfile, copyclothes
- loadclothesfile:act0:wedding.png
- copyclothes:act0:act1 (actor_to:actor_from)
1.4 - added copycharaeditordata, loadcharafile
- copycharaeditordata:act_dst:act_src:<flags>
- loadcharafile:act_to_replace:<keep height flag:0/1>:<filename or foldername>

Examples:
(init)
:useext:vnframe10
:a:i:f_stinit
(actual actions)
:a:0:f_acts:main:anim:(0,0,0)
:a:2:f_actm:main::{'anim':(7, 20, 2)}
:a:0:f_act:::{'desk': {'move_to': (1.043, 0.000, -0.810)}}
:a:3:f_act:::{'main': {'anim': (0, 4, 0), 'rotate_to': (0.000, 10.000, 0.000), 'anim_spd': 0.000}}
:a:4:f_act:::{'main': {'anim_spd': 1.000}}
:a:5:f_anime:::(({ 'desk': {'move_to': ((1.043, 0.000, -0.810), (1.043, 0.000, -0.362))},}, 1.00, 'linear'),)
:a:0:f_acts:sys:text:('s', 'Start pos!')
"""

from random import random
import vnframe


def custom_action(game,act):
    """:type game: vngameengine.VNNeoController"""

    # ------- texts --------
    if act["action"] == "f_actm_j":

        try:
            import libjsoncoder
            obj1 = libjsoncoder.json_decode(act["actionparam3"])
        except Exception as e:
            print("f_actm_j error, can't parse command '%s': %s"%(act["origintext"], str(e)))
            return True
        script = {act["actionparam"]: obj1}
        vnframe.act(game, script)

        #print "f_acts: ", script

        return True

    if act["action"] == "loadclothesfile":
        try:
            aid1 = act["actionparam"]
            if aid1 not in game._scenef_actors:
                raise Exception("Actor id <%s> is not registed!"%aid1)
            game._scenef_actors[aid1].load_clothes_file("UserData/coordinate/"+act["actionparam2"])
            return True
        except Exception as e:
            print("loadclothesfile error, can't parse command '%s': %s"%(act["origintext"], str(e)))
            return True

    if act["action"] == "copyclothes":
        try:
            aid1 = act["actionparam"]
            aid2 = act["actionparam2"]
            if aid1 not in game._scenef_actors:
                raise Exception("Actor id <%s> is not registed!"%aid1)
            if aid2 not in game._scenef_actors:
                raise Exception("Actor id <%s> is not registed!"%aid2)
            notacc = "0"
            if act.has_key("actionparam3"):
                notacc = act["actionparam3"]
            #game._scenef_actors[aid1].load_clothes_file("UserData/coordinate/"+act["actionparam2"])
            clothes = game._scenef_actors[aid2].get_curcloth_coordinate()
            actor = game._scenef_actors[aid1]
            if notacc == "1":
                actor.set_curcloth_coordinate_no_accessory(clothes)
            else:
                actor.set_curcloth_coordinate(clothes)
            return True
        except Exception as e:
            print("copyclothes error, can't parse command '%s': %s"%(act["origintext"], str(e)))
            return True

    if act["action"] == "copycharaeditordata":
        try:
            aid1 = act["actionparam"]
            aid2 = act["actionparam2"]
            if aid1 not in game._scenef_actors:
                raise Exception("Actor id <%s> is not registed!"%aid1)
            if aid2 not in game._scenef_actors:
                raise Exception("Actor id <%s> is not registed!"%aid2)
            optdata = "Body,Face,Hair"
            if act.has_key("actionparam3"):
                optdata = act["actionparam3"]
            opts = optdata.split(",")
            category = set()
            exclude = set()
            isForce = False
            for opt in opts:
                if opt in {"Body", "Face", "Hair", "Clothes", "Accessories"}:
                    category.add(opt)
                    continue
                if opt.startswith("-"):
                    exclude.add(opt[1:])
                    continue
                if opt == "_ForceFlg":
                    isForce = True
                    continue
                raise Exception("option <%s> is not defined!"%opt)
            from extplugins import CharaEditor
            ce = CharaEditor()
            if not ce.isDetected:
                raise Exception("CharaEditor plugin is not found. Need HS2StudioCharaEditor for HS2. Other games are not supported.")

            # get data from src char, use raw data
            actor_src = game.scenef_get_actor(aid2)
            chaData = ce.GetCharaEditorDataRawFiltered(actor_src.objctrl, category, exclude)
            # set to dst char
            actor_dst = game.scenef_get_actor(aid1)
            ce.SetCharaEditorDataRaw(actor_dst.objctrl, chaData, isForce)
            # done
            print("Copy <%s> to <%s:%s> from <%s:%s>... %d data copied"%(str(category), aid1, actor_dst.text_name, aid2, actor_src.text_name, len(chaData)))
            return True
        except Exception as e:
            print("copycharaeditordata error, can't parse command '%s': %s"%(act["origintext"], str(e)))
            import traceback
            traceback.print_exc()
            return True

    if act["action"] == "loadcharafile":
        from os import path
        def pickRandomPng(fromDir):
            from os import listdir
            from vngameengine import random_choice
            allfiles = listdir(fromDir)
            # filter
            pngfiles = []
            for file in allfiles:
                ext = path.splitext(file)[1].lower()
                if ext == ".png":
                    pngfiles.append(file)
            # pick
            if len(pngfiles):
                file = random_choice(pngfiles)
                return path.join(fromDir, file)
            else:
                raise Exception("No PNG file found in folder <%s>"%fromDir)

        try:
            aid = act["actionparam"]
            keepHeight = bool(eval(act["actionparam2"]))
            tgtInput = act["actionparam3"]
            if aid not in game._scenef_actors:
                raise Exception("Actor id <%s> is not registed!"%aid)
            actor_tgt = game.scenef_get_actor(aid)
            if keepHeight:
                actor_height = actor_tgt.height

            from UnityEngine import Application
            gameFolder = path.realpath(path.join(Application.dataPath, '..'))
            if actor_tgt.sex == 0:
                charaFolder = path.join(gameFolder, "userdata\\chara\\male")
            else:
                charaFolder = path.join(gameFolder, "userdata\\chara\\female")
            if path.isfile(tgtInput):
                tgtPath = tgtInput
            elif path.isdir(tgtInput):
                tgtPath = pickRandomPng(tgtInput)
            elif not path.isabs(tgtInput):
                tgtInput2 = path.abspath(path.join(charaFolder, tgtInput))
                if path.isfile(tgtInput2):
                    tgtPath = tgtInput2
                elif path.isdir(tgtInput2):
                    tgtPath = pickRandomPng(tgtInput2)
                else:
                    tgtPath = pickRandomPng(charaFolder)
                    print("Cannot found file or folder <%s>, load a random chara from <%s>."%(tgtInput, charaFolder))
            else:
                tgtPath = pickRandomPng(charaFolder)
                print("Cannot found file or folder from absolute path <%s>, load a random chara from <%s>"%(tgtInput, charaFolder))

            if not path.isfile(tgtPath):
                # in case no PNG is picked
                raise Exception("Can not found any PNG file to load!")

            # change actor
            actor_tgt.objctrl.ChangeChara(tgtPath)
            if keepHeight:
                actor_tgt.height = actor_height

            # done
            print("Replace <%s:%s> with <%s>"%(aid, actor_tgt.text_name, tgtPath))
            return True
        except Exception as e:
            print("loadcharafile error, can't parse command '%s': %s"%(act["origintext"], str(e)))
            return True


    import vnscenescriptext_vnframe11
    return vnscenescriptext_vnframe11.custom_action(game,act)


# -----

def debug_buttons(game,state):
    return [] # if we want no additional buttons

    # return in format of set_buttons_alt
    #return ["Demo btn (keitaro10)", demo1]

def demo1(game):
    """:type game: vngameengine.VNNeoController"""
    game.show_blocking_message_time("Some demo message")