﻿using System;
using System.Collections.Generic;

namespace Oni.Dae
{
    internal abstract class Transform
    {
        private string sid;
        private readonly float[] values;
        private Sampler[] animations;

        protected Transform(int valueCount)
        {
            this.values = new float[valueCount];
        }

        protected Transform(string sid, int valueCount)
        {
            this.sid = sid;
            this.values = new float[valueCount];
        }

        public string Sid
        {
            get { return sid; }
            set { sid = value; }
        }

        public float[] Values => values;
        public bool HasAnimations => animations != null;

        public Sampler[] Animations
        {
            get
            {
                if (animations == null)
                    animations = new Sampler[values.Length];

                return animations;
            }
        }

        protected Sampler GetAnimation(int index)
        {
            if (animations == null)
                return null;

            return animations[index];
        }

        public void BindAnimation(string valueName, Sampler animation)
        {
            if (string.IsNullOrEmpty(valueName))
            {
                for (int i = 0; i < values.Length; i++)
                    BindAnimation(i, animation);
            }
            else
            {
                int valueIndex = ParseValueIndex(valueName);

                if (valueIndex != -1)
                    BindAnimation(valueIndex, animation);
            }
        }

        private void BindAnimation(int index, Sampler animation)
        {
            if (animation.Inputs.Count == 0 || animation.Inputs[0].Source.Count == 0)
                animation = null;

            if (animation == null && !HasAnimations)
                return;

            Animations[index] = animation;
        }

        private int ParseValueIndex(string name)
        {
            if (name[0] == '(')
            {
                int end = name.IndexOf(')', 1);

                if (end == -1)
                    return -1;

                return int.Parse(name.Substring(1, end - 1).Trim());
            }

            return ValueNameToValueIndex(name);
        }

        public abstract int ValueNameToValueIndex(string name);
        public abstract string ValueIndexToValueName(int index);

        public abstract Matrix ToMatrix();
    }
}
