
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace Pages
{
	public partial class InfoPage : UIViewController
	{
		#region Constructors

		// The IntPtr and initWithCoder constructors are required for items that need 
		// to be able to be created from a xib rather than from managed code

		public InfoPage(IntPtr handle) : base(handle)
		{
			Initialize();
		}

		[Export("initWithCoder:")]
		public InfoPage(NSCoder coder) : base(coder)
		{
			Initialize();
		}

		public InfoPage() : base("InfoPage", null)
		{
			Initialize();
		}

		void Initialize()
		{
		}
		
		#endregion
	
		NSTimer UpdateBatteryStatusTimer;
		NSTimer ClearMotionLabelTimer;
		
		private void UpdateUIMetrics()
		{
			var scrn = UIScreen.MainScreen;
			//iPhone 4 doubles pixel count, but point count remains same
			resolutionLabel.Text = string.Format("{0}x{1} points, {2}x{3} pixels",
				scrn.Bounds.Width, scrn.Bounds.Height,
				scrn.Bounds.Width * scrn.Scale, scrn.Bounds.Height * scrn.Scale);
			frameSizeLabel.Text = string.Format("{0}x{1} points", 
				scrn.ApplicationFrame.Width, scrn.ApplicationFrame.Height);
		}
		
		private void ReadBatteryStatus()
		{
			var dev = UIDevice.CurrentDevice;
			dev.BatteryMonitoringEnabled = true;
			if (dev.BatteryMonitoringEnabled)
				try
				{
					batteryLabel.Text = string.Format("{0}% - {1}", Math.Round(dev.BatteryLevel * 100), dev.BatteryState);
				}
				finally
				{
					dev.BatteryMonitoringEnabled = false;
				}
			else
			{
				batteryLabel.Text = "Battery level monitoring not available";
				UpdateBatteryStatusTimer.Invalidate();
			}
		}
		
		public override bool CanBecomeFirstResponder
		{
			get { return true; }
		}
		
		public override void ViewDidAppear(bool animated)
		{
			base.ViewDidAppear(animated);
			deviceLabel.Text = String.Format("{0}, iOS v{1}", DeviceHardware.VersionString, UIDevice.CurrentDevice.SystemVersion);
			UpdateUIMetrics();
			//Status bar
			statusBarSwitch.On = !UIApplication.SharedApplication.StatusBarHidden;
			statusBarSwitch.ValueChanged += HandleStatusBarSwitchValueChanged;
			//Proximity monitor
			UIDevice.CurrentDevice.ProximityMonitoringEnabled = true;
			if (UIDevice.CurrentDevice.ProximityMonitoringEnabled)
				NSNotificationCenter.DefaultCenter.AddObserver(UIDevice.ProximityStateDidChangeNotification,
				(n) => { proximityLabel.Text = 
					UIDevice.CurrentDevice.ProximityState ? "Proximity detected" : "Proximity not detected"; });
			else
			  proximityLabel.Text = "Proximity sensor not available";
			//Battery status monitor
			UpdateBatteryStatusTimer = NSTimer.CreateRepeatingScheduledTimer(
				60, ReadBatteryStatus);
			ReadBatteryStatus();
			//Orientation
			//An alternative way to notice orientation changes, part 1
			//NSNotificationCenter.DefaultCenter.AddObserver(UIDevice.OrientationDidChangeNotification,
			//	OrientationChanged);
			//Shakes
			BecomeFirstResponder();
			UIApplication.SharedApplication.ApplicationSupportsShakeToEdit = true;
			//Multi-touch
			View.MultipleTouchEnabled = true;
		}
		
		public override void ViewDidDisappear(bool animated)
		{
			//Shakes
			ResignFirstResponder();
			//Battery status monitor
			UpdateBatteryStatusTimer.Invalidate();
			//Proximity monitor
			if (UIDevice.CurrentDevice.ProximityMonitoringEnabled)
				UIDevice.CurrentDevice.ProximityMonitoringEnabled = false;
			//Status bar
			statusBarSwitch.On = true;
			HandleStatusBarSwitchValueChanged(statusBarSwitch, new EventArgs());
			base.ViewDidDisappear (animated);
		}

		//An alternative way to notice orientation changes, part 2
		/*
		private void OrientationChanged(NSNotification notification)
		{
			switch (InterfaceOrientation)
			{
				case UIInterfaceOrientation.Portrait:
					interactionLabel.Text = "iPhone is oriented normally";
					break;
				case UIInterfaceOrientation.LandscapeLeft:
					interactionLabel.Text = "iPhone has been rotated right";
					break;
				case UIInterfaceOrientation.PortraitUpsideDown:
					interactionLabel.Text = "iPhone is upside down";
					break;
				case UIInterfaceOrientation.LandscapeRight:
					interactionLabel.Text = "iPhone has been rotated left";
					break;
			}
			SetTimerToClearMotionLabel();
			UpdateUIMetrics();
		}
		*/
		
		void HandleStatusBarSwitchValueChanged(object sender, EventArgs e)
		{
			UIApplication.SharedApplication.StatusBarHidden = !statusBarSwitch.On;
			if ((View != null) && (View.Window != null))
				View.Window.Frame = UIScreen.MainScreen.ApplicationFrame;
			
			//Without this, the nav bar is lazy about moving to the right place
			//Required a public property to be added to the AppDelegate
			var AppDel = (AppDelegate)UIApplication.SharedApplication.Delegate;
			var NavController = AppDel.NavController;
			NavController.SetNavigationBarHidden(true, false);
			NavController.SetNavigationBarHidden(false, false);
			UpdateUIMetrics();
		}
		
		public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)
		{
			return true;
		}
		
		private void SetTimerToClearMotionLabel()
		{
			if (ClearMotionLabelTimer != null)
				ClearMotionLabelTimer.Invalidate();
			ClearMotionLabelTimer = NSTimer.CreateScheduledTimer(3, () =>
			{
				interactionLabel.Text = "None";
				ClearMotionLabelTimer = null;
			});
		}
		
		public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration)
		{
			switch (toInterfaceOrientation)
			{
				case UIInterfaceOrientation.Portrait:
					interactionLabel.Text = "iPhone is oriented normally";
					break;
				case UIInterfaceOrientation.LandscapeLeft:
					interactionLabel.Text = "iPhone has been rotated right";
					break;
				case UIInterfaceOrientation.PortraitUpsideDown:
					interactionLabel.Text = "iPhone is upside down";
					break;
				case UIInterfaceOrientation.LandscapeRight:
					interactionLabel.Text = "iPhone has been rotated left";
					break;
			}
			SetTimerToClearMotionLabel();
			UpdateUIMetrics();
		}
		
		public override void MotionEnded(UIEventSubtype motion, UIEvent evt)
		{
			if (motion == UIEventSubtype.MotionShake)
			{
				interactionLabel.Text = "iPhone was shaken";
				SetTimerToClearMotionLabel();
			}
		}
		
		private string DescribeTouch(UITouch touch)
		{
			string desc;
			switch (touch.TapCount)
			{
				case 0:
					desc = "Swipe";
					break;
				case 1:
					desc = "Single tap";
					break;
				case 2:
					desc = "Double tap";
					break;
				default:
					desc = "Multiple tap";
					break;
			}
			switch (touch.Phase)
			{
				case UITouchPhase.Began:
					desc += " started";
					break;
				case UITouchPhase.Moved:
					desc += " moved";
					break;
				case UITouchPhase.Stationary:
					desc += " hasn't moved";
					break;
				case UITouchPhase.Ended:
					desc += " ended";
					break;
				case UITouchPhase.Cancelled:
					desc += " cancelled";
					break;
			}
			return desc;
		}
		
		private PointF StartCoord;
		
		public override void TouchesBegan(NSSet touches, UIEvent evt)
		{
			var touchArray = touches.ToArray<UITouch>();
			if (touches.Count > 0)
			{
				var coord = touchArray[0].LocationInView(touchArray[0].View);
				if (touchArray[0].TapCount < 2)
					StartCoord = coord;
				interactionLabel.Text = string.Format("{0} ({1},{2})",
					DescribeTouch(touchArray[0]), coord.X, coord.Y);
			}
		}
		
		public override void TouchesMoved(NSSet touches, UIEvent evt)
		{
			var touchArray = touches.ToArray<UITouch>();
			if (touches.Count > 0)
			{
				var coord = touchArray[0].LocationInView(touchArray[0].View);
				interactionLabel.Text = string.Format("{0} ({1},{2})",
					DescribeTouch(touchArray[0]), coord.X, coord.Y);
			}
		}
		
		public override void TouchesEnded(NSSet touches, UIEvent evt)
		{
			var touchArray = touches.ToArray<UITouch>();
			if (touches.Count > 0)
			{
				var coord = touchArray[0].LocationInView(touchArray[0].View);
				interactionLabel.Text = string.Format("{0} ({1},{2})->({3},{4})",
					DescribeTouch(touchArray[0]), StartCoord.X, StartCoord.Y, coord.X, coord.Y);
				SetTimerToClearMotionLabel();
			}
		}
	}
}
