﻿using System;
using TSGenHD.Exceptions;
using TSGenHD.TypeScript;
using TSGenHD.TypeScript.InternalTypes;

namespace TSGenHD.Factories
{
    public static class TsTypeFactory
    {
        public static TypeResolver Resolver = new TypeResolver();

        public static TsType Create(TsType parent, Type type)
        {
            TsType result = null;

            if (type.IsClass)
            {
                result = ClassFactory.CreateClass(parent, type);
            }
            else if (type.IsEnum)
            {
                result = EnumFactory.CreateEnum(parent, type);
            }
            else if (type == typeof(string))
            {
                result = TsString.Instance;
            }
            else if (IsNumberType(type))
            {
                result = TsNumber.Instance;
            }
            else if (type == typeof (char))
            {
                result = TsString.Instance;
            }
            else if (type == typeof (bool))
            {
                result = TsBoolean.Instance;
            }
            else if (type.IsArray)
            {
                result = new TsArray(type.GetElementType());
            }
            else if (type == typeof(object))
            {
                result = TsAny.Instance;
            }
            else if (type.IsValueType)
            {
                result = ClassFactory.CreateClass(parent, type);
            }
            else if (type.IsInterface)
            {
                result = ClassFactory.CreateClass(parent, type);
            }

            if (result != null)
            {
                Resolver.Types[type] = result;
                return result;
            }

            throw new UnsupportedTypeException(type);
        }

        public static bool IsNumberType(Type t)
        {
            return t == typeof(float) ||
                   t == typeof(double) ||
                   t == typeof(int) ||
                   t == typeof(uint) ||
                   t == typeof(ushort) ||
                   t == typeof(decimal) ||
                   t == typeof(long) ||
                   t == typeof(ulong) ||
                   t == typeof(byte) ||
                   t == typeof(sbyte) ||
                   t == typeof(short);
        }
    }
}