using System;
using System.Collections.Generic;
using System.Text;
using nft.framework.drawing;
using nft.framework;
using nft.core.schedule;

namespace nft.core.view
{
    /// <summary>
    /// Categorize type of conditions by its watch parameter and time cycle.
    /// 'TimeOfDay' is based on the sun movement (day/night range can vary), while 'Daily' is based on clock value. 
    /// Array of same type conditions can be combined and optimized as Hashmap by ConditionResourceFactory
    /// </summary>
    public enum ConditionTypes { 
        Unknown,
        Daily = (int)TimeUnit.Day,
        Weekly = (int)TimeUnit.Week,
        Monthly = (int)TimeUnit.Month,
        Yearly = (int)TimeUnit.Years,
        TimeOfDay, Weather, Scale }

    public interface ISceneParams
    {
        //DateTime Datetime { get; }
        Time Time { get; }
        Object Weather { get; }
        Scaler Scaler { get; }
    }

    public interface IConditionFactory
    {
        string Name { get; }

        ISceneCondition GetCondition(ParamsReader reader);

    }

    public interface ISceneCondition
    {
        string GroupName { get; }
        string ConditionName { get; }
        ConditionTypes ConditionType { get; }
        bool IsMatch(ISceneParams p);
    }

    /// <summary>
    /// This interface should be declared for the ISceneConditions which based on 
    /// 'Time' (based on the Calendar in the game) condition(s).
    /// If there are several ITimeRangeConditions with the same ConditionType, They can union to include them all.
    /// Which can be a new ITimeRangeCondition.
    /// 
    /// このインターフェースはTimeクラスを条件としたISceneConditionで実装されることを想定している
    /// もし、同じConditionTypeを持つ複数のITimeRangeConditionが存在するなら、
    /// その両方を同時に含む期間を定義することができ、それを条件とした新たなITimeRangeConditionとなりうる。
    /// </summary>
    public interface ITimeRangeCondition {
        /// <summary>
        /// returns true if this condition is after the scene
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        bool IsAfter(ISceneParams p);

        /// <summary>
        /// returns true if this condition is before the scene
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        bool IsBefore(ISceneParams p);
    }

}
