/*
<copyright file="BGGCRowA.cs" company="BansheeGz">
    Copyright (c) 2018-2021 All Rights Reserved
</copyright>
*/

using System;
using System.Collections.Generic;
using GameCreator.Core;
using GameCreator.Variables;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace BansheeGz.BGDatabase
{
    /// <summary>
    /// reference to a table row 
    /// </summary>
    public abstract class BGGCRowA : BGGCTableA
    {
        public enum BGGCRowSource : byte
        {
            Index,
            Id,
            Name,
        }

        [SerializeField] [HideInInspector] private BGGCRowSource rowSource;
        [SerializeField] [HideInInspector] private int rowIndex;
        [SerializeField] [HideInInspector] private string rowId;
        [SerializeField] [HideInInspector] private string rowName;
        [SerializeField] [HideInInspector] private bool useVarForRow;

        [VariableFilter(Variable.DataType.Number)]
        public VariableProperty rowIndexVar;

        [VariableFilter(Variable.DataType.String)]
        public VariableProperty rowIdVar;

        [VariableFilter(Variable.DataType.String)]
        public VariableProperty rowNameVar;

        private BGEntity entity;

        public BGEntity GetEntity(GameObject target)
        {
            //does not work!
            // if (entity?.Meta != null && !entity.Meta.IsDeleted) return entity;
            
            entity = null;
            var meta = Meta;
            if (meta == null) return null;
            
            switch (rowSource)
            {
                case BGGCRowSource.Index:
                    var trueRowIndex = rowIndex;
                    if (useVarForRow) trueRowIndex = (int) (float) rowIndexVar.Get(target);
                    if (trueRowIndex < 0 || trueRowIndex >= meta.CountEntities) return null;
                    entity = meta.GetEntity(trueRowIndex);
                    break;
                case BGGCRowSource.Id:
                    var trueRowId = rowId;
                    if (useVarForRow) trueRowId = (string) rowIdVar.Get(target);
                    if (!BGId.TryParse(trueRowId, out var entityId)) return null;
                    entity = meta.GetEntity(entityId);
                    break;
                case BGGCRowSource.Name:
                    var trueRowName = rowName;
                    if (useVarForRow) trueRowName = (string) rowNameVar.Get(target);
                    entity = meta.GetEntity(trueRowName);
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(rowSource));
            }

            return entity;
        }
        // +--------------------------------------------------------------------------------------+
        // | EDITOR                                                                               |
        // +--------------------------------------------------------------------------------------+

#if UNITY_EDITOR

        public override void EditorGui()
        {
            base.EditorGui();
            //row source
            var newRowSource = (BGGCRowSource) EditorGUILayout.EnumPopup("Row ID type", rowSource);
            if (newRowSource != rowSource)
            {
                rowSourceProp = newRowSource;
                GUIUtility.ExitGUI();
            }

            //row var
            EditorGUILayout.PropertyField(Prop(nameof(useVarForRow)), new GUIContent("Use var for row identity"));

            //row ID
            switch (newRowSource)
            {
                case BGGCRowSource.Index:
                    EditorGUILayout.PropertyField(Prop(useVarForRow ? nameof(rowIndexVar) : nameof(rowIndex)));
                    break;
                case BGGCRowSource.Id:
                    EditorGUILayout.PropertyField(Prop(useVarForRow ? nameof(rowIdVar) : nameof(rowId)));
                    break;
                case BGGCRowSource.Name:
                    EditorGUILayout.PropertyField(Prop(useVarForRow ? nameof(rowNameVar) : nameof(rowName)));
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(newRowSource));
            }
        }

        protected override void OnDisableEditorChild()
        {
            base.OnDisableEditorChild();
            entity = null;
        }

        protected override void OnMetaChange()
        {
            base.OnMetaChange();
            rowIdProp = null;
            rowIndex = 0;
            rowName = null;
        }
        protected BGGCRowSource rowSourceProp
        {
            get => (BGGCRowSource) Prop(nameof(rowSource)).enumValueIndex;
            set => Prop(nameof(rowSource)).enumValueIndex = (int) value;
        }

        protected int rowIndexProp
        {
            get => Prop(nameof(rowIndex)).intValue;
            set => Prop(nameof(rowIndex)).intValue = value;
        }

        protected string rowIdProp
        {
            get => Prop(nameof(rowId)).stringValue;
            set => Prop(nameof(rowId)).stringValue = value;
        }

        protected string rowNameProp
        {
            get => Prop(nameof(rowName)).stringValue;
            set => Prop(nameof(rowName)).stringValue = value;
        }

        protected bool useVarForRowProp
        {
            get => Prop(nameof(useVarForRow)).boolValue;
            set => Prop(nameof(useVarForRow)).boolValue = value;
        }
#endif
    }
}