using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using hive;
using System.ComponentModel;

#if (UNITY_EDITOR)
using EditorGame;
#endif //

namespace GameNetwork
{

	// MARK: - URLRequest
	public class URLRequest : MonoBehaviour
	{

		public delegate void URLRequestResponse (bool success, string responseString);
		//	event URLRequestResponse URLRequestResponseHandler;

		public delegate void InnerURLRequestResponse (InnerURLRequest innerURLRequest, bool success, string responseString);

		EventHandlerList listEventDelegates = new EventHandlerList ();

		URLRequestResponse _handler;

		static URLRequest _instance = null;

		// public event URLRequestResponse URLRequestResponseHandler {
		// 	add {
		// 		listEventDelegates.AddHandler(InnerURLRequestKey, value);
		// 	}
	
		// 	remove {
		// 		listEventDelegates.RemoveHandler(InnerURLRequestKey, value);
		// 	}
		// }

		//singleton method
		static public URLRequest Instance {
		// [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
			get {
				if (_instance == null) {
					_instance = FindObjectOfType<URLRequest> ();
					if (_instance == null) {
						//create gameobject and add component postbox
						GameObject obj = new GameObject ();
						obj.name = "URLRequest";
						_instance = obj.AddComponent<URLRequest> ();
						DontDestroyOnLoad (obj);
					}
				}
				return _instance;
			}
		}

		public void Request (
			string Method,
			string URLString,
			JSONObject Parameters,
			URLRequestResponse handler)
		{
			string key = System.DateTime.Now.ToString ("yyyyMMddHHmmssffff"); 

			GameObject obj = new GameObject ();
			obj.name = "InnerURLRequest -" + key;
		
			InnerURLRequest innerURLRequest = obj.AddComponent<InnerURLRequest> ();
			obj.transform.parent = _instance.gameObject.transform;

			listEventDelegates.AddHandler (key, handler);

			innerURLRequest.Request (key, Method, URLString, Parameters, new InnerURLRequestResponse (RequestHandler));
		}

		void RequestHandler (InnerURLRequest innerURLRequest, bool success, string responseString)
		{
			string key = innerURLRequest.key;

			URLRequestResponse handler = (URLRequestResponse)listEventDelegates [(object)key];

			listEventDelegates.RemoveHandler (key, handler);

			if (handler != null) {
				handler (success, responseString);
			}

			DestroyObject (innerURLRequest.gameObject);
		}
	}


	// MARK: - InnerURLRequest
	public class InnerURLRequest : MonoBehaviour
	{

		public string key;
		public string method;
		public string urlString;
		JSONObject parameters;
		public string responseString	= null;

		URLRequest.InnerURLRequestResponse _responseHandler;

		public void Request (
			string Key,
			string Method,
			string URLString,
			JSONObject Parameters,
			URLRequest.InnerURLRequestResponse handler)
		{
			key = Key;
			method = Method;
			urlString	= URLString;
			parameters	= Parameters;
			_responseHandler	= handler;

			if (string.Compare ("POST", method, true) == 0) {
				ApplyPostMethod ();
			} else {
				Debug.LogError ("Unknown Request:\nMethod- " + method);
			}
		}

		void ApplyPostMethod ()
		{
			Dictionary<string,string> headers = new Dictionary<string, string> ();

			headers.Add ("Content-Type", "application/json");

			byte[] body = null;

			if (parameters) {
				body	= System.Text.Encoding.UTF8.GetBytes (parameters.ToString ());
			}

			WWW www = new WWW (urlString, body, headers);
	
#if UNITY_EDITOR
			EditorCoroutine.start (WaitForRequest (www));
#else
		StartCoroutine(WaitForRequest(www));
#endif // UNITY_EDITOR
		}

		IEnumerator WaitForRequest (WWW www)
		{
			do {
				yield return www;
			} while (!www.isDone);

			bool isSuccess	= false;
			string responseString = "";

			if (!string.IsNullOrEmpty (www.error)) {
				isSuccess = false;
				responseString	= www.error;

				Debug.LogError ("WWW Error: " + www.error);
			
//			yield break;
			} else {
				isSuccess = true;
				responseString	= www.text;
			
				Debug.Log ("WWW: " + www.text);
			}

			this.responseString	= responseString;

			if (_responseHandler != null) {
				_responseHandler (this, isSuccess, responseString);
			}
		}
	}
}