# Orca
#
# Copyright 2005-2008 Google Inc.
# Portions Copyright 2007-2008, Sun Microsystems, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
# Boston MA  02110-1301 USA.
#
"""ACSS --- Aural CSS.

Class ACSS defines a simple wrapper for holding ACSS voice
definitions.  Speech engines implement the code for converting
ACSS definitions into engine-specific markup codes.

"""

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from typing import ClassVar


class ACSS(dict):
    """Holds ACSS representation of a voice."""

    FAMILY = "family"
    RATE = "rate"
    GAIN = "gain"
    AVERAGE_PITCH = "average-pitch"
    PITCH_RANGE = "pitch-range"
    STRESS = "stress"
    RICHNESS = "richness"
    PUNCTUATIONS = "punctuations"

    settings: ClassVar[dict[str, str | int | None]] = {
        FAMILY: None,  # None means use the engine's default value.
        RATE: 50,
        GAIN: 10,
        AVERAGE_PITCH: 5,
        PITCH_RANGE: 5,
        STRESS: 5,
        RICHNESS: 5,
        PUNCTUATIONS: "all",
    }

    def __init__(self, props: dict | None = None):
        """Create and initialize ACSS structure."""

        super().__init__()
        if not props:
            self["established"] = False
            return
        for key, value in props.items():
            if key == "established" or key in ACSS.settings:
                self[key] = dict(value) if key == ACSS.FAMILY else value

    def __eq__(self, other):
        if not isinstance(other, ACSS):
            return False
        if self.get(ACSS.FAMILY) != other.get(ACSS.FAMILY):
            return False
        if self.get(ACSS.RATE) != other.get(ACSS.RATE):
            return False
        return self.get(ACSS.AVERAGE_PITCH) == other.get(ACSS.AVERAGE_PITCH)

    # Mutable: dict items are modified after construction.
    __hash__ = dict.__hash__

    def update(self, new_dict):
        family = new_dict.get(ACSS.FAMILY)
        if isinstance(family, dict) and family.get("name") is None:
            new_dict.pop(ACSS.FAMILY)

        return super().update(new_dict)
