using Microscopic_Traffic_Simulator.ViewModels.Messages;
using Microscopic_Traffic_Simulator___Model.CellularTopologyObjects.GeneralParameters;
using Microscopic_Traffic_Simulator___Model.GeometricObjects;

namespace Microscopic_Traffic_Simulator.ViewModels
{
    /// <summary>
    /// Building modes.
    /// </summary>
    internal enum BuildingMode { None, Lane, Generator }

    /// <summary>
    /// Lane types.
    /// </summary>
    internal enum LaneType { Straight, Bezier }

    /// <summary>
    /// Generator types.
    /// </summary>
    internal enum GeneratorType { Generator, Sensor }

    /// <summary>
    /// Viewmodel for construction panel.
    /// </summary>
    class ConstructionViewModel : ViewModelBase
    {
        /// <summary>
        /// Message for sending geometric topology to other viewmodels after creating or opening
        /// geomtric topology.
        /// </summary>
        internal class GeometricTopologyMessage : ParameterizedMessage<GeometricTopology> { }

        /// <summary>
        /// Message for sending information about modification of geometric topology.
        /// </summary>
        internal class GeometricTopologyModifiedMessage : Message { }

        /// <summary>
        /// Message for sending geometric topology simulation control viewmodel to build cellular
        /// topology from it.
        /// </summary>
        internal class BuildCellularTopologyMessage : ParameterizedMessage<GeometricTopology, Parameters> { }

        /// <summary>
        /// Contains information about change of lane type and actual current lane type.
        /// </summary>
        internal class LaneTypeChangedMessage : ParameterizedMessage<LaneType> { }

        /// <summary>
        /// Message about change of the <see cref="CurrentBuildingMode"/> containing new value as parameter
        /// </summary>
        internal class IsConstructionModeChangedMessage : ParameterizedMessage<BuildingMode> { }

        /// <summary>
        /// Current geometric topology.
        /// </summary>
        private GeometricTopology geometricTopology;
        /// <summary>
        /// Current geometric topology.
        /// </summary>        
        internal GeometricTopology GeometricTopology { get { return geometricTopology; } }

        /// <summary>
        /// Current building mode.
        /// </summary>
        private BuildingMode currentBuildingMode = BuildingMode.None;
        /// <summary>
        /// Current building mode.
        /// </summary>
        public BuildingMode CurrentBuildingMode
        {
            get { return currentBuildingMode; }
            set
            {
                currentBuildingMode = value;
                messenger.GetEvent<IsConstructionModeChangedMessage>().Publish(value);
                OnPropertyChanged("CurrentBuildingMode");                
            }
        }

        /// <summary>
        /// Currently selected lane type.
        /// </summary>
        private LaneType currentLaneType = LaneType.Straight;
        /// <summary>
        /// Currently selected lane type.
        /// </summary>
        public LaneType CurrentLaneType
        {
            get { return currentLaneType; }
            set
            {
                currentLaneType = value;
                OnPropertyChanged("CurrentLaneType");
                messenger.GetEvent<LaneTypeChangedMessage>().Publish(value);
            }
        }

        /// <summary>
        /// Currently selected generator type.
        /// </summary>
        private GeneratorType currentGeneratorType = GeneratorType.Generator;
        /// <summary>
        /// Currently selected generator type.
        /// </summary>
        public GeneratorType CurrentGeneratorType
        {
            get { return currentGeneratorType; }
            set
            {
                currentGeneratorType = value;
                OnPropertyChanged("CurrentGeneratorType");                
            }
        }

        /// <summary>
        /// Creates construction viewmodel.
        /// </summary>
        /// <param name="messenger">Messenger to communication with other viewmodels.</param>
        /// <param name="settings">Reference to settings.</param>
        internal ConstructionViewModel(Messenger messenger)
        {
            this.messenger = messenger;
            messenger.GetEvent<ParametersViewModel.ParametersMessage>().Subscribe(i =>
                messenger.GetEvent<BuildCellularTopologyMessage>().Publish(geometricTopology, i));
        }

        /// <summary>
        /// Creates new geometric topology and publishes it to other viewmodels.
        /// </summary>
        internal void CreateNewGeometricTopology()
        {
            geometricTopology = new GeometricTopology();
            messenger.GetEvent<GeometricTopologyMessage>().Publish(geometricTopology);
        }

        /// <summary>
        /// Opens the geometric topology and publishes it to other viewmodels.
        /// </summary>
        /// <param name="path">Path to file with geometric topology.</param>
        internal void OpenGeometricTopology(string path)
        {
            geometricTopology = GeometricTopology.Deserialize(path);
            messenger.GetEvent<GeometricTopologyMessage>().Publish(geometricTopology);
        }

        /// <summary>
        /// Saves the geometric topology.
        /// </summary>
        /// <param name="path">Path to file the geometric topology to be saved.</param>
        internal void SaveGeometricTopology(string path)
        {
            geometricTopology.Serialize(path);
        }
    }
}
