﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;

public static class MakeTesseract {
    [MenuItem("Tools/Make Tesseract")]
    public static void MkTesseract()
    {
        var mesh = new Mesh();

        // 0               1
        // 2               3
        //     8       9
        //     10      11
        //      12   13
        //      14   15
        // 4               5
        // 6               7
        List<Vector4> vert4d = new List<Vector4> {
            new Vector4(0,0,0,0),
            new Vector4(1,0,0,0),
            new Vector4(0,1,0,0),
            new Vector4(1,1,0,0),

            new Vector4(0,0,1,0),
            new Vector4(1,0,1,0),
            new Vector4(0,1,1,0),
            new Vector4(1,1,1,0),

            new Vector4(0,0,0,1),
            new Vector4(1,0,0,1),
            new Vector4(0,1,0,1),
            new Vector4(1,1,0,1),

            new Vector4(0,0,1,1),
            new Vector4(1,0,1,1),
            new Vector4(0,1,1,1),
            new Vector4(1,1,1,1),
        };
        Vector4 recenter = new Vector4(-0.5f, -0.5f, -0.5f, -0.5f);

        var verts = new List<Vector3>();
        var colors = new List<Color>();
        var triangles = new List<int>();
        var uvs = new List<Vector2>();

        System.Action<int, int, int, int> mkface = (a, b, c,d) =>
        {
            var start = verts.Count();
            verts.AddRange(new List<Vector3>
            {
                vert4d[a] + recenter,
                vert4d[b] + recenter,
                vert4d[c] + recenter,
                vert4d[d] + recenter,
            });
            colors.AddRange(new List<Color>
            {
                new Color((vert4d[a] + recenter).w, 0,0),
                new Color((vert4d[b] + recenter).w, 0,0),
                new Color((vert4d[c] + recenter).w, 0,0),
                new Color((vert4d[d] + recenter).w, 0,0),
            });

            // grid of 6 wide 4 tall
            var face = start / 4;
            float uvx = (face % 6) / 6f;
            float uvy = (face / 6) / 4f;
            Debug.Log($"face {face} at {uvx} {uvy}");

            uvs.AddRange(new List<Vector2>
            {
                new Vector2(uvx + 0    , uvy + 0),
                new Vector2(uvx + 1/6f , uvy + 0),
                new Vector2(uvx + 0    , uvy + 1/4f),
                new Vector2(uvx + 1/6f , uvy + 1/4f),
            });
            triangles.AddRange(new List<int> {
                start, start + 2, start + 1,
                start + 2, start + 3, start + 1
            });
        };

        mkface(0, 1, 2, 3); // outer back
        mkface(0, 1, 4, 5); // outer top
        mkface(2, 3, 6, 7); // outer bottom
        mkface(4, 5, 6, 7); // outer front
        mkface(0, 4, 2, 6); // outer left
        mkface(1, 5, 3, 7); // outer right

        mkface(8, 9, 10, 11); // inner back
        mkface(8, 9, 12, 13); // inner top
        mkface(10, 11, 14, 15); // inner bottom
        mkface(12, 13, 14, 15); // inner front
        mkface(8, 12, 10, 14); // inner left
        mkface(9, 13, 11, 15); // inner right

        mkface(0, 8, 2, 10); // top-left vertical
        mkface(9, 1, 11, 3); // top-right vertical
        mkface(4, 12, 6, 14); // bottom-left vertical
        mkface(13, 5, 15, 7); // bottom-right vertical

        mkface(0, 1, 8, 9); // top-back horiz
        mkface(12, 13, 4, 5); // top-front horiz
        mkface(8, 12, 0, 4); // top-left horiz
        mkface(1, 5, 9, 13); // top-right horiz

        mkface(2, 3, 10, 11); // bottom-back horiz
        mkface(14, 15, 6, 7); // bottom-front horiz
        mkface(10, 14, 2, 6); // bottom-left horiz
        mkface(3, 7, 11, 15); // bottom-right horiz

        mesh.SetVertices(verts);
        mesh.SetTriangles(triangles, 0);
        mesh.SetUVs(0, uvs);
        mesh.SetColors(colors);

        MeshUtility.Optimize(mesh);

        AssetDatabase.CreateAsset(mesh, "Assets/tesseract/tesseract.asset");
        AssetDatabase.SaveAssets();
    }
}
