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

using System;
using System.Collections.Generic;
using Bolt;
using Ludiq;

namespace BansheeGz.BGDatabase
{
    [BGPluginAttribute(Version = "1.0")]
    [UnitCategory("BansheeGz")]
    public class BGDatabaseGetField : BGDatabaseGetFieldA
    {

        [DoNotSerialize] public ValueOutput targetEntity;
        [DoNotSerialize] public ValueOutput objectValue;
        [DoNotSerialize] public ValueOutput stringValue;
        [DoNotSerialize] public ValueOutput intValue;
        [DoNotSerialize] public ValueOutput floatValue;
        [DoNotSerialize] public ValueOutput boolValue;
        [DoNotSerialize] public ValueOutput entityValue;
        [DoNotSerialize] public ValueOutput entityListValue;

        protected override void Definition()
        {
            base.Definition();

            targetEntity = ValueOutput<BGEntity>("targetEntity", GetTargetEntity);
            objectValue = ValueOutput<object>("objectValue", GetObjectValue);
            stringValue = ValueOutput<string>("stringValue", GetStringValue);
            intValue = ValueOutput<int>("intValue", GetIntValue);
            floatValue = ValueOutput<float>("floatValue", GetFloatValue);
            boolValue = ValueOutput<bool>("boolValue", GetBoolValue);
            entityValue = ValueOutput<BGEntity>("entityValue", GetEntityValue);
            entityListValue = ValueOutput<List<BGEntity>>("entityListValue", GetEntityListValue);
        }


        private List<BGEntity> GetEntityListValue(Flow flow)
        {
            return GetCastedValue<List<BGEntity>>(flow);
        }

        private BGEntity GetEntityValue(Flow flow)
        {
            return GetCastedValue<BGEntity>(flow);
        }

        private bool GetBoolValue(Flow flow)
        {
            return GetCastedValue<bool>(flow);
        }

        private float GetFloatValue(Flow flow)
        {
            return GetCastedValue<float>(flow);
        }

        private int GetIntValue(Flow flow)
        {
            return GetCastedValue<int>(flow);
        }

        private string GetStringValue(Flow flow)
        {
            return GetCastedValue<string>(flow);
        }

        private T GetCastedValue<T>(Flow flow)
        {
            var meta = GetMeta(flow);
            var field = GetField(flow, meta);
            if (!(field is BGField<T>)) throw new Exception("Can not cast " + field.FullName + " field to BGField<" + typeof(T).Name + ">, the field's value type is " + field.ValueType.Name);
            var row = GetEntity(flow, meta);
            return ((BGField<T>) field)[row.Index];
        }

        private object GetObjectValue(Flow flow)
        {
            var meta = GetMeta(flow);
            var field = GetField(flow, meta);
            var row = GetEntity(flow, meta);
            return field.GetValue(row.Index);
        }

        private BGEntity GetTargetEntity(Flow flow)
        {
            var meta = GetMeta(flow);
            return GetEntity(flow, meta);
        }
    }
}