"""
VN Scene Script Ext - MMDD
by Countd360
Provide functions to interact with MMDD

Command information all in 'act' param, which is a dict, may contants:
    "origintext": raw text format of this command
    "action": command name
    "actionparam": param 1, option
    "actionparam2": param 2, option
    "actionparam3": param 3, option

contents:
    mmdd_clear
    mmdd_load
    mmdd_start
    mmdd_stop
    mmdd_goto
    mmdd_setup
    mmdd_wait
    mmdd_isplay

Function: mmdd_clear - clear MMDD data
Syntax:
    mmdd_clear:[exclude]
Examples:
    mmdd_clear      - clear all data
    mmdd_clear:1    - clear motion/morph/music

Function: mmdd_load - load MMDD data
Syntax:
    mmdd_load:[dataset]:[onLoad]:[onFail]
Examples:
    mmdd_load           - load default save data
    mmdd_load:dance1    - load data 'dance1'
    mmdd_load:dance1:200:end    - load data 'dance1', go cam 200 if success else go end

Function: mmdd_start - start dance
Syntax:
    mmdd_start
Examples:
    mmdd_start

Function: mmdd_stop - stop dance
Syntax:
    mmdd_stop
Examples:
    mmdd_stop

Function: mmdd_goto - jump to frame, only work when dance stopped
Syntax:
    mmdd_goto:frameNo
Examples:
    mmdd_goto:100       - jump to frame 100

Function: mmdd_setup - setup start/end/loop setting
Syntax:
    mmdd_setup:startfrom/endat/loop
Examples:
    mmdd_setup:100:200:1       - dance from frame 100 - 200, loops

Function: mmdd_wait - wait until dance is over, then goto next cam
Syntax:
    mmdd_wait:uiOption
    uiOption can be 'hide' or 'lock' or 'onchange'
Examples:
    mmdd_wait:hide       - hide ui until dance over, then goto next cam

Function: mmdd_isplay - check if mmdd is playing, change next cam. Note, the cmd will not go next by itself, need user click next button or use other cmd like 'timernext'
Syntax:
    mmdd_isplay:onPlay:onStop
Examples:
    mmdd_isplay:200:300   - go to cam 200 next if MMDD is playing, else goto 300.


"""

import mmddirector
import vnanime
from vnscenescript import statestr_to_int, run_state

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

    # get mmdd instance
    if hasattr(game.gdata, "mmdd"):
        mmdd = game.gdata.mmdd
    else:
        mmdd = mmddirector.MMDDirector(game)
        game.gdata.mmdd = mmdd
    # in case mmdd with clip control
    if not vnanime.check_keyframe_anime(game):
        vnanime.init_keyframe_anime(game)        

    # clear
    if act["action"] == "mmdd_clear":
        try:
            # clear mmdd setting
            if act.has_key("actionparam"):
                exclude = bool(eval(act["actionparam"]))
            else:
                exclude = False
            # do cleanup
            mmdd.cleanup(exclude)
        except Exception, e:
            print "mmdd_clear error, can't parse command '%s':"%act["origintext"], e
        return True

    # load
    if act["action"] == "mmdd_load":
        try:
            # load mmdd setting from scene
            if act.has_key("actionparam") and len(act["actionparam"]) > 0:
                name = act["actionparam"]
            else:
                name = "save"
            if act.has_key("actionparam2") and len(act["actionparam2"]) > 0:
                onOK = statestr_to_int(game, act["actionparam2"])
            else:
                onOK = None
            if act.has_key("actionparam3") and len(act["actionparam3"]) > 0:
                onNG = statestr_to_int(game, act["actionparam3"])
            else:
                onNG = None
            # do load
            #print "loading mmdd data <%s>"%name
            err = mmdd.loadFromScene(name)
            if err:
                print "mmdd_load error: %s, onNG = "%err, onNG
                if onNG != None:
                    #run_state(game, onNG, True)
                    game.scenedata.scNextState = onNG
            else:
                print "mmdd_load done, onOK =", onOK
                if onOK != None:
                    #run_state(game, onOK, True)
                    game.scenedata.scNextState = onOK
        except Exception, e:
            print "mmdd_load error, can't parse command '%s':"%act["origintext"], e
        return True

    # start
    if act["action"] == "mmdd_start":
        try:
            # start
            mmdd.start()
        except Exception, e:
            print "mmdd_start error, can't parse command '%s':"%act["origintext"], e
        return True

    # stop
    if act["action"] == "mmdd_stop":
        try:
            # stop
            mmdd.stop()
        except Exception, e:
            print "mmdd_stop error, can't parse command '%s':"%act["origintext"], e
        return True

    # goto
    if act["action"] == "mmdd_goto":
        try:
            # goto
            mmdd.gotoFrame(int(act["actionparam"]))
        except Exception, e:
            print "mmdd_goto error, can't parse command '%s':"%act["origintext"], e
        return True

    # setup
    if act["action"] == "mmdd_setup":
        try:
            mmdd.setStartFrame(int(act["actionparam"]))
            mmdd.setEndFrame(int(act["actionparam2"]))
            mmdd.loop = bool(eval(act["actionparam3"]))
        except Exception, e:
            print "mmdd_setup error, can't parse command '%s':"%act["origintext"], e
        return True

    # wait
    if act["action"] == "mmdd_wait":
        try:
            ui = act["actionparam"]
            def on_mmdd_next(game):
                # restore ui
                if ui == "lock":
                    game.isHideGameButtons = False
                elif ui == "hide":
                    game.visible = True
                else:
                    pass    # do nothing to ui
                # go next
                from vnscenescript import _on_timer_next
                _on_timer_next(game)
            # adjust ui
            if ui == "lock":
                game.isHideGameButtons = True
            elif ui == "hide":
                game.visible = False
            else:
                pass    # do nothing to ui
            # set a timer
            if mmdd.isPlaying:
                toend = float(mmdd.EndFrame - mmdd.curFrame) / mmdd.playFPS
                print "Wait from %d to %d, regist timer of %fsec"%(mmdd.curFrame, mmdd.EndFrame, toend)
            else:
                toend = 0.2
            game.set_timer(toend, on_mmdd_next)
        except Exception, e:
            print "mmdd_wait error, can't parse command '%s':"%act["origintext"], e
        return True

    # isplay
    if act["action"] == "mmdd_isplay":
        try:
            if mmdd.isPlaying and act.has_key("actionparam") and len(act["actionparam"]) > 0:
                onPlay = statestr_to_int(game, act["actionparam"])
                game.scenedata.scNextState = onPlay
            if not mmdd.isPlaying and act.has_key("actionparam2") and len(act["actionparam2"]) > 0:
                onStop = statestr_to_int(game, act["actionparam2"])
                game.scenedata.scNextState = onStop
        except Exception, e:
            print "mmdd_isplay error, can't parse command '%s':"%act["origintext"], e
        return True

    # return False means this act is out of my scope        
    return False

def debug_buttons(game,state):
    # return in format of set_buttons_alt
    #return ["Demo btn (keitaro10)", demo1]
    return [] # if we want no additional buttons

