"""
VN Scene Script Ext - schedule10
Provide functions to schedule scene jump or run VNSS command.
This is an advanced version of timernext, it can be managered and cancelled

schedulescene, schedulevnss, cancelschedule, checkschedule

v1.0: 
- add schedulescene, schedulevnss, cancelschedule, checkschedule function

v1.1:
- support call from vnphy action


Function: schedulescene - schedule a scene, this is an advanced verion of timernext command.
Syntax:
    schedulescene:sid:sec:sceneindex
Example:
    schedulescene:s1:10:200      - jump to scene 200 after 10 second, schedule id is s1

Function: schedulevnss - schedule a vnss cmd, can be blank
Syntax:
    schedulevnss:sid:sec:[VNSS cmd]
Example:
    schedulevnss:s1:10:showui    - run "showui" cmd after 10 second, schedule id is s1

Function: cancelschedule - cancel a schedule
Syntax:
    cancelschedule:sid
Example:
    cancelschedule:s1            - cancel schedule with id = s1

Function: checkschedule - get a schedule timer value
Syntax:
    checkschedule:sid:varname
Example:
    checkschedule:s1:s1time      - check schedule with id = s1, set time value to blackrain var s1, time value = 0 if not valid

"""

from vnscenescript import statestr_to_int, run_state, run_action

def init_schedule(game):
    if not hasattr(game.scenedata, "vnss_schedule"):
        game.scenedata.vnss_schedule = {}

def cancel_schedule(game, sid):
    init_schedule(game)
    if sid in game.scenedata.vnss_schedule:
        (timerId, _) = game.scenedata.vnss_schedule.pop(sid)
        game.clear_timer(timerId, False)

def check_schedule(game, sid):
    init_schedule(game)
    if sid in game.scenedata.vnss_schedule:
        (timerId, _) = game.scenedata.vnss_schedule[sid]
        if 0 <= timerId < len(game.timers):
            remain = game.timers[timerId]
            print "check schedule %s: remain %f second"%(sid, remain)
            return remain if remain > 0 else 0
    print "check schedule %s: not found, may be run out"%(sid)
    return 0

def start_schedule(game, sid, stime, action):
    cancel_schedule(game, sid)
    timerId = game.set_timer(stime, run_schedule_action)
    if timerId != -1:
        game.scenedata.vnss_schedule[sid] = (timerId, action)
        return True
    else:
        return False

def run_schedule_action(game):
    # get sid
    timerId = -1
    for i in range(len(game.timers)):
        if game.timers[i] <= 0 and game.timersFuncEnd[i] == run_schedule_action:
            timerId = i
            break
    if timerId == -1:
        raise Exception("run_schedule_action error: Timer ID not detected!?")
    sid = None
    for tsid in game.scenedata.vnss_schedule:
        if game.scenedata.vnss_schedule[tsid][0] == timerId:
            sid = tsid
            break
    if sid == None:
        raise Exception("run_schedule_action error: Schedule ID not detected for timer id = %d!?"%timerId)
    # pick action and clear schedule
    (timerId, action) = game.scenedata.vnss_schedule.pop(sid)
    game.clear_timer(timerId, False)
    # run by action type
    if action == None:
        # null command, do nothing
        print "Run schedule %s: Null VNSS command"%(sid)
        pass
    elif isinstance(action, int):
        # goto scene
        print "Run schedule %s: goto scene %d"%(sid, action)
        run_state(game, action, True)
    else:
        # run vnss cmd
        print "Run schedule %s: run vnss cmd %s"%(sid, str(action))
        run_action(game, action)

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

    if act["action"] == "schedulescene":
        try:
            sid = act["actionparam"]
            stime = float(act["actionparam2"])
            saction = statestr_to_int(game, act["actionparam3"])
            start_schedule(game, sid, stime, saction)
            return True
        except Exception, e:
            print "schedulescene error, can't parse command '%s':"%act["origintext"], e
            return True

    if act["action"] == "schedulevnss":
        def parse_subact(txt):
            if len(txt.strip()) == 0:
                return None
            ar = txt.split(":", 3)
            sact = {}
            # act["arcode"] = ar
            sact["origintext"] = txt
            if "states" in act:
                sact["states"] = act["states"]
            sact["action"] = ar[0]
            if len(ar) > 1:
                sact["actionparam"] = ar[1]
                if len(ar) > 2:
                    sact["actionparam2"] = ar[2]
                    if len(ar) > 3:
                        sact["actionparam3"] = ar[3]
            return sact
        try:
            sid = act["actionparam"]
            stime = float(act["actionparam2"])
            saction = parse_subact(act["actionparam3"])
            start_schedule(game, sid, stime, saction)
            return True
        except Exception, e:
            print "schedulevnss error, can't parse command '%s':"%act["origintext"], e
            return True

    if act["action"] == "cancelschedule":
        try:
            sid = act["actionparam"]
            cancel_schedule(game, sid)
            return True
        except Exception, e:
            print "cancelschedule error, can't parse command '%s':"%act["origintext"], e
            return True

    if act["action"] == "checkschedule":
        try:
            sid = act["actionparam"]
            varname = act["actionparam2"]
            if not hasattr(game.gdata, 'brVars'):
                game.gdata.brVars = {}
            game.gdata.brVars[varname] = check_schedule(game, sid)
            return True
        except Exception, e:
            print "checkschedule error, can't parse command '%s':"%act["origintext"], e
            return True


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

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