// Copyright (c) 2011-2017 Thinksquirrel Inc.

using UnityEngine;
using UnityEditor;
using Thinksquirrel.Thinkscroller;

public static class ThinkscrollerMenuItems
{
    // These variables control the location of Thinkscroller menu commands.
    // Do not include the "Thinkscroller" folder in the name.
    // No trailing slashes allowed!
    public const string menuLocation = "GameObject";
    public const string menuToolsLocation = "Tools/Thinksquirrel";

    [MenuItem(menuToolsLocation + "/Thinkscroller/Product Support", false, 10000)]
    internal static void ProductSupport()
    {
        Application.OpenURL("https://assets-support.thinksquirrel.com/collection/44-thinkscroller");
    }

    /// <summary>
    /// Creates a complete parallax scene.
    /// </summary>
    /// <remarks>
    /// Uses an orthographic camera, if selected. Otherwise, uses the main camera if it is orthographic, or creates a new camera if not.
    /// </remarks>
    [MenuItem(menuLocation + "/Thinkscroller/Parallax Scene", false, 5)]
    public static void CreateParallaxScene()
    {
        // Selection is an orthographic camera
        if (Selection.activeGameObject)
        {
            if (Selection.activeGameObject.GetComponent<Camera>())
            {
                if (Selection.activeGameObject.GetComponent<Camera>().orthographic)
                {
                    CreateParallaxScene_INTERNAL(Selection.activeGameObject.GetComponent<Camera>());
                    return;
                }
            }
        }

        // Main camera is orthographic
        if (Camera.main)
        {
            if (Camera.main.orthographic)
            {
                CreateParallaxScene_INTERNAL(Camera.main);
                return;
            }
        }

        // Create a camera
        CreateParallaxScene_INTERNAL(null);
    }

    private static void CreateParallaxScene_INTERNAL(Camera cam)
    {
        if (!cam)
        {
            var camObject = new GameObject("Parallax Camera");
            cam = camObject.AddComponent<Camera>();
            cam.orthographic = true;
            cam.orthographicSize = 1;

            cam.farClipPlane = 100;
            cam.nearClipPlane = -100;

            cam.backgroundColor = new Color(0.439f, 0.780f, 0.941f, 0.020f);

            if (!Camera.main)
            {
                cam.tag = "MainCamera";
                cam.gameObject.AddComponent<AudioListener>();
            }
        }

        // Create 3 game objects at the camera's position, and move them 5 units, 10 units, and 20 units away
        var parentObject = new GameObject("Parallax Manager");
        var foreground = new GameObject("Scroll Layer: Foreground");
        var middleground = new GameObject("Scroll Layer: Middleground");
        var background = new GameObject("Scroll Layer: Background");

        // Move parent transform to camera
        parentObject.transform.parent = cam.transform;
        parentObject.transform.localScale = Vector3.one;
        parentObject.transform.localPosition = Vector3.zero;

        // Move layers
        foreground.transform.parent = parentObject.transform;
        foreground.transform.localScale = Vector3.one;
        foreground.transform.localPosition = Vector3.forward * 5f;

        middleground.transform.parent = parentObject.transform;
        middleground.transform.localScale = Vector3.one;
        middleground.transform.localPosition = Vector3.forward * 10f;

        background.transform.parent = parentObject.transform;
        background.transform.localScale = Vector3.one;
        background.transform.localPosition = Vector3.forward * 20f;

        // Add components
        var fgLayer = foreground.AddComponent<ScrollLayer>();
        var mgLayer = middleground.AddComponent<ScrollLayer>();
        var bgLayer = background.AddComponent<ScrollLayer>();

        var manager = parentObject.AddComponent<Parallax>();

        // Add textures
        fgLayer.SetTexture(Resources.Load("FG", typeof(Texture2D)) as Texture2D);
        mgLayer.SetTexture(Resources.Load("MG", typeof(Texture2D)) as Texture2D);
        bgLayer.SetTexture(Resources.Load("BG", typeof(Texture2D)) as Texture2D);

        // Change settings
        fgLayer.alignment = ScrollLayerAlignment.Bottom;
        fgLayer.offset = new Vector2(0, -101);
        fgLayer.tileY = false;
        fgLayer.advancedFoldout_EDITOR = true;

        mgLayer.alignment = ScrollLayerAlignment.Bottom;
        mgLayer.offset = new Vector2(0, -92);
        mgLayer.tileY = false;
        mgLayer.advancedFoldout_EDITOR = true;

        bgLayer.tileY = false;
        bgLayer.advancedFoldout_EDITOR = true;

        manager.SetParallaxCamera(cam);

        cam.ResetProjectionMatrix();

        fgLayer.RefreshBillboard();
        mgLayer.RefreshBillboard();
        bgLayer.RefreshBillboard();

        // Set all objects as dirty
        EditorUtility.SetDirty(fgLayer);
        EditorUtility.SetDirty(mgLayer);
        EditorUtility.SetDirty(bgLayer);
        EditorUtility.SetDirty(manager);

        // Set selection to manager
        Selection.activeGameObject = parentObject;
    }

    /// <summary>
    /// Creates a GameObject with a pixel-perfect scroll layer.
    /// </summary>
    [MenuItem(menuLocation + "/Thinkscroller/Pixel-Perfect Scroll Layer", false, 5)]
    public static void CreatePixelPerfectScrollLayer()
    {
        var scrollLayerObject = new GameObject("Scroll Layer");
        scrollLayerObject.AddComponent<ScrollLayer>();
    }

    /// <summary>
    /// Creates a GameObject with a tiled scroll layer.
    /// </summary>
    [MenuItem(menuLocation + "/Thinkscroller/Tiled Scroll Layer", false, 5)]
    public static void CreateTiledScrollLayer()
    {
        var scrollLayerObject = new GameObject("Scroll Layer");
        var layer = scrollLayerObject.AddComponent<ScrollLayer>();
        layer.isPixelPerfect = false;
    }

    /// <summary>
    /// Creates a GameObject with a stretched scroll layer.
    /// </summary>
    [MenuItem(menuLocation + "/Thinkscroller/Stretched Scroll Layer", false, 5)]
    public static void CreateStretchedScrollLayer()
    {
        var scrollLayerObject = new GameObject("Scroll Layer");
        var layer = scrollLayerObject.AddComponent<ScrollLayer>();
        layer.isPixelPerfect = false;
        layer.SetBillboardStretch(true);
    }

    /// <summary>
    /// Creates a GameObject with an object scroll layer.
    /// </summary>
    [MenuItem(menuLocation + "/Thinkscroller/Object Scroll Layer", false, 5)]
    public static void CreateObjectScrollLayer()
    {
        var scrollLayerObject = new GameObject("Scroll Layer");
        var layer = scrollLayerObject.AddComponent<ScrollLayer>();
        layer.isObjectLayer = true;
    }

    /// <summary>
    /// Creates a GameObject with a parallax manager.
    /// </summary>
    [MenuItem(menuLocation + "/Thinkscroller/Parallax Manager", false, 5)]
    public static void CreateParallaxManager()
    {
        var managerObject = new GameObject("Parallax Manager");
        managerObject.AddComponent<Parallax>();
    }
}
