using UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;

public class PhotoTaker : MonoBehaviour
{
    // Screenshot file settings.
    public string temporaryFileName = "temp.png";
    public string androidStoragePath = "/mnt/sdcard/TestCameraApp";

    public void StartShooting()
    {
        StartCoroutine(ShootingCoroutine());
    }

    // Main coroutine

    IEnumerator ShootingCoroutine()
    {
        TakeTemporaryScreenshot();
        PlayShutterSound();

        yield return StartCoroutine(WaitCaptureCompletion());

#if UNITY_EDITOR
#elif UNITY_IOS
        AddToAlbum(TemporaryScreenshotPath);
#elif UNITY_ANDROID
        AddToAlbum(MoveToExternalStorage());
#endif
    }

    // Misc functions

    string Timestamp {
        get { return System.DateTime.Now.ToString("yyyy-MMdd-HHmm-ss"); }
    }

    string TemporaryScreenshotPath {
#if !UNITY_EDITOR && (UNITY_IOS || UNITY_ANDROID)
        get { return Path.Combine(Application.persistentDataPath, temporaryFileName); }
#else
        get { return temporaryFileName; }
#endif
    }

    bool CheckFileInUse(string filePath)
    {
        FileStream stream = null;
        try {
            stream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
        } catch (IOException) {
            return true;
        } finally {
            if (stream != null) stream.Close();
        }
        return false;
    }

    // Internal functions

    void TakeTemporaryScreenshot()
    {
        if (File.Exists(TemporaryScreenshotPath)) File.Delete(TemporaryScreenshotPath);
        Application.CaptureScreenshot(temporaryFileName);
    }

    void PlayShutterSound()
    {
#if UNITY_EDITOR
#elif UNITY_IOS
        PhotoTakerPlayShutterSound();
#elif UNITY_ANDROID
        var mediaActionSound = new AndroidJavaObject("android.media.MediaActionSound");
        mediaActionSound.Call("play", mediaActionSound.GetStatic<int>("SHUTTER_CLICK"));
#endif
    }

    IEnumerator WaitCaptureCompletion()
    {
        yield return new WaitForSeconds(0.1f);
        while (!File.Exists(TemporaryScreenshotPath)) yield return null;
        yield return new WaitForSeconds(0.1f);
        while (CheckFileInUse(TemporaryScreenshotPath)) yield return null;
    }

    string MoveToExternalStorage()
    {
        if (!Directory.Exists(androidStoragePath))
            Directory.CreateDirectory(androidStoragePath);
        var destPath = Path.Combine(androidStoragePath, Timestamp + ".png");
        File.Move(TemporaryScreenshotPath, destPath);
        return destPath;
    }

    void AddToAlbum(string filePath)
    {
#if UNITY_EDITOR
#elif UNITY_IOS
        PhotoTakerMoveImageToAlbum(filePath);
#elif UNITY_ANDROID
        // string action = Intent.ACTION_MEDIA_SCANNER_SCAN_FILE 
        AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent");
        string action = intentClass.GetStatic<string>("ACTION_MEDIA_SCANNER_SCAN_FILE");

        // Intent intentObject = new Intent(action);
        AndroidJavaObject intentObject = new AndroidJavaObject("android.content.Intent", action);

        // Uri uriObject = Uri.parse("file:" + filePath);
        AndroidJavaClass uriClass = new AndroidJavaClass("android.net.Uri");
        AndroidJavaObject uriObject = uriClass.CallStatic<AndroidJavaObject>("parse","file:" + filePath);

        // intentObject.setData(uriObject);
        intentObject.Call<AndroidJavaObject>("setData", uriObject);

        // this.sendBroadcast(intentObject);
        AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
        currentActivity.Call("sendBroadcast", intentObject);
#endif
    }

#if UNITY_IOS
    [DllImport("__Internal")] static extern void PhotoTakerPlayShutterSound();
    [DllImport("__Internal")] static extern void PhotoTakerMoveImageToAlbum(string path);
#endif
}