
    Ii~,                        % S r SSKJr  SSKJrJrJr  SSKJr  SSK	J
r
Jr  \(       a    " S S\5      r\ " S S	5      5       rSS
 jr/ SQrS\S'    \ " S S5      5       rg)a  Declarative user preferences for PlayPalace.

Preferences are defined using the same option types as game options
(BoolOption, MenuOption, etc.) with category grouping, per-game overrides,
and auto-serialization.

Usage:
    prefs = UserPreferences()
    prefs.play_turn_sound  # True (default)
    prefs.get_effective("play_turn_sound", game_type="pig")  # per-game or global
    prefs.set_game_override("play_turn_sound", "pig", False)
    )annotations)	dataclassfieldfields)Enum)AnyTYPE_CHECKINGc                  4    \ rS rSrSrSrSr\SS j5       rSr	g)	DiceKeepingStyle   zDice keeping style preference.
playpalace	quentin_cc                L     U " U5      $ ! [          a    U R                  s $ f = f)z1Convert string to enum, defaulting to PLAYPALACE.)
ValueError
PLAYPALACE)clsvalues     <c:\Users\dbart\PlayPalace11\server\core\users\preferences.pyfrom_strDiceKeepingStyle.from_str#   s*    	"u: 	">>!	"s   
 ## N)r   strreturnz'DiceKeepingStyle')
__name__
__module____qualname____firstlineno____doc__r   	QUENTIN_Cclassmethodr   __static_attributes__r       r   r   r      s!    (JI" "r"   r   c                      \ rS rSr% SrS\S'   S\S'   S\S'   SrS\S'   SrS\S	'   S
rS\S'   Sr	S\S'   Sr
S\S'   SrS\S'   Srg)PrefMeta1   a  Metadata for a single preference field.

Attributes:
    category: Category key (e.g. "display", "dice").
    label: Fluent key for menu label (receives $status or $choice).
    change_msg: Fluent key for change announcement.
    description: Fluent key spoken on Space.
    prompt: Fluent key for input prompt (menu options only).
    kind: "bool" or "menu".
    default: Default value.
    choices: For menu prefs, list of (value, fluent_key) tuples.
    enum_class: Optional enum class for type conversion.
r   categorylabel
change_msg descriptionpromptboolkindNr   defaultzlist[tuple[str, str]] | Nonechoicesztype[Enum] | None
enum_classr   )r   r   r   r   r   __annotations__r*   r+   r-   r.   r/   r0   r!   r   r"   r   r$   r$   1   sV     MJOKFCD#GS,0G)0$(J!(r"   r$   c                4    SSK Jn  U" U R                  SU 0S9$ )z2Create a dataclass field with preference metadata.r   )r   	pref_meta)r.   metadata)dataclassesr   r.   )metadc_fields     r   
pref_fieldr8   L   s    -DLLK3FGGr"   ))displayzpref-category-display)soundszpref-category-sounds)gameplayzpref-category-gameplay)dicezpref-category-dicezlist[tuple[str, str]]PREF_CATEGORIESc                     \ rS rSr% Sr\" \" SSSSSSS	95      rS\S
'   \" \" SSSSSSS	95      r	S\S'   \" \" SSSSSSS	95      r
S\S'   \" \" SSSSSSS	95      rS\S'   \" \" SSSSSS\R                  S S!/\S"9	5      rS#\S$'   \" \S%S0S&9rS'\S('   \S7S) j5       r\S8S* j5       r\S9S+ j5       rS:S;S- jjrS<S. jrS=S/ jrS>S0 jrS?S1 jrS@S2 jrSAS3 jrSBS4 jr\SCS5 j5       rS6rg,)DUserPreferencese   zUser preferences that persist across sessions.

