CancelTypes = {
    MouseClickOnly:3,
    AnyKey:2,
    MouseClickOrAnyKey:1,
    SpecificKey:4,
    None:0
};
WaitModes = {
    WaitForUser:0,
    WaitFor:1,
    WaitForTimer:2
};
SkipEventTriggers = {
    Mouse:0,
    Keyboard:1,
    Action:2
};
Ext.define('SkipEvent', {
    constructor:function (trigger, eventObject) {
        this.Trigger = trigger;
        this.EventObject = eventObject;
    },
    toString:function () {
        return Ext.String.format('SkipEvent:\nTrigger: {0}\nEventObject:\n{1}', this.Trigger, print(this.EventObject));
    }
});
Ext.define('AuthorPause', {
    constructor:function (source, waitMode, waitTime, cancelType, cancelKey1, cancelKey2, timerValue, timerID) {
        this.Source = source;
        this.WaitMode = waitMode;
        this.WaitTime = waitTime;

        this.CancelType = cancelType;
        this.CancelKey1 = cancelKey1;
        this.CancelKey2 = cancelKey2;
        this.StartTime = new Date();

        if (typeof(timerValue) == 'undefined') {
            timerValue = 0;
        }
        if (typeof(timerID) == 'undefined') {
            timerID = -1;
        }


        this.TimerValue = timerValue;
        this.TimerID = timerID;

        if (this.TimerID > 0) {
            if (Author.LessonManager.AuthorLesson.InternalTimer == null){
               // Author.log("Process a wait for timer pause, but no start timer is set before.\n Automatically start a internal timer.");
                Author.LessonManager.AuthorLesson.registerInternalTimer(new InternalTimer(null));
            }
        }

    },
    toString:function () {
        return Ext.String.format("Pause Source: {0}, type: {1}, waitTime: {2}, cancelType: {3}, key1: {4}, key2: {5}", (this.Source), this.WaitMode, this.WaitTime, this.CancelType, this.CancelKey1, this.CancelKey2);
    },
    skipPauseByKeyDown:function (e) {
        var keyCode = e.getKey();
        var keyShift = (e.shiftKey ? 1 : 0) + (e.ctrlKey ? 2 : 0) + (e.altKey ? 4 : 0);
        var keyPressed = Author.keyNameMap[keyCode];
        if (keyShift == 0)
            keyShift = 8;
        var keyCodeStr = keyCode + "," + keyShift;

        if (this.CancelType == CancelTypes.SpecificKey && (keyCodeStr == this.CancelKey1 || keyCodeStr == this.CancelKey2)) {
            this.onSkipped(new SkipEvent(SkipEventTriggers.Keyboard, {
                Event:e,
                Key:keyPressed
            }));
            return;
        }

        if(this.CancelType == CancelTypes.AnyKey || this.CancelType == CancelTypes.MouseClickOrAnyKey){

            var modifierKeyCodes = [16, 17, 18]; // shift: 16, ctrl: 17, alt: 18
            // in case of skip pause by any key, only skip pause when the key just pressed was not ctrl, shift or alt
            if(modifierKeyCodes.indexOf(keyCode) >= 0){
                return;
            }
            this.onSkipped(new SkipEvent(SkipEventTriggers.Keyboard, {
                Event:e,
                Key:keyPressed
            }));
        }
    },
    skipPauseByMouseClick:function (e, t, o) {
        if (this.CancelType == CancelTypes.MouseClickOnly || this.CancelType == CancelTypes.MouseClickOrAnyKey) {
            this.onSkipped(new SkipEvent(SkipEventTriggers.Mouse, {
                Event:e,
                Key:'MouseClick'
            }));
        }
    },
    onSkipped:function (skipEvent) {
        if (typeof(this.Source.onSkippedByUser) == 'function') {

            this.Source.onSkippedByUser(skipEvent);
        }
    },

    onTimerReached:function (time) {
        if (typeof(this.Source.onTimerReached) == 'function') {
            this.Source.onTimerReached(time);
        }
    }
});
Ext.define('PauseClass15', {
    extend:'GeneralAction',
    constructor:function (cfgXML, o, actionSequence) {
        this.WaitMode = WaitModes.WaitForUser;
        this.WaitTime = 3600 * 24 * 1000;
        this.CancelType = CancelTypes.MouseClickOrAnyKey;
        this.CancelKey1 = null;
        this.CancelKey2 = null;
        this.StartTime = new Date();
        this.callParent([ cfgXML, o, actionSequence]);
        this.WaitMode = XmlHelper.getInteger(cfgXML, "waitMode");
        this.WaitTime = XmlHelper.tryGetValue(cfgXML, "waitTime", TryGetValueOption.Float, 3600 * 24) * 1000;
        this.TimerValue = XmlHelper.tryGetValue(cfgXML, "timerValue", TryGetValueOption.Float, 0) * 1000;
        this.TimerID = XmlHelper.tryGetValue(cfgXML, "timerID", TryGetValueOption.Integer, -1);
        this.CancelType = XmlHelper.getInteger(cfgXML, "cancelType");
        this.CancelKey1 = XmlHelper.tryGetValue(cfgXML, "key1", TryGetValueOption.Normal, null);
        this.CancelKey2 = XmlHelper.tryGetValue(cfgXML, "key2", TryGetValueOption.Normal, null);
        this.StartTime = new Date();
        if (this.WaitMode == WaitModes.WaitForUser) {
            this.WaitTime = 3600 * 24 * 1000;
        }
        if (this.WaitMode == WaitModes.WaitForTimer) {
            this.WaitTime = 3600 * 24 * 1000;
        }
    },
    processAction:function () {
        Author.DisplayManager.Pause = this.toAuthorPause();
        if (this.WaitMode == WaitModes.WaitForTimer) {
            Author.DisplayManager.startCheckingTimer();
        }
        return {MoveOn:true, Interval:this.WaitTime};
    },
    toString:function () {
        return Ext.String.format("Pause ID: {0}, type: {1}, waitTime: {2}, cancelType: {3}, key1: {4}, key2: {5}", this.id, this.WaitMode, this.WaitTime, this.CancelType, this.CancelKey1, this.CancelKey2);
    },
    toAuthorPause:function () {
        return new AuthorPause(this, this.WaitMode, this.WaitTime, this.CancelType, this.CancelKey1, this.CancelKey2, this.TimerValue, this.TimerID);
    },
    onSkippedByUser:function (skipEvent) {
       // Author.log("Pause skippedByUser: " + this);

        if (Author.DisplayManager.Pause) {
            if (Author.DisplayManager.Pause.Source.id = this.id) {
                Author.DisplayManager.Pause = null;
            }
        }
        window.clearTimeout(Author.DisplayManager.ActionTimer);
        Author.DisplayManager.processListActions();
    },
    onTimerReached:function (time) {
        if (Author.DisplayManager.Pause) {
            if (Author.DisplayManager.Pause.Source.id = this.id) {
                Author.DisplayManager.Pause = null;
            }
        }
       // Author.log("Timer triggered at " + time);
        window.clearTimeout(Author.DisplayManager.ActionTimer);
        Author.DisplayManager.processListActions();
    }
});




