using System;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Text;

//Pretty much a copy of GetData...
namespace PedometerU.Tests
{

	public class GetGoals : MonoBehaviour
	{
		// For HTTP requests to the server.
		private MochaParser mp;

		// Goals Progress Bar
		public Image pbbg;
		public Image pbf;

		// My Goal Progress Bar
		public Image mgpbbg;
		public Image mgpbf;

		// Monster Progress Bar
		public Image mpbbg;
		public Image mpbf;

		private string[] items = { "circle_eye", "crazy_hair", "circle_head", "gap_mouth", "pig_nose", "crown" };

		// Display Text
		public Text rivalText;
		public Text goalText;
		public Text stepText;
		public Text pointsText;
		public Text remainingText;

		// Goal information.
		private string currentDayStr;
		private string goalDayStr;
		public string prefKey;

		// Used for time calculation.
		private int timeUsed;
		private int timeRemaining;
		private const int secondsperday = 86400;

		//Progress Bar...
		private float barDisplay; //current progress
		//private Vector2 barPos;
		// This gets overwritten later by the background's size values.
		private Vector2 barSize = new Vector2(5000, 10);

		//Pedometer
		private Pedometer pedometer;
		int userSteps;
		int userPoints;
		public int stepsGoal;
		private int savedSteps;
		private int savedPoints;

		public string currentStepsKey;
		public string totalPointsKey;

		void OnStep (int steps, double distance) {
			//userDistance = (distance * 3.28084);
			userSteps = steps + savedSteps;
			PlayerPrefs.SetInt(currentStepsKey,userSteps);
				stepText.text = userSteps.ToString () + "/" + stepsGoal.ToString();

			userPoints = steps*5 + savedPoints;
			PlayerPrefs.SetInt(totalPointsKey,userPoints);
			pointsText.text = "Points: " + userPoints.ToString ();
		}

		private void OnDisable () {
			// Release the pedometer
			pedometer.Dispose();
			pedometer = null;
		}

		//saved value from last session loads in on START
		//write usersteps + saved val to pref in ONSTEP

		void Start ()
		{
			//PlayerPrefs.DeleteAll(); //danger!!
			if(prefKey == "daily")
			{
				// This should later only get called per goal
				StartCoroutine(updateRival());
				currentStepsKey = "currentSteps";
				totalPointsKey = "totalPoints";
			}
			else
			{
				currentStepsKey = "currentSteps_p";
				totalPointsKey = "totalPoints_p";
			}

			savedSteps = PlayerPrefs.GetInt(currentStepsKey);
			savedPoints = PlayerPrefs.GetInt(totalPointsKey);
			// Create a new pedometer
			pedometer = new Pedometer(OnStep);
			// Reset UI
			stepText.text = savedSteps.ToString () + "/" + stepsGoal.ToString();

			if(PlayerPrefs.HasKey(totalPointsKey))
			{
				pointsText.text = "Points: " + PlayerPrefs.GetInt(totalPointsKey).ToString ();
			}
			else
			{
				PlayerPrefs.SetInt(totalPointsKey, 0);
				pointsText.text = "Points: " + PlayerPrefs.GetInt(totalPointsKey).ToString ();
			}

			if(prefKey == "daily")
				{
				if(PlayerPrefs.HasKey("goalDate"))
				{
					goalDayStr = PlayerPrefs.GetString("goalDate");
				}
				else
				{
					PlayerPrefs.SetString("goalDate",
							System.DateTime.Now.AddDays(1).ToString("MM/dd/yyyy"));
					goalDayStr = PlayerPrefs.GetString("goalDate");
				}
				goalText.color = new Color(0f, 0f, 0f);
			}
			userSteps = savedSteps;
			userPoints = savedPoints;

			//OnStep(savedSteps, 0); //necessary?
			//Debug.Log(savedSteps);

			//Debug.Log(pbbg.rectTransform.anchoredPosition.x.ToString() + " " + pbbg.rectTransform.anchoredPosition.y.ToString());

			//barPos = new Vector2(pbbg.transform.position.x, 1895 - pbbg.transform.position.y);

			currentDayStr = System.DateTime.Now.ToString("MM/dd/yyyy");
		}

		// Was used for testing.
		private float tempcounter = 0.1f;

		// Call this to update the goals progress bar.
		public void updateProgressBar()
		{
			//Debug.Log (pbbg.rectTransform.rect.width + " " + pbbg.rectTransform.rect.height);
			barSize.x = pbbg.rectTransform.rect.width;

			//tempcounter += 0.0005f;

			// resize the fill.
			RectTransform temp = pbf.rectTransform;
			//temp.sizeDelta = new Vector2 (-barSize.x + barSize.x * tempcounter, 0);
			temp.sizeDelta = new Vector2 (-barSize.x + (barSize.x * barDisplay), 0);
			temp.anchoredPosition = new Vector2 (temp.rect.width * 0.5f - (barSize.x * 0.5f),0);
		}

