using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class UnityNetworkManager : MonoBehaviour
{
    private static UnityNetworkManager instance;
    public static UnityNetworkManager Instance
    {
        get
        {
            if (instance == null)
            {
                GameObject NetworkManager = new GameObject("UnityNetworkManager");
                instance = NetworkManager.AddComponent<UnityNetworkManager>();
            }
            return instance;
        }
    }
    /**
    UnityWebRequest uwr = new UnityWebRequest();
    uwr.url = "http://www.mysite.com";
    uwr.method = UnityWebRequest.kHttpVerbGET;   // can be set to any custom method, common constants privided
 
    uwr.useHttpContinue = false;
    uwr.chunkedTransfer = false;
    uwr.redirectLimit = 0;  // disable redirects
    uwr.timeout = 60;       // don't make this small, web requests do take some time 
    **/

    /// <summary>
    /// GET请求
    /// </summary>
    /// <param name="url"></param>
    /// <param name="action"></param>
    public void Get(string url, Action<bool, string> actionResult)
    {
        StartCoroutine(_Get(url, actionResult));
    }


    /// <summary>
    /// 请求byte数据
    /// </summary>
    /// <param name="url"></param>
    /// <param name="action">请求发起后处理回调结果的委托,处理请求结果的byte数组</param>
    /// <returns></returns>
    public void GetBytes(string url, Action<bool, string, byte[]> actionResult)
    {
        StartCoroutine(_GetBytes(url, actionResult));
    }

    /// <summary>
    /// 请求图片
    /// </summary>
    /// <param name="url">图片地址,like 'http://www.my-server.com/image.png '</param>
    /// <param name="action">请求发起后处理回调结果的委托,处理请求结果的图片</param>
    /// <returns></returns>
    public void GetTexture(string url, Action<bool, string, Texture2D> actionResult)
    {
        StartCoroutine(_GetTexture(url, actionResult));
    }

    /// <summary>
    /// 请求AssetBundle
    /// </summary>
    /// <param name="url">AssetBundle地址,like 'http://www.my-server.com/myData.unity3d'</param>
    /// <param name="actionResult">请求发起后处理回调结果的委托,处理请求结果的AssetBundle</param>
    /// <returns></returns>
    public void GetAssetBundle(string url, Action<bool, string, AssetBundle> actionResult)
    {
        StartCoroutine(_GetAssetBundle(url, actionResult));
    }

    /// <summary>
    /// 请求服务器地址上的音效
    /// </summary>
    /// <param name="url">没有音效地址,like 'http://myserver.com/mysound.wav'</param>
    /// <param name="actionResult">请求发起后处理回调结果的委托,处理请求结果的AudioClip</param>
    /// <param name="audioType">音效类型</param>
    /// <returns></returns>
    public void GetAudioClip(string url, Action<bool, string, AudioClip> actionResult, AudioType audioType = AudioType.WAV)
    {
        StartCoroutine(_GetAudioClip(url, actionResult, audioType));
    }

    /// <summary>
    /// 向服务器提交post请求
    /// </summary>
    /// <param name="serverURL">服务器请求目标地址,like "http://www.my-server.com/myform"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托,处理请求对象</param>
    /// <returns></returns>
    public void Post(string serverURL, List<IMultipartFormSection> lstformData, Action<bool, string> actionResult)
    {
        //List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        //formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
        //formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));

        StartCoroutine(_Post(serverURL, lstformData, actionResult));
    }

    /// <summary>
    /// 通过PUT方式将字节流传到服务器
    /// </summary>
    /// <param name="url">服务器目标地址 like 'http://www.my-server.com/upload' </param>
    /// <param name="contentBytes">需要上传的字节流</param>
    /// <param name="resultAction">处理返回结果的委托</param>
    /// <returns></returns>
    public void UploadByPut(string url, byte[] contentBytes, Action<bool> actionResult)
    {
        StartCoroutine(_UploadByPut(url, contentBytes, actionResult, ""));
    }

    /// <summary>
    /// GET请求
    /// </summary>
    /// <param name="url">请求地址,like 'http://www.my-server.com/ '</param>
    /// <param name="action">请求发起后处理回调结果的委托</param>
    /// <returns></returns>
    IEnumerator _Get(string url, Action<bool, string> actionResult)
    {
        using (UnityWebRequest uwr = UnityWebRequest.Get(url))
        {
            //yield return uwr.SendWebRequest();
            yield return uwr.SendWebRequest();
            string text = "";
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                text = uwr.downloadHandler.text;
            }
            else
            {
                text = uwr.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke(uwr.isHttpError, text);
            }
        }
    }

    /// <summary>
    /// 请求图片
    /// </summary>
    /// <param name="url"></param>
    /// <param name="action">请求发起后处理回调结果的委托,处理请求结果的byte数组</param>
    /// <returns></returns>
    IEnumerator _GetBytes(string url, Action<bool, string, byte[]> actionResult)
    {
        using (UnityWebRequest uwr = new UnityWebRequest(url))
        {
            DownloadHandlerFile downloadFile = new DownloadHandlerFile(url);
            uwr.downloadHandler = downloadFile;
            yield return uwr.SendWebRequest();
            byte[] bytes = null;
            string text = null;
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                bytes = downloadFile.data;
            }
            else
            {
                text = uwr.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke((uwr.isNetworkError || uwr.isHttpError), text, bytes);
            }
        }
    }
    /// <summary>
    /// 请求图片
    /// </summary>
    /// <param name="url">图片地址,like 'http://www.my-server.com/image.png '</param>
    /// <param name="action">请求发起后处理回调结果的委托,处理请求结果的图片</param>
    /// <returns></returns>
    IEnumerator _GetTexture(string url, Action<bool, string, Texture2D> actionResult)
    {
        using (UnityWebRequest uwr = new UnityWebRequest(url))
        {
            DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
            uwr.downloadHandler = downloadTexture;
            yield return uwr.SendWebRequest();
            Texture2D texture = null;
            string text = null;
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                texture = downloadTexture.texture;
            }
            else
            {
                text = uwr.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke((uwr.isNetworkError || uwr.isHttpError), text, texture);
            }
        }
    }

    /// <summary>
    /// 请求AssetBundle
    /// </summary>
    /// <param name="url">AssetBundle地址,like 'http://www.my-server.com/myData.unity3d'</param>
    /// <param name="actionResult">请求发起后处理回调结果的委托,处理请求结果的AssetBundle</param>
    /// <returns></returns>
    IEnumerator _GetAssetBundle(string url, Action<bool, string, AssetBundle> actionResult)
    {
        using (UnityWebRequest uwr = new UnityWebRequest(url))
        {
            DownloadHandlerAssetBundle downloadAssetBundle = new DownloadHandlerAssetBundle(uwr.url, uint.MaxValue);
            uwr.downloadHandler = downloadAssetBundle;
            yield return uwr.SendWebRequest();
            AssetBundle assetBundle = null;
            string text = null;
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                assetBundle = downloadAssetBundle.assetBundle;
            }
            else
            {
                text = uwr.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke((uwr.isNetworkError || uwr.isHttpError), text, assetBundle);
            }
        }
    }

    /// <summary>
    /// 请求服务器地址上的音效
    /// </summary>
    /// <param name="url">没有音频地址,like 'http://myserver.com/mymovie.mp3'</param>
    /// <param name="actionResult">请求发起后处理回调结果的委托,处理请求结果的MovieTexture</param>
    /// <param name="audioType">音效类型</param>
    /// <returns></returns>
    IEnumerator _GetAudioClip(string url, Action<bool, string, AudioClip> actionResult, AudioType audioType = AudioType.WAV)
    {
        using (UnityWebRequest uwr = new UnityWebRequest(url))
        {
            DownloadHandlerAudioClip downloadAudioClip = new DownloadHandlerAudioClip(url, AudioType.WAV);
            uwr.downloadHandler = downloadAudioClip;
            yield return uwr.SendWebRequest();
            AudioClip audioClip = null;
            string text = null;
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                audioClip = downloadAudioClip.audioClip;
            }
            else
            {
                text = uwr.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke((uwr.isNetworkError || uwr.isHttpError), text, audioClip);
            }
        }
    }

    /// <summary>
    /// 向服务器提交post请求
    /// </summary>
    /// <param name="url">服务器请求目标地址,like "http://www.my-server.com/myform"</param>
    /// <param name="lstformData">form表单参数</param>
    /// <param name="lstformData">处理返回结果的委托</param>
    /// <returns></returns>
    IEnumerator _Post(string url, List<IMultipartFormSection> lstformData, Action<bool, string> actionResult)
    {
        //List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        //formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
        //formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));
        using (UnityWebRequest uwr = UnityWebRequest.Post(url, lstformData))
        {
            yield return uwr.SendWebRequest();
            string text = "";
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                text = uwr.downloadHandler.text;
            }
            else
            {
                text = uwr.error;
            }
            if (actionResult != null)
            {
                actionResult.Invoke(uwr.isHttpError, text);
            }
        }
    }

    /// <summary>
    /// 通过PUT方式将字节流传到服务器
    /// </summary>
    /// <param name="url">服务器目标地址 like 'http://www.my-server.com/upload' </param>
    /// <param name="contentBytes">需要上传的字节流</param>
    /// <param name="resultAction">处理返回结果的委托</param>
    /// <param name="resultAction">设置header文件中的Content-Type属性</param>
    /// <returns></returns>
    IEnumerator _UploadByPut(string url, byte[] contentBytes, Action<bool> actionResult, string contentType = "application/octet-stream")
    {
        using (UnityWebRequest uwr = new UnityWebRequest())
        {
            UploadHandler uploader = new UploadHandlerRaw(contentBytes);

            // Sends header: "Content-Type: custom/content-type";
            uploader.contentType = contentType;

            uwr.uploadHandler = uploader;

            yield return uwr.SendWebRequest();

            bool res = true;
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                res = false;
            }
            if (actionResult != null)
            {
                actionResult.Invoke(res);
            }
        }
    }
}