Fields are defined in display order within each category.
Metadata on each field drives menu generation and serialization.
r9   zpref-set-brief-announcementsz pref-changed-brief-announcementszpref-desc-brief-announcementsr,   F)r&   r'   r(   r*   r-   r.   brief_announcementsr:   zpref-set-play-turn-soundzpref-changed-play-turn-soundzpref-desc-play-turn-soundTplay_turn_soundr;   z$pref-set-confirm-destructive-actionsz(pref-changed-confirm-destructive-actionsz%pref-desc-confirm-destructive-actionsconfirm_destructive_actionsr<   zpref-set-clear-kept-on-rollzpref-changed-clear-kept-on-rollzpref-desc-clear-kept-on-rollclear_kept_on_rollzpref-set-dice-keeping-stylezpref-changed-dice-keeping-stylezpref-desc-dice-keeping-stylezpref-select-dice-keeping-stylemenu)r   z"pref-dice-keeping-style-playpalace)r   z!pref-dice-keeping-style-quentin_c)	r&   r'   r(   r*   r+   r-   r.   r/   r0   r   dice_keeping_style	skip_pref)default_factoryr4   zdict[str, dict[str, Any]]game_overridesc                    / n[        U 5       H@  nUR                  R                  S5      nUc  M#  UR                  UR                  U45        MB     U$ )zCReturn (field_name, PrefMeta) for every preference field, in order.r3   )r   r4   getappendname)r   resultfr6   s       r   get_pref_fieldsUserPreferences.get_pref_fields   sJ     A::>>+.Dqvvtn-  r"   c                ~    U R                  5        VVs/ s H  u  p#UR                  U:X  d  M  X#4PM     snn$ s  snnf )z@Return pref fields belonging to a category, in definition order.)rP   r&   )r   r&   nms       r   get_fields_for_category'UserPreferences.get_fields_for_category   s8     $'#6#6#8S#841AJJ(<R#8SSSs   99c                    [        U 5       H0  nUR                  U:X  d  M  UR                  R                  S5      s  $    g)z!Get PrefMeta for a field by name.r3   N)r   rM   r4   rK   )r   
field_namerO   s      r   get_pref_metaUserPreferences.get_pref_meta   s6     Avv#zz~~k22  r"   Nc                   U(       az  X R                   ;   ak  U R                   U   nX;   aW  X1   nU R                  U5      nU(       a9  UR                  (       a(  [        U[        5      (       a  UR                  U5      $ U$ U$ [        X5      $ )zGet the effective value of a preference, considering per-game overrides.

If game_type is provided and a per-game override exists, return that.
Otherwise return the global value.
)rI   rY   r0   
isinstancer   getattr)selfrX   	game_type	overridesrawr6   s         r   get_effectiveUserPreferences.get_effective   sy     &9&99++I6I&+))*5DOO3=c33G3G4??3/PSP
t((r"   c                    X R                   ;  a  0 U R                   U'   [        U[        5      (       a  UR                  nX0R                   U   U'   g)zSet a per-game override.N)rI   r\   r   r   )r^   rX   r_   r   s       r   set_game_override!UserPreferences.set_game_override   sG    ///-/D	*eT""KKE5:I&z2r"   c                    X R                   ;   aB  U R                   U   R                  US5        U R                   U   (       d  U R                   U	 ggg)z6Remove a per-game override (revert to global default).N)rI   popr^   rX   r_   s      r   clear_game_override#UserPreferences.clear_game_override   sO    +++	*..z4@&&y1''	2 2 ,r"   c                ^    X R                   ;   a  U R                   U   R                  U5      $ g)z,Get a per-game override, or None if not set.N)rI   rK   ri   s      r   get_game_override!UserPreferences.get_game_override   s-    +++&&y155jAAr"   c                N    X R                   ;   =(       a    XR                   U   ;   $ )z$Check if a per-game override is set.)rI   ri   s      r   has_game_override!UserPreferences.has_game_override   s%    ///`JBUBUV_B`4``r"   c                    U R                  5        H  u  p[        XUR                  5        M     U R                  R	                  5         g)z0Reset all preferences and overrides to defaults.N)rP   setattrr.   rI   clear)r^   rM   r6   s      r   	reset_allUserPreferences.reset_all  s7    ..0JDD- 1!!#r"   c                    U R                  U5       Hy  u  p#[        XUR                  5        [        U R                  5       HE  nU R                  U   R                  US5        U R                  U   (       a  M8  U R                  U	 MG     M{     g)z0Reset all preferences in a category to defaults.N)rU   rs   r.   listrI   rh   )r^   r&   rM   r6   r_   s        r   reset_categoryUserPreferences.reset_category  sw    66x@JDD-!$"5"56	##I.224>**955++I6 7 Ar"   c                    0 nU R                  5        H9  u  p#[        X5      n[        U[        5      (       a  UR                  X'   M5  XAU'   M;     U R
                  (       a  U R
                  US'   U$ )z"Convert to dictionary for storage.rI   )rP   r]   r\   r   r   rI   )r^   rN   rM   r6   r   s        r   to_dictUserPreferences.to_dict  sf    !#..0JDD'E%&&${{$t 1 '+':':F#$r"   c                   0 nU R                  5        HZ  u  p4X1;   d  M  X   nUR                  (       a   UR                  U5      X#'   M7  UR
                  S:X  a  [        U5      X#'   MV  XRU'   M\     U " S0 UD6nSU;   a"  [        US   [        5      (       a
  US   Ul	        U$ ! [        [        4 a    UR                  X#'    M  f = f)zCreate from dictionary.r,   rI   r   )
rP   r0   r   KeyErrorr.   r-   r,   r\   dictrI   )r   datakwargsrM   r6   ra   prefss          r   	from_dictUserPreferences.from_dict#  s     "$--/JD|j??4'+s'; YY&(#'9FL#&4L 0 ft#
48H3I4(P(P#'(8#9E  '1 4'+||4s   B##CCr   )r   list[tuple[str, PrefMeta]])r&   r   r   r   )rX   r   r   zPrefMeta | None)N)rX   r   r_   z
str | Noner   r   )rX   r   r_   r   r   r   r   None)rX   r   r_   r   r   r   )rX   r   r_   r   r   z
Any | None)rX   r   r_   r   r   r,   )r   r   )r&   r   r   r   )r   r   )r   r   r   z'UserPreferences') r   r   r   r   r   r8   r$   rA   r1   rB   rC   rD   r   r   rF   r   r   rI   r    rP   rU   rY   rb   re   rj   rm   rp   ru   ry   r|   r   r!   r   r"   r   r?   r?   e   s    !+097	
	! 	 ',53	
	OT 	 )38A?	
	) 	  */86	
	  	 ,6/863$//DB (	
,( $ 16t$1N-    T T  )";3a$7  r"   r?   N)r6   r$   r   r   )r   
__future__r   r5   r   r   r   enumr   typingr   r	   r   r$   r8   r=   r1   r?   r   r"   r   <module>r      s|    # 0 0  %"t "( ) ) )4H*&  3 Q Q Qr"   