using System;
using nft.framework.plugin;
using nft.contributions.game;
using System.Collections.Generic;
using nft.util;

namespace nft.core.game
{
	/// <summary>
	/// MapGeneratorUtil の概要の説明です。
	/// </summary>
	public class MapGeneService
	{
		/// <summary>
		/// Default unit size (ie. grid size).
		/// Should be a multiple of 256.
		/// </summary>
		public const int DefaultUnitSize = 256;
		public const int DefaultAboveSeaLevel = 40;
		public const int SystemMaxHeight = 255;
		// max area of distric which is recomended from memory or sysytem environment.
		static public int DistrictAreaMax 
		{
			get {
				int n = DefaultUnitSize/256;
				return 64/(n*n);
			}
		}

		#region singleton
		static private MapGeneService theInstance; 
		static MapGeneService()
		{
			theInstance = new MapGeneService();
		}

		static public MapGeneService TheInstance 
		{
			get { return theInstance; }
		}

		private MapGeneService()
		{
		}
		#endregion
		
		public IWorldDivider DefaultWorldDividor 
		{
			get 
			{
                VContributionId idDefault = new VContributionId(VPluginId.System, "SimpleDivider");
                CtbWorldDivider dv = PluginManager.theInstance.GetContribution(idDefault) as CtbWorldDivider;
				if(dv!=null)
					return dv.Divider;
				else
					return null;
			}
		}

        /// <summary>
        /// Apply porper method to process for each IMapGenerator sub-interfaces.
        /// </summary>
        /// <param name="gen"></param>
        /// <param name="param"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public object GenericGenerate(IMapGenerator gen, ParamSet param, object input) {
            if (input == null) {
                if (gen is ITerrainGenerator) {
                    return ((ITerrainGenerator)gen).Generate(param);
                }
            } 
            else if(input is ITerrainMap){
                ITerrainMap map = (ITerrainMap)input;
                if (gen is IWorldDivider) {
                    return ((IWorldDivider)gen).Divide(map);
                }
            }
            throw new ArgumentException("Unknown pair of type for 'gen'" + 
                gen.GetType().Name + " and 'input'" + input.GetType().Name);
        }
    }
}
