using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(WaveSpawnerScript))]
public class WaveSpawnerEditor : Editor {

    /*SerializedProperties*/
    SerializedProperty spawnPointProp;
    SerializedProperty wavesProp;
        /*Waveclass elements*/
        SerializedProperty waveNameProp;
        SerializedProperty enemyPrefabProp;
        SerializedProperty countdownProp;
        SerializedProperty runsProp;
        SerializedProperty enemiesPerRunProp;
        SerializedProperty timeBetweenRunsProp;
    SerializedProperty timeNeededProp;

    private void OnEnable() {
        /*Initialization*/
        spawnPointProp = serializedObject.FindProperty("spawnPoint");
        wavesProp = serializedObject.FindProperty("waves");
        timeNeededProp = serializedObject.FindProperty("timeNeeded");
    }

    public override void OnInspectorGUI() {
        serializedObject.Update();

        /*SpawnPoint field*/
        GUILayout.Space(10);
        EditorGUILayout.PropertyField(spawnPointProp, new GUIContent("Spawn Point"), GUILayout.Width(300));
        GUILayout.Space(20);

        /*Infotext*/
        EditorGUILayout.LabelField("Info", EditorStyles.boldLabel);
        EditorGUILayout.LabelField("You should calculate TimeBetweenRuns as the");
        EditorGUILayout.LabelField("following: TimePerWave > EnemyPerWave * 2 + x");
        GUILayout.Space(10);

        /*AddWave button*/
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("WaveSpawner editor");
        if (GUILayout.Button("Add wave", GUILayout.Width(100))) {
            AddWave(wavesProp);
        }
        EditorGUILayout.EndHorizontal();

        /*Wave-Settings*/
        for (int i = 0; i < wavesProp.arraySize; i++) {

            GUILayout.Space(10);

            /*Initialization*/
            waveNameProp = wavesProp.GetArrayElementAtIndex(i).FindPropertyRelative("waveName");
            enemyPrefabProp = wavesProp.GetArrayElementAtIndex(i).FindPropertyRelative("enemyPrefab");
            countdownProp = wavesProp.GetArrayElementAtIndex(i).FindPropertyRelative("countdown");
            runsProp = wavesProp.GetArrayElementAtIndex(i).FindPropertyRelative("runs");
            enemiesPerRunProp = wavesProp.GetArrayElementAtIndex(i).FindPropertyRelative("enemiesPerRun");
            timeBetweenRunsProp = wavesProp.GetArrayElementAtIndex(i).FindPropertyRelative("timeBetweenRuns");

            EditorGUILayout.BeginVertical("box");

            /*DeleteWave button*/
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField(waveNameProp.stringValue);
            if (GUILayout.Button("Delete wave", GUILayout.Width(100))) {
                RemoveWave(wavesProp, i);
                serializedObject.ApplyModifiedProperties();
                return;
            }
            EditorGUILayout.EndHorizontal();


            /*PropertyFields*/
            EditorGUILayout.PropertyField(waveNameProp, new GUIContent("Wave name"), GUILayout.Width(295));
            EditorGUILayout.PropertyField(enemyPrefabProp, new GUIContent("Enemy prefab"), GUILayout.Width(295));
            EditorGUILayout.PropertyField(countdownProp, new GUIContent("Countdown"), GUILayout.Width(295));

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(runsProp, new GUIContent("Runs"), GUILayout.Width(295));
            //If the run value has changed we have to resize the enemiesPerRun and timeBetweenRuns array
            if(EditorGUI.EndChangeCheck()) {
                enemiesPerRunProp.arraySize = runsProp.intValue;
                timeBetweenRunsProp.arraySize = runsProp.intValue;
            }

            EditorGUILayout.LabelField("Enemies per run");
            EditorGUILayout.BeginHorizontal();
            for (int j = 0; j < enemiesPerRunProp.arraySize; j++) {
                EditorGUILayout.PropertyField(enemiesPerRunProp.GetArrayElementAtIndex(j), new GUIContent(""),GUILayout.Width(30));
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.LabelField("Time between runs");
            EditorGUILayout.BeginHorizontal();
            for (int j = 0; j < timeBetweenRunsProp.arraySize; j++) {
                EditorGUILayout.PropertyField(timeBetweenRunsProp.GetArrayElementAtIndex(j), new GUIContent(""), GUILayout.Width(30));
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();
        }

        GUILayout.Space(20);
        EditorGUILayout.LabelField("Time Needed: " + timeNeededProp.floatValue + " s");

        serializedObject.ApplyModifiedProperties();
    }

    private void AddWave(SerializedProperty array) {
        array.arraySize++;

        array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("waveName").stringValue = "Wave " + array.arraySize.ToString();

        array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("enemyPrefab").objectReferenceValue = null;

        array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("countdown").floatValue = 5f;

        array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("runs").intValue = 1;

        array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("enemiesPerRun").arraySize = 
            array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("runs").intValue;

        array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("timeBetweenRuns").arraySize = 
            array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("runs").intValue;

        for (int i = 0; i < array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("enemiesPerRun").arraySize; i++) {
            array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("enemiesPerRun").
                GetArrayElementAtIndex(array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("enemiesPerRun").arraySize - 1).intValue = 1;
        }
        for (int i = 0; i < array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("timeBetweenRuns").arraySize; i++) {
            array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("timeBetweenRuns").
                GetArrayElementAtIndex(array.GetArrayElementAtIndex(array.arraySize - 1).FindPropertyRelative("timeBetweenRuns").arraySize -1).floatValue = 6f;
        }
    }

    private void RemoveWave(SerializedProperty array, int index) {
        int oldSize = array.arraySize;
        array.DeleteArrayElementAtIndex(index);
        if (array.arraySize == oldSize) {
            array.DeleteArrayElementAtIndex(index);
        }
    }
}