﻿using System;
using System.Collections.Generic;

namespace Oni.Dae
{
    internal class Effect : Entity
    {
        private readonly List<EffectParameter> parameters;
        private readonly EffectParameter emission;
        private readonly EffectParameter ambient;
        private readonly EffectParameter diffuse;
        private readonly EffectParameter specular;
        private readonly EffectParameter shininess;
        private readonly EffectParameter reflective;
        private readonly EffectParameter reflectivity;
        private readonly EffectParameter transparent;
        private readonly EffectParameter transparency;
        private readonly EffectParameter indexOfRefraction;

        public Effect()
        {
            parameters = new List<EffectParameter>();

            var alphaOne = new Vector4(0.0f, 0.0f, 0.0f, 1.0f);

            emission = new EffectParameter("emission", alphaOne, this);
            ambient = new EffectParameter("ambient", alphaOne, this);
            diffuse = new EffectParameter("diffuse", alphaOne, this);
            specular = new EffectParameter("specular", alphaOne, this);
            shininess = new EffectParameter("shininess", 20.0f, this);
            reflective = new EffectParameter("reflective", 1.0f, this);
            reflectivity = new EffectParameter("reflectivity", Vector4.One, this);
            transparent = new EffectParameter("transparent", alphaOne, this);
            transparency = new EffectParameter("transparency", 1.0f, this);
            indexOfRefraction = new EffectParameter("index_of_refraction", 1.0f, this);
        }

        public EffectType Type { get; set; }

        public List<EffectParameter> Parameters => parameters;

        public IEnumerable<EffectTexture> Textures
        {
            get
            {
                foreach (var param in new[] { diffuse, ambient, specular, reflective, transparent, emission })
                {
                    var texture = param.Value as EffectTexture;

                    if (texture != null)
                        yield return texture;
                }
            }
        }

        public EffectParameter Emission => emission;

        public EffectParameter Ambient => ambient;

        public object AmbientValue
        {
            get { return ambient.Value; }
            set { ambient.Value = value; }
        }

        public EffectParameter Diffuse => diffuse;

        public object DiffuseValue
        {
            get { return diffuse.Value; }
            set { diffuse.Value = value; }
        }

        public EffectParameter Specular => specular;

        public object SpecularValue
        {
            get { return specular.Value; }
            set { specular.Value = value; }
        }

        public EffectParameter Shininess => shininess;

        public EffectParameter Reflective => reflective;

        public EffectParameter Reflectivity => reflectivity;

        public EffectParameter Transparent => transparent;

        public object TransparentValue
        {
            get { return transparent.Value; }
            set { transparent.Value = value; }
        }

        public EffectParameter Transparency => transparency;

        public EffectParameter IndexOfRefraction => indexOfRefraction;
    }
}