		// Use this for the progress bar you're testing with.
		public void updateMyGoalProgressBar()
		{
			//Debug.Log (pbbg.rectTransform.rect.width + " " + pbbg.rectTransform.rect.height);
			barSize.x = mgpbbg.rectTransform.rect.width;

			//tempcounter += 0.0005f;

			// resize the fill.
			RectTransform temp = mgpbf.rectTransform;
			//temp.sizeDelta = new Vector2 (-barSize.x + barSize.x * tempcounter, 0);
			temp.sizeDelta = new Vector2 (-barSize.x + (barSize.x * barDisplay), 0);
			temp.anchoredPosition = new Vector2 (temp.rect.width * 0.5f - (barSize.x * 0.5f),0);
		}

		// Call this to update the monster's progress bar.
		public void updateMonsterProgressBar()
		{
			float fractionused = (float)(timeUsed) / (float)(secondsperday);
			//Debug.Log (dayleft);

			barSize.x = mpbbg.rectTransform.rect.width;

			//tempcounter += 0.0005f;

			// resize the fill.
			RectTransform temp = mpbf.rectTransform;
			//temp.sizeDelta = new Vector2 (-barSize.x + barSize.x * tempcounter, 0);
			temp.sizeDelta = new Vector2 (-barSize.x + (barSize.x * fractionused), 0);
			temp.anchoredPosition = new Vector2 (temp.rect.width * 0.5f - (barSize.x * 0.5f),0);
		}

		// Calculates the time remaining for the day.
		// Will likely make a separate function for smaller timed goals if we have time.
		public void updateTimeRemaining()
		{
			timeUsed = ((System.DateTime.Now.Hour * 60 * 60) + (System.DateTime.Now.Minute * 60) + System.DateTime.Now.Second);

			timeRemaining =  secondsperday - timeUsed;
		}

		// Format the time remaining variable to a proper string.
		public string formatTimeRemaining()
		{
			string output = "Time remaining: ";

			output += "" + (timeRemaining / 3600);
			output += ":" + (timeRemaining % 3600 / 60);
			output += ":" + (timeRemaining % 60);

			return output;
		}

		// Shell function for now to update rival text.
		// You'll wanna call this with startcoroutine().
		public IEnumerator updateRival()
		{
			mp = new MochaParser ();
			yield return mp.MakeRequest ("http://corder.tech/mocha/random");
			rivalText.text = "You are being chased by " + mp.players [0].username;
		}

		void Update()
		{
			updateTimeRemaining ();
			updateProgressBar ();
			//updateMyGoalProgressBar ();

			if(prefKey == "daily")
			{
				updateMonsterProgressBar ();
				remainingText.text = formatTimeRemaining ();
				currentDayStr = System.DateTime.Now.ToString("MM/dd/yyyy");
			}

			//userSteps = (int)(Time.time*10.0f);
			//barDisplay = Time.time*0.05f;
			barDisplay = (float)userSteps/(float)stepsGoal;
			stepText.text = userSteps.ToString () + "/" + stepsGoal.ToString();

			//check if the current date matches the goal date
			if(prefKey == "daily" && currentDayStr == goalDayStr)
			{
				Debug.Log("current: " + currentDayStr);
				Debug.Log("goal:    " + goalDayStr);
				Debug.Log(prefKey + "...DAY HAS PASSED!! SETTING GOAL TO NEXT DAY!!");
				PlayerPrefs.SetString("goalDate",
						System.DateTime.Now.AddDays(1).ToString("MM/dd/yyyy"));
				goalDayStr = PlayerPrefs.GetString("goalDate");
				Debug.Log("new goal: " + goalDayStr);

				//reset steps...
				userSteps = 0;
				PlayerPrefs.SetInt(currentStepsKey, userSteps);
			}
			//goal complete
			else if(barDisplay >= 1.0f)
			{
				Debug.Log(prefKey + "... Goal complete! +100pts!");
				userSteps = 0;
				PlayerPrefs.SetInt(currentStepsKey, userSteps);
				savedSteps = 0;
				//OnStep(0,0);

				//destroy the goal and set a new one?
				savedPoints += stepsGoal*10;
				PlayerPrefs.SetInt(totalPointsKey, savedPoints);
				pointsText.text = "Points: " + PlayerPrefs.GetInt(totalPointsKey).ToString ();

				//Random item
				if(!PlayerPrefs.HasKey("inventory"))
					PlayerPrefs.SetString("inventory", "");
				StringBuilder invList = new StringBuilder ();
				invList.Append(PlayerPrefs.GetString ("inventory"));
				invList.Append(items[(int)Math.Round(UnityEngine.Random.value*6.0f)]).Append(" ");
				PlayerPrefs.SetString ("inventory", invList.ToString());
			}
		}
	}
}
