using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using Machinations.Annotations;
using Machinations.FromFlash.graph;
using Machinations.FromFlash.machinations.model;

namespace Machinations
{
    /// <summary>
    /// Interaction logic for GraphControl.xaml
    /// </summary>
    public partial class GraphControl : INotifyPropertyChanged
    {
        private ToggleButton m_toggledButton;
        public event PropertyChangedEventHandler PropertyChanged;
        public Action ButtonPressed;
        public Action SelectAllPressed;

        private readonly Dictionary<Key, ToggleButton> m_funcDic;

        public GraphControl()
        {
            InitializeComponent();
            m_funcDic = new Dictionary<Key, ToggleButton>
            {
                {Key.F1, SelectButton},
                {Key.F2, PoolButton},
                {Key.F3, GateButton},
                {Key.F4, ResourceConnectionButton},
                {Key.F5, StateConnectionButton},
                {Key.F6, SourceButton},
                {Key.F7, DrainButton},
                {Key.F8, ConverterButton},
                {Key.F9, TraderButton},
                {Key.F10, SelectButton},
                {Key.F11, SelectButton},
                {Key.F12, SelectButton}
            };
        }

        public ToggleButton ToggledButton
        {
            get { return m_toggledButton; }
        }

        private void GraphButtonsClick(object sender, RoutedEventArgs e)
        {
            GraphButtonChange(sender as ToggleButton);
        }

        public void GraphButtonChoose(ToggleButton tb)
        {
            tb.IsChecked = true;
            GraphButtonChange(tb);
        }

        public void GraphButtonUncheck()
        {
            if (m_toggledButton != null)
            {
                m_toggledButton.IsChecked = false;
                OnPropertyChanged(m_toggledButton.Name);
                m_toggledButton = null;
            }
        }

        private void GraphButtonChange(ToggleButton tb)
        {
            if (tb == null || tb == m_toggledButton) return;
            //OnPropertyChanged(tb.Name);
            if ((bool)tb.IsChecked)
            {
                GraphButtonUncheck();
                m_toggledButton = tb;
                ButtonPressed.Invoke();
            }
            else
            {
                m_toggledButton = null;
            }
        }

        public bool SelectedTbIsSelect()
        {
            return m_toggledButton.Name == "SelectButton";
        }


        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public GraphElement CreateElement()
        {
            var nodeClass = m_toggledButton.Tag as NodeClass? ?? NodeClass.None;
            if (nodeClass != NodeClass.None)
            {
                GraphNode node = GraphSymbol.GetNodeFromClass(nodeClass);
                return node;
            }
            var connectionClass = m_toggledButton.Tag as ConnectionClass? ?? ConnectionClass.None;
            if (connectionClass != ConnectionClass.None)
            {
                MachinationsConnection connection = GraphConnectionType.GetConnectionFromClass(connectionClass);
                return connection;
            }

            return null;
        }

        public void SetButton(Key key)
        {
            GraphButtonChoose(m_funcDic[key]);
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            SelectAllPressed?.Invoke();
        }
    }
}
