using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Dvb.DataBroadcasting.Biop;
using skyscraper5.Skyscraper;
using skyscraper5.Skyscraper.Gps;
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;

namespace skyscraper5.src.Skyscraper.FrequencyListGenerator
{
	public class DbBlindscanJob
	{
		public DbBlindscanJob(Guid jobGuid, PhysicalAddress tunerMac, STD_TYPE tunerStandard, int diseqCIndex,
			IGpsReceiver jobContextGps, double satellitePosition)
		{
			this.JobGuid = jobGuid;
			this.TunerMAC = tunerMac;
			this.TunerStandard = tunerStandard;
			this.DiseqCIndex = diseqCIndex;
			this.HorizontalHighState = DbBlindscanJobPolarizationStatus.NOT_SELECTED;
			this.HorizontalLowState = DbBlindscanJobPolarizationStatus.NOT_SELECTED;
			this.VerticalHighState = DbBlindscanJobPolarizationStatus.NOT_SELECTED;
			this.VerticalLowState = DbBlindscanJobPolarizationStatus.NOT_SELECTED;
			if (jobContextGps != null)
			{
				if (jobContextGps.HasLock)
				{
					this.GpsCoordinate = jobContextGps.Coordinate.Clone();
				}
			}

			this.SatPosition = satellitePosition;
		}


		public double SatPosition { get; private set; }

		public GpsCoordinate? GpsCoordinate { get; private set; }

		public Guid JobGuid { get; private set; }
		public PhysicalAddress TunerMAC { get; private set; }
		public STD_TYPE TunerStandard { get; private set; }
		public int DiseqCIndex { get; private set; }

		public DbBlindscanJobPolarizationStatus HorizontalLowState;
		public DbBlindscanJobPolarizationStatus HorizontalHighState;
		public DbBlindscanJobPolarizationStatus VerticalLowState;
		public DbBlindscanJobPolarizationStatus VerticalHighState;

		public DateTime DateAdded { get; set; }

		public override string ToString()
		{
			return $"{nameof(SatPosition)}: {SatPosition}, {nameof(JobGuid)}: {JobGuid}";
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="mode">Set to 1 to return just the Position or Tuner standard, Set to 2 to get the scan states.</param>
		/// <returns></returns>
		public string ToString(int mode)
		{
			switch(mode)
			{
				case 1:
					if (SatPosition >= 0.0)
					{
						return String.Format("{0}°E", SatPosition);
					}
					else
					{
						double westerner = SatPosition /= -1;
						return String.Format("{0}°W", westerner);
					}
					return TunerStandard.ToString();
				case 2:
					return String.Format("({0}/{1}/{2}/{3})", (int)HorizontalLowState, (int)HorizontalHighState, (int)VerticalLowState, (int)VerticalHighState);
				default:
					return ToString();
			}
		}

		public string GetFiveLetterOrbitalPosition()
		{
			if (SatPosition >= 0)
			{
				return String.Format("{0:4}E", (int)(SatPosition * 10));
			}
			else
			{
                double westerner = SatPosition /= -1;
                return String.Format("{0:4}W", (int)(westerner * 10));
            }
		}

	}

	public enum DbBlindscanJobPolarizationStatus : int
	{
		SELECTED_WAITING = 0,
		SELECTED_BLINDSCANNING = 1,
		SELECTED_SCRAPING = 2,
		SELECTED_DONE = 100,
		NOT_SELECTED = 101,
		/// <summary>
		/// Die Blindscan Funktion in StreamReader.dll hat einen Fehler gemeldet.
		/// </summary>
		SELECTED_FAILED = 102,
		/// <summary>
		/// Die SendDiseqc Funktion in StreamReader.dll hat einen Fehler gemeldet.
		/// </summary>
		SELECTED_FAILED_DISEQC = 103,
		/// <summary>
		/// Der vorliegende Scan zielt nicht auf einen Satelliten ab.
		/// </summary>
		NOT_SELECTED_NON_S_HINT = 105,
	}
}
