using System;
using Machinations.FromFlash.machinations.model;
using Machinations.GUI;
using Machinations.UserComponents;

namespace Machinations.FromFlash.graph
{
    /// <summary>
    /// class for loading graph nodes, similar to GraphConnection Type
    /// </summary>
    public class GraphSymbol
    {
        public string Name;
		public NodeClass NodeClass;
		
		public GraphSymbol(NodeClass nodeClass, string name)
        {
            NodeClass = nodeClass;
            Name = name;
        }

        public static GraphNode GetNodeFromClass(NodeClass nodeClass)
        {
            switch (nodeClass)
            {
                case NodeClass.Pool:
                    return new Pool();
                case NodeClass.Gate:
                    return new Gate();
                case NodeClass.Source:
                    return new Source();
                case NodeClass.Drain:
                    return new Drain();
                case NodeClass.Converter:
                    return new Converter();
                case NodeClass.Trader:
                    return new Trader();
                case NodeClass.EndCondition:
                    return new EndCondition();
                case NodeClass.Register:
                    return new Register();
                case NodeClass.Delay:
                    return new Delay();
                case NodeClass.ArtificialPlayer:
                    return new ArtificialPlayer();
                case NodeClass.InnerInOut:
                    return new InnerInOut();
                case NodeClass.OuterInOut:
                    return new OuterInOut();

                default:
                    throw new UnsupportedElementException(nodeClass.ToString());
            }
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Converter node)
        {
            return new ConverterView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Trader node)
        {
            return new TraderView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Pool node)
        {
            return new PoolView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Gate node)
        {
            return new GateView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Source node)
        {
            return new SourceView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Drain node)
        {
            return new DrainView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Delay node)
        {
            return new DelayView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(Register node)
        {
            return new RegisterView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(EndCondition node)
        {
            return new EndConditionView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(ArtificialPlayer node)
        {
            return new ArtifitialPlayerView(node);
        }

        public static INodeView<MachinationsNode> GetViewFromClass(MachinationsNode node)
        {
            throw new NotImplementedException();
        }
    }

    public class UnsupportedElementException : Exception
    {
        private string m_nodeClass;
        private string m_reason;
        public UnsupportedElementException(string nodeClass, string reason = null)
        {
            m_nodeClass = nodeClass;
            m_reason = reason;
        }

        public string NodeClass
        {
            get { return m_nodeClass; }
        }

        public string Reason
        {
            get { return m_reason; }
        }
    }
}
