// Autogenerated with DRAKON Editor 1.21
using System;
using System.Collections.Generic;

namespace Automatontest {

class Foo {

	private int _acc = 0;
	private readonly List<int> _stack = new List<int>();

	public int Acc { get { return _acc; } }

    public interface IFoo_State
    {
        string Name { get; }
        void Big(Foo obj, int value);
        void Medium(Foo obj, int value);
        void Small(Foo obj, int value);
    }
    private IFoo_State _state = Yellow_State;
    public IFoo_State State { get { return _state; } }
    private class Yellow_State_Definition : IFoo_State {
        public string Name { get { return "Yellow"; } }
        public void Big(Foo obj, int value) {
            obj.Yellow_Big(value);
        }
        public void Medium(Foo obj, int value) {
            obj.Yellow_Medium(value);
        }
        public void Small(Foo obj, int value) {
            obj.Yellow_Small(value);
        }
    }
    public static readonly IFoo_State Yellow_State = new Yellow_State_Definition();
    private class Grey_State_Definition : IFoo_State {
        public string Name { get { return "Grey"; } }
        public void Big(Foo obj, int value) {
            obj.Grey_Big(value);
        }
        public void Medium(Foo obj, int value) {
            obj.Grey_Medium(value);
        }
        public void Small(Foo obj, int value) {
            obj.Grey_Small(value);
        }
    }
    public static readonly IFoo_State Grey_State = new Grey_State_Definition();
    private class Red_State_Definition : IFoo_State {
        public string Name { get { return "Red"; } }
        public void Big(Foo obj, int value) {
            obj.Red_Big(value);
        }
        public void Medium(Foo obj, int value) {
            obj.Red_Medium(value);
        }
        public void Small(Foo obj, int value) {
            obj.Red_Small(value);
        }
    }
    public static readonly IFoo_State Red_State = new Red_State_Definition();
    private class Finished_State_Definition : IFoo_State {
        public string Name { get { return "Finished"; } }
        public void Big(Foo obj, int value) {
            throw new System.InvalidOperationException("The 'Foo' object is in the finished state.");
        }
        public void Medium(Foo obj, int value) {
            throw new System.InvalidOperationException("The 'Foo' object is in the finished state.");
        }
        public void Small(Foo obj, int value) {
            throw new System.InvalidOperationException("The 'Foo' object is in the finished state.");
        }
    }
    public static readonly IFoo_State Finished_State = new Finished_State_Definition();
    private class Intermediate_State_Definition : IFoo_State {
        public string Name { get { return "Intermediate"; } }
        public void Big(Foo obj, int value) {
            throw new System.InvalidOperationException("The 'Foo' object is in the intermediate state.");
        }
        public void Medium(Foo obj, int value) {
            throw new System.InvalidOperationException("The 'Foo' object is in the intermediate state.");
        }
        public void Small(Foo obj, int value) {
            throw new System.InvalidOperationException("The 'Foo' object is in the intermediate state.");
        }
    }
    public static readonly IFoo_State Intermediate_State = new Intermediate_State_Definition();
    public void Big(int value) {
        IFoo_State current = _state;
        _state = Intermediate_State;
        current.Big(this, value);
    }
    public void Medium(int value) {
        IFoo_State current = _state;
        _state = Intermediate_State;
        current.Medium(this, value);
    }
    public void Small(int value) {
        IFoo_State current = _state;
        _state = Intermediate_State;
        current.Small(this, value);
    }
    private void Grey_Small(int value)
    {
        Grey_default(value);
    }
    private void Red_Small(int value)
    {
        throw new System.InvalidOperationException("Foo: Method 'Small' is not expected in state 'Red'.");
    }

    public static void Main() {
        // item 175
        Foo obj = new Foo();
        // item 176
        Assert(obj.State.Name == "Yellow");
        Assert(obj.Acc == 0);
        // item 281
        obj.Big(10);
        // item 282
        Assert(obj.State.Name == "Yellow");
        Assert(obj.Acc == 0);
        // item 177
        obj.Small(10);
        // item 280
        Assert(obj.State.Name == "Red");
        Assert(obj.Acc == 40);
        // item 283
        obj.Medium(1000);
        // item 284
        Assert(obj.State.Name == "Grey");
        Assert(obj.Acc == 39);
        // item 285
        obj.Big(15);
        // item 286
        Assert(obj.State.Name == "Yellow");
        Assert(obj.Acc == 189);
        // item 287
        obj.Medium(11);
        // item 288
        Assert(obj.State.Name == "Grey");
        Assert(obj.Acc == 250);
        // item 159
        Console.WriteLine("End of the automaton test!");
    }

    private void Add(int value) {
        // item 183
        _acc += value;
        _stack.Add(value);
    }

    private static void Assert(bool condition) {
        // item 201
        if (condition) {
            
        } else {
            // item 204
            throw new System.Exception("Assertion failed.");
        }
    }

    private void Grey_Big(int value) {
        // item 2660001
        if (value == 5) {
            // item 274
            Add(500);
        } else {
            // item 2660002
            if (value == 15) {
                // item 276
                Add(150);
            } else {
                // item 275
                Add(value);
            }
        }
        // item 218
        _state = Yellow_State;
    }

    private void Grey_Medium(int value) {
        // item 243
        Subtract(value * 3);
        // item 233
        _state = Finished_State;
    }

    private void Grey_default(int value) {
        // item 277
        Subtract(value * 2);
        // item 234
        _state = Red_State;
    }

    private void Red_Big(int value) {
        // item 278
        Add(1);
        // item 221
        _state = Yellow_State;
    }

    private void Red_Medium(int value) {
        // item 279
        Subtract(1);
        // item 244
        _state = Grey_State;
    }

    private void Subtract(int value) {
        // item 189
        _acc -= value;
    }

    private void Yellow_Big(int value) {
        // item 212
        _state = Yellow_State;
    }

    private void Yellow_Medium(int value) {
        IEnumerator<int> _it255 = null;
        int item = default(int);
        // item 229
        Add(value);
        // item 254
        if (_acc > 0) {
            // item 289
            int m = 10;
            // item 2550001
            _it255 = ((IEnumerable<int>)_stack).GetEnumerator();
            while (true) {
                // item 2550002
                if (_it255.MoveNext()) {
                    
                } else {
                    break;
                }
                // item 2550004
                item = _it255.Current;
                // item 257
                if (item % 3 == 0) {
                    // item 261
                    m += 20;
                    break;
                } else {
                    
                }
                // item 260
                m += 5;
            }
            // item 290
            Add(m);
            // item 231
            _state = Grey_State;
        } else {
            // item 262
            int i = 3;
            while (true) {
                // item 250
                if (value > 10) {
                    
                } else {
                    // item 253
                    Add(value);
                }
                // item 265
                i--;
                // item 263
                if (i >= 0) {
                    
                } else {
                    break;
                }
            }
            // item 232
            _state = Red_State;
        }
    }

    private void Yellow_Small(int value) {
        // item 230
        Multiply(value);
        // item 262
        int i = 3;
        while (true) {
            // item 250
            if (value > 10) {
                
            } else {
                // item 253
                Add(value);
            }
            // item 265
            i--;
            // item 263
            if (i >= 0) {
                
            } else {
                break;
            }
        }
        // item 232
        _state = Red_State;
    }

    void Multiply(int value) {
        // item 195
        _acc *= value;
    }
}
}
