﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Oni.Objects
{
    internal class ObjectLoadContext
    {
        private readonly Func<TemplateTag, string, ObjectLoadContext, InstanceDescriptor> getDescriptor;
        private readonly TextWriter info;
        private readonly Dictionary<string, ObjectClass> classCache;
        private string basePath;
        private string filePath;

        public ObjectLoadContext(Func<TemplateTag, string, ObjectLoadContext, InstanceDescriptor> getDescriptor, TextWriter info)
        {
            this.getDescriptor = getDescriptor;
            this.info = info;
            this.classCache = new Dictionary<string, ObjectClass>(StringComparer.Ordinal);
        }

        public T GetClass<T>(TemplateTag tag, string name, Func<InstanceDescriptor, T> reader)
            where T : ObjectClass, new()
        {
            ObjectClass klass;

            string fullName = tag.ToString() + name;

            if (!classCache.TryGetValue(fullName, out klass))
            {
                var descriptor = getDescriptor(tag, name, this);

                if (descriptor != null)
                {
                    info.WriteLine("Using {0} object class '{1}' from '{2}'", tag, descriptor.Name, descriptor.FilePath);

                    klass = reader(descriptor);
                    klass.Name = descriptor.Name;
                }

                classCache.Add(fullName, klass);
            }

            return (T)klass;
        }

        public string BasePath
        {
            get { return basePath; }
            set { basePath = value; }
        }

        public string FilePath
        {
            get { return filePath; }
            set { filePath = value; }
        }
    }
}
