define("umlStateMachine", ["umlStateMachineApi", "clientkernelModulesApi", "clientkernelLoggerApi"],
    function(umlStateMachineApi, clientkernelModulesApi, clientkernelLoggerApi) {
        "use strict";

        function $iterator(o) {
            if (o instanceof Array) return function() {
                return {
                    cur: 0,
                    arr: o,
                    hasNext: function() {
                        return this.cur < this.arr.length;
                    },
                    next: function() {
                        return this.arr[this.cur++];
                    }
                };
            };
            return typeof(o.iterator) == 'function' ? $bind(o, o.iterator) : o.iterator;
        };;
        var $fid = 0;

        function $bind(o, m) {
            if (m == null) return null;
            if (m.__id__ == null) m.__id__ = $fid++;
            var f;
            if (o.hx__closures__ == null) o.hx__closures__ = {};
            else f = o.hx__closures__[m.__id__];
            if (f == null) {
                f = function() {
                    return f.method.apply(f.scope, arguments);
                };
                f.scope = o;
                f.method = m;
                o.hx__closures__[m.__id__] = f;
            }
            return f;
        };
        var $_;
        var $estr = function() {
            return _hcmn_.js_Boot.__string_rec(this, '');
        };
        if (typeof haxe == 'undefined') {
            var haxe = {};
        };

        haxe.IMap = function() {}
        haxe.IMap.prototype = {

        };
        if (!haxe.ds) {
            haxe.ds = {};
        };
        haxe.ds.BalancedTree = function() {};
        haxe.ds.BalancedTree.__name__ = ["haxe", "ds", "BalancedTree"];
        haxe.ds.BalancedTree.prototype.root = null;
        haxe.ds.BalancedTree.prototype.set = function(key, value) {
            this.root = this.setLoop(key, value, this.root);
        };
        haxe.ds.BalancedTree.prototype.get = function(key) {
            var node = this.root;
            while (node != null) {
                var c = this.compare(key, node.key);
                if (c == 0) return node.value;
                if (c < 0) node = node.left;
                else node = node.right;
            }
            return null;
        };
        haxe.ds.BalancedTree.prototype.exists = function(key) {
            var node = this.root;
            while (node != null) {
                var c = this.compare(key, node.key);
                if (c == 0) return true;
                else if (c < 0) node = node.left;
                else node = node.right;
            }
            return false;
        };
        haxe.ds.BalancedTree.prototype.setLoop = function(k, v, node) {
            if (node == null) return new haxe.ds.TreeNode(null, k, v, null);
            var c = this.compare(k, node.key);
            if (c == 0) return new haxe.ds.TreeNode(node.left, k, v, node.right, node == null ? 0 : node._height);
            else if (c < 0) {
                var nl = this.setLoop(k, v, node.left);
                return this.balance(nl, node.key, node.value, node.right);
            } else {
                var nr = this.setLoop(k, v, node.right);
                return this.balance(node.left, node.key, node.value, nr);
            }
        };
        haxe.ds.BalancedTree.prototype.balance = function(l, k, v, r) {
            var hl;
            if (l == null) hl = 0;
            else hl = l._height;
            var hr;
            if (r == null) hr = 0;
            else hr = r._height;
            if (hl > hr + 2) {
                if ((function($this) {
                        var $r;
                        var _this = l.left;
                        $r = _this == null ? 0 : _this._height;
                        return $r;
                    }(this)) >= (function($this) {
                        var $r;
                        var _this1 = l.right;
                        $r = _this1 == null ? 0 : _this1._height;
                        return $r;
                    }(this))) return new haxe.ds.TreeNode(l.left, l.key, l.value, new haxe.ds.TreeNode(l.right, k, v, r));
                else return new haxe.ds.TreeNode(new haxe.ds.TreeNode(l.left, l.key, l.value, l.right.left), l.right.key, l.right.value, new haxe.ds.TreeNode(l.right.right, k, v, r));
            } else if (hr > hl + 2) {
                if ((function($this) {
                        var $r;
                        var _this2 = r.right;
                        $r = _this2 == null ? 0 : _this2._height;
                        return $r;
                    }(this)) > (function($this) {
                        var $r;
                        var _this3 = r.left;
                        $r = _this3 == null ? 0 : _this3._height;
                        return $r;
                    }(this))) return new haxe.ds.TreeNode(new haxe.ds.TreeNode(l, k, v, r.left), r.key, r.value, r.right);
                else return new haxe.ds.TreeNode(new haxe.ds.TreeNode(l, k, v, r.left.left), r.left.key, r.left.value, new haxe.ds.TreeNode(r.left.right, r.key, r.value, r.right));
            } else return new haxe.ds.TreeNode(l, k, v, r, (hl > hr ? hl : hr) + 1);
        };
        haxe.ds.BalancedTree.prototype.compare = function(k1, k2) {
            return _hcmn_.Reflect.compare(k1, k2);
        };
        haxe.ds.BalancedTree.prototype.__class__ = haxe.ds.BalancedTree;
        haxe.ds.TreeNode = function(l, k, v, r, h) {
            if (h == null) h = -1;
            this.left = l;
            this.key = k;
            this.value = v;
            this.right = r;
            if (h == -1) this._height = ((function($this) {
                var $r;
                var _this = $this.left;
                $r = _this == null ? 0 : _this._height;
                return $r;
            }(this)) > (function($this) {
                var $r;
                var _this1 = $this.right;
                $r = _this1 == null ? 0 : _this1._height;
                return $r;
            }(this)) ? (function($this) {
                var $r;
                var _this2 = $this.left;
                $r = _this2 == null ? 0 : _this2._height;
                return $r;
            }(this)) : (function($this) {
                var $r;
                var _this3 = $this.right;
                $r = _this3 == null ? 0 : _this3._height;
                return $r;
            }(this))) + 1;
            else this._height = h;
        };
        haxe.ds.TreeNode.__name__ = ["haxe", "ds", "TreeNode"];
        haxe.ds.TreeNode.prototype.left = null;
        haxe.ds.TreeNode.prototype.right = null;
        haxe.ds.TreeNode.prototype.key = null;
        haxe.ds.TreeNode.prototype.value = null;
        haxe.ds.TreeNode.prototype._height = null;
        haxe.ds.TreeNode.prototype.__class__ = haxe.ds.TreeNode;
        haxe.ds.EnumValueMap = function() {
            haxe.ds.BalancedTree.call(this);
        };
        haxe.ds.EnumValueMap.__interfaces__ = [haxe.IMap];
        haxe.ds.EnumValueMap.__name__ = ["haxe", "ds", "EnumValueMap"];
        haxe.ds.EnumValueMap.__super__ = haxe.ds.BalancedTree;
        for (var k in haxe.ds.BalancedTree.prototype) haxe.ds.EnumValueMap.prototype[k] = haxe.ds.BalancedTree.prototype[k];
        haxe.ds.EnumValueMap.prototype.compare = function(k1, k2) {
            var d = k1[1] - k2[1];
            if (d != 0) return d;
            var p1 = k1.slice(2);
            var p2 = k2.slice(2);
            if (p1.length == 0 && p2.length == 0) return 0;
            return this.compareArgs(p1, p2);
        };
        haxe.ds.EnumValueMap.prototype.compareArgs = function(a1, a2) {
            var ld = a1.length - a2.length;
            if (ld != 0) return ld;
            var _g1 = 0;
            var _g = a1.length;
            while (_g1 < _g) {
                var i = _g1++;
                var d = this.compareArg(a1[i], a2[i]);
                if (d != 0) return d;
            }
            return 0;
        };
        haxe.ds.EnumValueMap.prototype.compareArg = function(v1, v2) {
            if (_hcmn_.Reflect.isEnumValue(v1) && _hcmn_.Reflect.isEnumValue(v2)) return this.compare(v1, v2);
            else if ((v1 instanceof Array) && v1.__enum__ == null && ((v2 instanceof Array) && v2.__enum__ == null)) return this.compareArgs(v1, v2);
            else return _hcmn_.Reflect.compare(v1, v2);
        };
        haxe.ds.EnumValueMap.prototype.__class__ = haxe.ds.EnumValueMap;
        if (typeof js == 'undefined') {
            var js = {};
        };
        if (!js._Boot) {
            js._Boot = {};
        };
        js._Boot.HaxeError = function(val) {
            Error.call(this);
            this.val = val;
            this.message = String(val);
            if (Error.captureStackTrace) Error.captureStackTrace(this, js._Boot.HaxeError);
        };
        js._Boot.HaxeError.__name__ = ["js", "_Boot", "HaxeError"];
        js._Boot.HaxeError.__super__ = Error;
        for (var k in Error.prototype) js._Boot.HaxeError.prototype[k] = Error.prototype[k];
        js._Boot.HaxeError.prototype.val = null;
        js._Boot.HaxeError.prototype.__class__ = js._Boot.HaxeError;
        if (typeof umlStateMachine == 'undefined') {
            var umlStateMachine = {};
        };
        umlStateMachine.Activator = function() {};
        umlStateMachine.Activator = ck_implements(umlStateMachine.Activator, clientkernelModulesApi.IModuleActivator);
        umlStateMachine.Activator.__interfaces__ = [clientkernelModulesApi.IModuleActivator];
        umlStateMachine.Activator.__name__ = ["umlStateMachine", "Activator"];
        umlStateMachine.Activator.prototype.start = function(context) {
            context.registerService(new umlStateMachine.StateMachineProvider(), umlStateMachineApi.IStateMachineProvider, null);
        };
        umlStateMachine.Activator.prototype.stop = function(context) {};
        umlStateMachine.Activator.main = function() {};
        umlStateMachine.Activator.prototype.__class__ = umlStateMachine.Activator;
        umlStateMachine.Log = function() {};
        umlStateMachine.Log.__name__ = ["umlStateMachine", "Log"];
        umlStateMachine.Log.logger = null;
        umlStateMachine.Log.useLogger = function(eLogger) {
            umlStateMachine.Log.logger = eLogger;
        };
        umlStateMachine.Log.debug = function(message) {
            if (umlStateMachine.Log.logger != null) umlStateMachine.Log.logger.debug(message);
        };
        umlStateMachine.Log.info = function(message) {
            if (umlStateMachine.Log.logger != null) umlStateMachine.Log.logger.info(message);
        };
        umlStateMachine.Log.debugHandler = function(message, handler) {
            if (umlStateMachine.Log.logger != null) {
                if (handler != null) umlStateMachine.Log.logger.debug(message + _hcmn_.Std.string(_hcmn_.Type["typeof"](handler)) + " " + _hcmn_.Std.string(handler));
                else umlStateMachine.Log.logger.debug(message);
            }
        };
        umlStateMachine.Log.debugTrigger = function(message, payload) {
            if (umlStateMachine.Log.logger != null) {
                var payloadClassName = "";
                if (payload != null) {
                    if (_hcmn_.Type.getClass(payload) != null) try {
                        payloadClassName = _hcmn_.Type.getClassName(_hcmn_.Type.getClass(payload));
                    } catch (e) {
                        if (e instanceof js._Boot.HaxeError) e = e.val;
                        payloadClassName = "";
                    }
                }
                if (payloadClassName != "") umlStateMachine.Log.debug(message + " payload:" + payloadClassName);
                else umlStateMachine.Log.debug(message);
            }
        };
        umlStateMachine.Log.trace = function(message) {
            if (umlStateMachine.Log.logger != null) umlStateMachine.Log.logger.trace(message);
        };
        umlStateMachine.Log.error = function(message) {
            if (umlStateMachine.Log.logger != null) umlStateMachine.Log.logger.error(message);
        };
        umlStateMachine.Log.warn = function(message) {
            if (umlStateMachine.Log.logger != null) umlStateMachine.Log.logger.warn(message);
        };
        umlStateMachine.Log.prototype.__class__ = umlStateMachine.Log;
        umlStateMachine.State = function(id, type) {
            this.id = id;
            this.type = type;
            this.logRoot = "[State:" + _hcmn_.Std.string(id) + "] ";
            this.onEnterHandlers = [];
            this.onRunHandlers = [];
            this.onExitHandlers = [];
        };
        umlStateMachine.State = ck_implements(umlStateMachine.State, umlStateMachineApi.IState);
        umlStateMachine.State.__interfaces__ = [umlStateMachineApi.IState];
        umlStateMachine.State.__name__ = ["umlStateMachine", "State"];
        umlStateMachine.State.prototype.logRoot = null;
        umlStateMachine.State.prototype.id = null;
        umlStateMachine.State.prototype.type = null;
        umlStateMachine.State.prototype.onEnterHandlers = null;
        umlStateMachine.State.prototype.onRunHandlers = null;
        umlStateMachine.State.prototype.onExitHandlers = null;
        umlStateMachine.State.prototype.onEnter = function(handler) {
            this.onEnterHandlers.push(handler);
            return this;
        };
        umlStateMachine.State.prototype.onRun = function(handler) {
            this.onRunHandlers.push(handler);
            return this;
        };
        umlStateMachine.State.prototype.onExit = function(handler) {
            this.onExitHandlers.push(handler);
            return this;
        };
        umlStateMachine.State.prototype["final"] = function() {
            this.type = umlStateMachineApi.StateType.FINAL;
            return this;
        };
        umlStateMachine.State.prototype.finalDeaf = function() {
            this.type = umlStateMachineApi.StateType.FINAL_DEAF;
            return this;
        };
        umlStateMachine.State.prototype.getId = function() {
            return this.id;
        };
        umlStateMachine.State.prototype.getType = function() {
            return this.type;
        };
        umlStateMachine.State.prototype.doEnter = function() {
            var handler;
            var _g = 0;
            var _g1 = this.onEnterHandlers;
            while (_g < _g1.length) {
                var handler1 = _g1[_g];
                ++_g;
                umlStateMachine.Log.debugHandler(this.logRoot + "doEnter : ", handler1);
                handler1();
            }
        };
        umlStateMachine.State.prototype.doRun = function() {
            var handler;
            var _g = 0;
            var _g1 = this.onRunHandlers;
            while (_g < _g1.length) {
                var handler1 = _g1[_g];
                ++_g;
                umlStateMachine.Log.debugHandler(this.logRoot + "doRun : ", handler1);
                handler1();
            }
        };
        umlStateMachine.State.prototype.doExit = function() {
            var handler;
            var _g = 0;
            var _g1 = this.onExitHandlers;
            while (_g < _g1.length) {
                var handler1 = _g1[_g];
                ++_g;
                umlStateMachine.Log.debugHandler(this.logRoot + "doExit : ", handler1);
                handler1();
            }
        };
        umlStateMachine.State.prototype.equals = function(state) {
            if (this == state) return true;
            if (state == null) return false;
            if (_hcmn_.Std.string(state.getId()) == _hcmn_.Std.string(this.getId())) return true;
            return false;
        };
        umlStateMachine.State.prototype.__class__ = umlStateMachine.State;
        umlStateMachine.StateMachine = function(initialState, logger) {
            umlStateMachine.Log.useLogger(logger);
            this.states = new haxe.ds.EnumValueMap();
            this.transitions = new _hcmn_.List();
            this.currentState = this.addStateImpl(initialState, umlStateMachineApi.StateType.INITIAL);
        };
        umlStateMachine.StateMachine = ck_implements(umlStateMachine.StateMachine, umlStateMachineApi.IStateMachine);
        umlStateMachine.StateMachine.__interfaces__ = [umlStateMachineApi.IStateMachine];
        umlStateMachine.StateMachine.__name__ = ["umlStateMachine", "StateMachine"];
        umlStateMachine.StateMachine.prototype.states = null;
        umlStateMachine.StateMachine.prototype.transitions = null;
        umlStateMachine.StateMachine.prototype.currentState = null;
        umlStateMachine.StateMachine.prototype.useLogger = function(logger) {
            umlStateMachine.Log.useLogger(logger);
        };
        umlStateMachine.StateMachine.prototype.addState = function(state) {
            return this.addStateImpl(state, umlStateMachineApi.StateType.NORMAL);
        };
        umlStateMachine.StateMachine.prototype.addTransition = function(sourceState, targetState, trigger) {
            if (!this.states.exists(sourceState)) throw new js._Boot.HaxeError(new umlStateMachineApi.StateMachineException(null, sourceState, umlStateMachineApi.StateMachineExceptionType.NON_EXISTING_STATE));
            if (!this.states.exists(targetState)) throw new js._Boot.HaxeError(new umlStateMachineApi.StateMachineException(null, targetState, umlStateMachineApi.StateMachineExceptionType.NON_EXISTING_STATE));
            var transition = new umlStateMachine.Transition(sourceState, targetState, trigger, false);
            this.transitions.add(transition);
            return transition;
        };
        umlStateMachine.StateMachine.prototype.addStateInternalTransition = function(state, trigger) {
            if (!this.states.exists(state)) throw new js._Boot.HaxeError(new umlStateMachineApi.StateMachineException(null, state, umlStateMachineApi.StateMachineExceptionType.NON_EXISTING_STATE));
            var transition = new umlStateMachine.Transition(state, state, trigger, true);
            this.transitions.add(transition);
            return transition;
        };
        umlStateMachine.StateMachine.prototype.trigger = function(trigger, payload) {
            var _g = this;
            _hcmn_.haxe_Timer.delay(function() {
                _g.internalTrigger(trigger, payload);
            }, 0);
        };
        umlStateMachine.StateMachine.prototype.internalTrigger = function(trigger, payload) {
            var logRoot = "[Trigger:" + _hcmn_.Std.string(trigger) + "] ";
            umlStateMachine.Log.debugTrigger(logRoot, payload);
            if (this.currentState.getType() == umlStateMachineApi.StateType.FINAL) {
                var exception = new umlStateMachineApi.StateMachineException(trigger, this.currentState.getId(), umlStateMachineApi.StateMachineExceptionType.STATE_IS_FINAL);
                umlStateMachine.Log.error(logRoot + exception.getMessage());
                throw new js._Boot.HaxeError(exception);
            }
            if (this.currentState.getType() == umlStateMachineApi.StateType.FINAL_DEAF) {
                umlStateMachine.Log.debug(logRoot + " Curren State:" + _hcmn_.Std.string(this.currentState.getId()) + "is final_def state. Returning.");
                return;
            }
            if (this.transitions == null) {
                var exception1 = new umlStateMachineApi.StateMachineException(trigger, this.currentState.getId(), umlStateMachineApi.StateMachineExceptionType.NO_VALID_TRANSITION);
                umlStateMachine.Log.error(logRoot + exception1.getMessage());
                throw new js._Boot.HaxeError(exception1);
            }
            var transition = this.findTransition(trigger, payload);
            if (transition == null) {
                var exception2 = new umlStateMachineApi.StateMachineException(trigger, this.currentState.getId(), umlStateMachineApi.StateMachineExceptionType.NO_VALID_TRANSITION);
                umlStateMachine.Log.error(logRoot + exception2.getMessage());
                throw new js._Boot.HaxeError(exception2);
            }
            this.executeTransition(transition, payload);
        };
        umlStateMachine.StateMachine.prototype.addStateImpl = function(state, type) {
            var stateObject = new umlStateMachine.State(state, type);
            this.states.set(state, stateObject);
            return stateObject;
        };
        umlStateMachine.StateMachine.prototype.getState = function(state) {
            if (this.states.exists(state)) return this.states.get(state);
            return null;
        };
        umlStateMachine.StateMachine.prototype.findTransition = function(trigger, payload) {
            var transition = null;
            var iTransition;
            var _g_head = this.transitions.h;
            var _g_val = null;
            while (_g_head != null) {
                var iTransition1;
                iTransition1 = (function($this) {
                    var $r;
                    _g_val = _g_head[0];
                    _g_head = _g_head[1];
                    $r = _g_val;
                    return $r;
                }(this));
                if (this.currentState.equals(this.getState(iTransition1.getSourceState())) && _hcmn_.Std.string(trigger) == _hcmn_.Std.string(iTransition1.getTrigger()) && iTransition1.doTest(payload)) {
                    transition = iTransition1;
                    break;
                }
            }
            return transition;
        };
        umlStateMachine.StateMachine.prototype.executeTransition = function(transition, payload) {
            umlStateMachine.Log.debug(transition.getLogRoot() + " executing...");
            var isInternal = transition.getIsInternal();
            if (!isInternal) this.currentState.doExit();
            transition.doAction(payload);
            this.currentState = this.getState(transition.getTargetState());
            if (!isInternal) this.currentState.doEnter();
            this.currentState.doRun();
        };
        umlStateMachine.StateMachine.prototype.__class__ = umlStateMachine.StateMachine;
        umlStateMachine.StateMachineProvider = function() {};
        umlStateMachine.StateMachineProvider = ck_implements(umlStateMachine.StateMachineProvider, clientkernelModulesApi.IService);
        umlStateMachine.StateMachineProvider = ck_implements(umlStateMachine.StateMachineProvider, umlStateMachineApi.IStateMachineProvider);
        umlStateMachine.StateMachineProvider.__interfaces__ = [clientkernelModulesApi.IService, umlStateMachineApi.IStateMachineProvider];
        umlStateMachine.StateMachineProvider.__name__ = ["umlStateMachine", "StateMachineProvider"];
        umlStateMachine.StateMachineProvider.prototype.getStateMachine = function(initState, logger) {
            return this.getStateMachineUntyped(initState, logger);
        };
        umlStateMachine.StateMachineProvider.prototype.getStateMachineUntyped = function(initState, logger) {
            return new umlStateMachine.StateMachine(initState, logger);
        };
        umlStateMachine.StateMachineProvider.prototype.__class__ = umlStateMachine.StateMachineProvider;
        umlStateMachine.Transition = function(sourceState, targetState, trigger, isInternal) {
            this.isInternal = false;
            this.sourceState = sourceState;
            this.targetState = targetState;
            this.trigger = trigger;
            this.isInternal = isInternal;
            this.logRoot = "[Transition: " + _hcmn_.Std.string(sourceState) + " ---(" + _hcmn_.Std.string(trigger) + ")---> " + _hcmn_.Std.string(targetState) + "] ";
            this.actionHandlers = [];
        };
        umlStateMachine.Transition = ck_implements(umlStateMachine.Transition, umlStateMachineApi.ITransition);
        umlStateMachine.Transition.__interfaces__ = [umlStateMachineApi.ITransition];
        umlStateMachine.Transition.__name__ = ["umlStateMachine", "Transition"];
        umlStateMachine.Transition.prototype.logRoot = null;
        umlStateMachine.Transition.prototype.sourceState = null;
        umlStateMachine.Transition.prototype.targetState = null;
        umlStateMachine.Transition.prototype.trigger = null;
        umlStateMachine.Transition.prototype.guardConditionHandler = null;
        umlStateMachine.Transition.prototype.actionHandlers = null;
        umlStateMachine.Transition.prototype.isInternal = null;
        umlStateMachine.Transition.prototype.guardCondition = function(handler) {
            this.guardConditionHandler = handler;
            return this;
        };
        umlStateMachine.Transition.prototype.action = function(handler) {
            this.actionHandlers.push(handler);
            return this;
        };
        umlStateMachine.Transition.prototype.getLogRoot = function() {
            return this.logRoot;
        };
        umlStateMachine.Transition.prototype.getIsInternal = function() {
            return this.isInternal;
        };
        umlStateMachine.Transition.prototype.getSourceState = function() {
            return this.sourceState;
        };
        umlStateMachine.Transition.prototype.getTargetState = function() {
            return this.targetState;
        };
        umlStateMachine.Transition.prototype.getTrigger = function() {
            return this.trigger;
        };
        umlStateMachine.Transition.prototype.doTest = function(payload) {
            if (this.guardConditionHandler == null) return true;
            var testResult = this.guardConditionHandler(payload);
            umlStateMachine.Log.debugHandler(this.logRoot + "doTest = " + (testResult == null ? "null" : "" + testResult) + " : ", this.guardConditionHandler);
            return testResult;
        };
        umlStateMachine.Transition.prototype.doAction = function(payload) {
            var handler;
            var _g = 0;
            var _g1 = this.actionHandlers;
            while (_g < _g1.length) {
                var handler1 = _g1[_g];
                ++_g;
                umlStateMachine.Log.debugHandler(this.logRoot + "doAction : ", handler1);
                handler1(payload);
            }
        };
        umlStateMachine.Transition.prototype.__class__ = umlStateMachine.Transition;
        return {
            exports: umlStateMachine,
            activator: umlStateMachine.Activator
        };
    });
//# sourceURL=umlStateMachine.js