available_frequencies = ["moy", "woy", "doy", "dow"];
# available_modalities = ["add", "mul"];

to_datefn = OrderedDict{Symbol, Function}(
    :moy => month,
    :woy => week,
    :doy => dayofyear,
    :dow => dayofweek
)
to_intmode = OrderedDict{Symbol, Int8}(
    :add => Ses.inte_one,
    :mul => Ses.inte_two
)
to_symbmode = OrderedDict{Int8, Symbol}(
    Ses.inte_one => :add,
    Ses.inte_two => :mul
)



init_factors(;mode::Int8 = inte_one, init::Float32 = 0.0f0, dims::NTuple{2, <:Integer} = (1, 1)) =
    if is_additive(mode) fill(init, dims) else fill(1.0f0, dims) end



rescale(mode::Real, label::Real, factor::Real) = ifelse(is_additive(mode), label + factor, label / factor);
rescale(mode::Real, labels::AbstractVecOrMat{<:Real}, factor::Real) = rescale.(mode, labels, factor);
rescale(mode::Real, labels::Real, factor::AbstractVecOrMat{<:Real}) = rescale.(mode, labels, factor);
function rescale(mode::Real, labels::AbstractVecOrMat{<:Real}, factors::AbstractVecOrMat{<:Real})
    if is_additive(mode)
        # return [lb + fct for (lb, fct) in zip(labels, factors)];
        return labels .- factors;
    end

    # return [lb / fct for (lb, fct) in zip(labels, factors)];
    return labels .* factors;
end



scale(mode::Real, label::Real, factor::Real) = ifelse(is_additive(mode), label - factor, label * factor);
scale(mode::Real, label::AbstractVecOrMat{<:Real}, factor::Real) = scale.(mode, label, factor);
function scale(mode::Real, labels::AbstractVecOrMat{<:Real}, factors::AbstractVecOrMat{<:Real})
    if is_additive(mode)
        # return [lb - fct for (lb, fct) in zip(labels, factors)];
        return labels .- factors;
    end

    # return [lb * fct for (lb, fct) in zip(labels, factors)];
    return labels .* factors;
end



include("abstract.jl")
include("scalers.jl")



to_scaler = OrderedDict{Symbol, Tuple}(
    :moy => (Ses.MonthlyScaler, Ses.InvMonthlyScaler),
    :woy => (Ses.WeeklyScaler, Ses.InvWeeklyScaler),
    :doy => (Ses.DayOfYearScaler, Ses.InvDayOfYearScaler),
    :dow => (Ses.DayOfWeekScaler, Ses.InvDayOfWeekScaler)
);



include("logging.jl")