using System;
using System.Collections.Generic;
using System.Threading;
using skyscraper5.Skyscraper.Drawing;
using skyscraper5.Skyscraper.Plugins;
using skyscraper5.Skyscraper.Scraper.Storage;
using skyscraper8.Skyscraper.Scraper.Storage;

namespace skyscraper5.Skyscraper.Gps
{
	public class WhatCanIReceive
	{
		public static void StandaloneProgram()
		{
			PluginManager pluginManager = PluginManager.GetInstance();
			DataStorageFactory dataStorageFactory = StorageConnectionManager.GetInstance().GetDefaultDataStorageFactory();
			DataStorage dataStorage = dataStorageFactory.CreateDataStorage();
			
			WhatCanIReceive instance = new WhatCanIReceive(dataStorage);
			
			int configuredGpsId = GpsManager.GetConfiguredGpsId();
			IGpsReceiverFactory receiverFactory = GpsManager.GetGpsReceiverFactoryById(configuredGpsId);
			GpsManager.AutoconfigureGpsReceiverFactory(receiverFactory);
			IGpsReceiver gpsReceiver = receiverFactory.CreateGpsReceiver();
			gpsReceiver.Start();
			while (!gpsReceiver.HasLock)
				Thread.Sleep(100);
			GpsCoordinate coordinate = gpsReceiver.Coordinate;
			PointF point = new PointF(coordinate.Longitude, coordinate.Latitude);

			IEnumerable<Tuple<SatelliteBeam, SatelliteBeamFootprint>> receptableSatellites = instance.GetReceptableSatellites(point);
			foreach (var (beam, footprint) in receptableSatellites)
			{
				Console.WriteLine("[{2}] {0} with {1}", beam.Name, footprint.Name, beam.Position);
			}
			gpsReceiver.Stop();
		}

		public DataStorage Storage { get; }

		public WhatCanIReceive(DataStorage storage)
		{
			Storage = storage;
		}

		public IEnumerable<Tuple<SatelliteBeam, SatelliteBeamFootprint>> GetReceptableSatellites(PointF positionOnEath)
		{
			IEnumerable<SatelliteBeam> satelliteBeams = Storage.BeamsSelectEnabled();
			foreach (SatelliteBeam satelliteBeam in satelliteBeams)
			{
				if (satelliteBeam.Position > positionOnEath.Y + 80)
					continue;
				if (satelliteBeam.Position < positionOnEath.Y - 80)
					continue;
				List<SatelliteBeamFootprint> footprints = Storage.BeamsSelectFootprints(satelliteBeam.Id, satelliteBeam.ProcessTimestamp);
				footprints.Sort((x, y) => String.Compare(y.Name, x.Name, StringComparison.Ordinal));
				foreach (SatelliteBeamFootprint footprint in footprints)
				{
					if (footprint.Polygon.Wraps(positionOnEath))
					{
						yield return new Tuple<SatelliteBeam, SatelliteBeamFootprint>(satelliteBeam, footprint);
						break;
					}
				}
			}
			yield break;
		}
	}
}
