void ONScripter::timerEvent()
{
    if (remaining_time == 0){
        SDL_Event event;
        event.type = ONS_BREAK_EVENT;
        SDL_PushEvent(&event);
        return;
    }
    
    int duration = 0;
    if (event_mode & WAIT_TIMER_MODE){
        proceedAnimation();
        duration = calcDurationToNextAnimation();
    }
            
    if (duration > 0){
        if (remaining_time > duration){
            remaining_time -= duration;
        }
        else if (remaining_time > 0){
            duration = remaining_time;
            remaining_time = 0;
        }
        stepAnimation(duration);
        if (timer_id) SDL_RemoveTimer(timer_id);
        timer_id = SDL_AddTimer(duration, timerCallback, NULL);
    }
    else if (remaining_time > 0){
        if (timer_id) SDL_RemoveTimer(timer_id);
        timer_id = SDL_AddTimer(remaining_time, timerCallback, NULL);
        remaining_time = 0;
    }
}
void ONScripter::timerEvent(int count)
{
    if (!(event_mode & WAIT_TIMER_MODE)) return;

    int duration = proceedAnimation();
            
    if (duration > 0){
        if (count == -1 || duration < count){
            resetRemainingTime( duration );
            advancePhase( duration );
        }
        else{
            resetRemainingTime( count );
        }
    }
}
void PonscripterLabel::startTimer(int count)
{
    int duration = proceedAnimation();

    if (duration > 0 && duration < count) {
        resetRemainingTime(duration);
        advancePhase(duration);
        remaining_time = count;
    }
    else {
        advancePhase(count);
        remaining_time = 0;
    }

    event_mode |= WAIT_TIMER_MODE;
}
void PonscripterLabel::timerEvent(void)
{
    timerEventTop:

    int ret;

    if (event_mode & WAIT_TIMER_MODE) {
        int duration = proceedAnimation();

        if (duration == 0
            || (remaining_time >= 0
                && remaining_time - duration <= 0)) {
            bool end_flag  = true;
            bool loop_flag = false;
            if (remaining_time >= 0) {
                remaining_time = -1;
                if (event_mode & WAIT_VOICE_MODE && wave_sample[0]) {
                    end_flag = false;
                    if (duration > 0) {
                        resetRemainingTime(duration);
                        advancePhase(duration);
                    }
                }
                else {
                    loop_flag = true;
                    if (automode_flag || autoclick_time > 0)
                        current_button_state.button = 0;
                    else if (usewheel_flag)
                        current_button_state.button = -5;
                    else
                        current_button_state.button = -2;
                }
            }

            if (end_flag
                && event_mode & (WAIT_INPUT_MODE | WAIT_BUTTON_MODE)
                && (clickstr_state == CLICK_WAIT
                    || clickstr_state == CLICK_NEWPAGE)) {
                playClickVoice();
                stopAnimation(clickstr_state);
            }

            if (end_flag || duration == 0)
                event_mode &= ~WAIT_TIMER_MODE;

            if (loop_flag) goto timerEventTop;
        }
        else {
            if (remaining_time > 0)
                remaining_time -= duration;

            resetRemainingTime(duration);
            advancePhase(duration);
        }
    }
    else if (event_mode & EFFECT_EVENT_MODE) {
        const char* current = script_h.getCurrent();
        ret = this->parseLine();

        if (ret & RET_CONTINUE) {
            if (ret == RET_CONTINUE) {
                readToken(); // skip trailing \0 and mark kidoku
            }

            if (effect_blank == 0 || effect_counter == 0) goto timerEventTop;

            startTimer(effect_blank);
        }
        else {
            script_h.setCurrent(current);
            readToken();
            advancePhase();
        }

        return;
    }
    else {
        if (system_menu_mode != SYSTEM_NULL
            || (event_mode & WAIT_INPUT_MODE
                && volatile_button_state.button == -1)) {
            if (!system_menu_enter_flag)
                event_mode |= WAIT_TIMER_MODE;

            executeSystemCall();
        }
        else
            executeLabel();
    }

    volatile_button_state.button = 0;
}