
    Ii([                         d Z ddlZddlZddlmZ ej
                  j                  d e ee      j                  j                               ddl
mZ ddlmZ ddlmZmZmZ  G d dej$                        Zy)	zLogin dialog for Play Palace client.

Uses a hierarchical TreeCtrl to display servers and their accounts,
making the ownership relationship clear to screen reader users.
    N)Path)ConfigManager)ManagedTreeCtrl)ConfigSharingDialogtry_load_export_fileformat_export_timestampc                        e Zd ZdZd fd	Zd ZddZd Zd Zd Z	d Z
ed	        Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )LoginDialogz?Login dialog with a server/account tree and management buttons.c                    t         |   |dd       t               | _        d| _        t               | _        d| _        d| _        d| _	        d| _
        d| _        d| _        | j                          | j                          y)zInitialize the login dialog.zPlay Palace Login)i  i  )titlesize NF)super__init__r   config_managerusernamestruser_input_valuerefresh_tokenrefresh_expires_at	server_id
account_id
server_url_populating
_create_uiCenterOnScreen)selfparent	__class__s     >C:\Users\dbart\PlayPalace11\clients\desktop\ui\login_dialog.pyr   zLoginDialog.__init__   sx    ':L ,o #!"&     c                 h   t        j                  |       | _        t        j                  t         j                        }t        j
                  | j                  d      }|j                         }|xj                  dz  c_        |j                         }|j                  |       |j                  |dt         j                  t         j                  z  d       t        j
                  | j                  d      }|j                  |dt         j                  t         j                  z  d       t        | j                  t         j                   t         j"                  z  t         j$                  z        | _        |j                  | j&                  dt         j(                  t         j                  z  t         j*                  z  d       t        j                  t         j,                        }t        j.                  | j                  d	      | _        |j                  | j0                  dt         j*                  d
       t        j.                  | j                  d      | _        |j                  | j2                  dt         j*                  d
       t        j.                  | j                  d      | _        |j                  | j4                  d       |j                  |dt         j                  t         j*                  z  t         j                  z  d       t        j                  t         j,                        }t        j.                  | j                  d      | _        |j                  | j6                  dt         j*                  d
       t        j.                  | j                  d      | _        |j                  | j8                  dt         j*                  d
       t        j.                  | j                  d      | _        |j                  | j:                  d       |j                  |dt         j                  t         j*                  z  t         j                  z  d       t        j                  t         j,                        }t        j.                  | j                  t         j<                  d      | _        | j>                  jA                          |j                  | j>                  dt         j*                  d
       t        j.                  | j                  t         jB                  d      }|j                  |d       |j                  |dt         j                  t         j                  z  d       | j                  jE                  |       | j&                  jG                  t         jH                  | jJ                         | j&                  jG                  t         jL                  | jN                         | j0                  jG                  t         jP                  | jR                         | j2                  jG                  t         jP                  | jT                         | j4                  jG                  t         jP                  | jV                         | j6                  jG                  t         jP                  | jX                         | j8                  jG                  t         jP                  | jZ                         | j:                  jG                  t         jP                  | j\                         | j>                  jG                  t         jP                  | j^                         |jG                  t         jP                  | j`                         | jb                  je                         }	d}
|	r| jb                  jg                  |	      }
| ji                  |	|
       | j&                  jk                         jm                         r| j&                  jo                          y| j0                  jo                          y)zCreate the UI components.zPlayPalace 11.)label   r   
   z&Servers and Accounts:)style   zAdd &Server   Add Acco&unt	Re&gister&Edit&Deletez	Ad&vancedz&Loginz&CancelNselect_server_idselect_account_id)8wxPanelpanelBoxSizerVERTICAL
StaticTextGetFont	PointSizeBoldSetFontAddALLCENTERLEFTTOPr   TR_HAS_BUTTONS	TR_SINGLETR_HIDE_ROOTtreeEXPANDRIGHT
HORIZONTALButtonadd_server_btnadd_account_btnregister_btnedit_btn
delete_btnadvanced_btnID_OK	login_btn
SetDefault	ID_CANCELSetSizerBindEVT_TREE_SEL_CHANGED_on_tree_sel_changedEVT_TREE_ITEM_ACTIVATED_on_tree_item_activated
EVT_BUTTONon_add_serveron_add_accounton_registeron_edit	on_deleteon_advancedon_login	on_cancelr   get_last_server_idget_last_account_id_populate_treeGetSelectionIsOkSetFocus)r   sizerr   
title_font
tree_label	add_sizer
item_sizeraction_sizer
cancel_btnlast_serverlast_accounts              r    r   zLoginDialog._create_ui.   s   XXd^
BKK( djj0@A]]_
!__&
j!		%BFFRYY.3 ]]4::5MN
		*a266!126 $JJ##bll2R__D
	 			$))Q		BGG 3bhh >C KK.	 ii

-Hd))1bhh:!yy>Jd**Arxx;IIdjjDd''+		)Q"(( 2RVV ;R@ [[/
		$**G<t}}a15))DJJi@t288Q7IIdjjDt((!,		*a288!3bff!<bA {{2==14::rxxB!!#BHHa8YYtzz2<<C
Q'		,266BII#5r: 	

E" 			r..0I0IJ		r1143O3OP  0B0BC!!"--1D1DEr}}d.>.>?2==$,,7R]]DNN;r}}d.>.>?BMM4==9t~~6 ))<<>..BB;OL[LY 99!!#((*II ((*r!   c                    d| _         	 t               }| j                  j                         }|j	                         r| j                  j                  |      \  }}|j	                         r|| j                  j                  |      }|r/| j                  j                  |      r|j                  |d          | j                  j                  ||      \  }}|j	                         r|| j                  j                          | j                  j                  d      }d}	| j                  j                         }
|
j                         D ]e  \  }}|j                  dd      }| j                  j!                  ||      }| j                  j#                  |d|df       | j                  j%                  |      }|j                         D ]`  \  }}|j                  dd	      }| j                  j!                  ||      }| j                  j#                  |d
||f       ||k(  sY||k(  s_|}	b ||v xs ||k(  }|r:| j                  j'                  |d      dkD  r| j                  j)                  |       ||k(  s0|	4| j                  j                  |      \  }}|j	                         r|n|}	h |	|| j                  j                  |      \  }}|j	                         rN| j                  j                  |      \  }}|j	                         r| j                  j)                  |       |}	n|}	|	r| j                  j+                  |	       d| _         | j-                          y# d| _         w xY w)zRebuild the tree from config, preserving expand state where possible.

        Args:
            select_server_id: Server to select (or expand if selecting an account).
            select_account_id: Account to select within select_server_id.
        Tr'   r   NnamezUnknown Serverserverr   UnknownaccountFr   )r   setrB   GetRootItemrd   GetFirstChildGetItemData
IsExpandedaddGetNextChildDeleteAllItemsAddRootr   get_all_serversitemsget
AppendItemSetItemDataget_server_accountsGetChildrenCountExpand
SelectItem_update_button_states)r   r.   r/   expanded_server_idsrootitemcookiedata	tree_roottarget_itemserversr   rq   server_nameserver_itemaccountsr   rs   r   	acct_itemshould_expandfirst_child_first_serverfirst_accounts                            r    rb   zLoginDialog._populate_tree   s     :	%"%%99((*Dyy{#yy66t<fiik99006D		 4 4T :+//Q8#'99#9#9$#GLD&	 iik II$$&		))"-IK))99;G%,]]_!	6$jj1AB"ii229kJ		%%kHi3NO..BB9M+3>>+;'J&{{:yAH $		 4 4[( KIII)))iJ5WX !$44GX9X&/ ,< !*-@ @ aIQaDa TYY%?%?U%SVW%WII$$[1  00[5H%)YY%<%<[%INK1<1A1A1C+K1 &56 ""&))"9"9)"Da$$&'+yy'>'>|'L$M1$))+		((6&3&2		$$[1$D""$  %Ds-   CM$ 'D8M$  M$ &AM$ 8M$ <CM$ $	M-c                     | j                   j                         }|j                         sy| j                   j                  |      }|sy|S )zGet data for the currently selected tree item.

        Returns:
            Tuple of (item_type, server_id, account_id) or (None, None, None).
        )NNN)rB   rc   rd   rw   )r   selr   s      r    _get_selected_item_dataz#LoginDialog._get_selected_item_data   sA     ii$$&xxz%yy$$S)%r!   c                 .    | j                         \  }}}|S )zBGet the server_id for the current selection, walking up if needed.)r   )r   	item_typer   r   s       r    _get_server_id_for_selectionz(LoginDialog._get_server_id_for_selection   s    "&">">"@	9ar!   c                 v   | j                   j                         }|j                         sy| j                   j                  |      }|sy|d   }|dk(  r| j                   j	                  |      S |dk(  rF| j                   j                  |      }|j                         r| j                   j	                  |      S y)z6Get the server display name for the current selection.r   r   rq   rs   )rB   rc   rd   rw   GetItemTextGetItemParent)r   r   r   r   r   s        r    _get_server_name_for_selectionz*LoginDialog._get_server_name_for_selection   s    ii$$&xxzyy$$S)G	 99((--)#YY,,S1F{{}yy,,V44r!   c                 F   | j                         \  }}}| j                         }|dk(  r| j                  | j                  d       | j                  | j                  d       | j                  | j
                  d|        | j                  | j                  d|        | j                  j                  d       | j                  j                  d       | j
                  j                  d       | j                  j                  d       | j                  j                  d       y|dk(  r| j                  | j                  d	       | j                  | j                  d
       | j                  | j
                  d|        | j                  | j                  d|        | j                  j                  d       | j                  j                  d       | j
                  j                  d       | j                  j                  d       | j                  j                  d       y| j                  | j                  d       | j                  | j                  d       | j                  | j
                  d       | j                  | j                  d       | j                  j                  d       | j                  j                  d       | j
                  j                  d       | j                  j                  d       | j                  j                  d       y)z?Update button labels and enabled state based on tree selection.rq   z&Edit Serverz&Delete ServerzAdd Acco&unt to zRe&gister on TFrs   z&Edit Accountz&Delete Accountr+   r,   r)   r*   N)	r   r   
_set_labelrJ   rK   rH   rI   EnablerN   )r   r   r   r   r   s        r    r   z!LoginDialog._update_button_states   sS   +/+G+G+I(	9j99; OODMM>:OODOO-=>OOD004D[M2RSOOD--{m/LMMM  &OO""4(  ''-$$T*NN!!%()#OODMM?;OODOO->?OOD004D[M2RSOOD--{m/LMMM  &OO""4(  ''-$$T*NN!!$'OODMM73OODOOY7OOD00.AOOD--{;MM  'OO""5)  ''.$$U+NN!!%(r!   c                 N    | j                         |k7  r| j                  |       yy)zSSet button label only if it changed (avoids redundant screen reader announcements).N)GetLabelSetLabel)btnr#   s     r    r   zLoginDialog._set_label!  s#     <<>U"LL #r!   c                 ^    |j                          | j                  s| j                          yy)zHandle tree selection change.N)Skipr   r   r   events     r    rT   z LoginDialog._on_tree_sel_changed+  s%    

&&(  r!   c                 X   |j                         }|j                         sy| j                  j                  |      }|r|d   dk(  r| j	                  |       y| j                  j                  |      r| j                  j                  |       y| j                  j                  |       y)z'Handle Enter/double-click on tree item.Nr   rs   )GetItemrd   rB   rw   r^   rx   Collapser   )r   r   r   r   s       r    rV   z#LoginDialog._on_tree_item_activated1  s    }}yy{yy$$T*DGy(MM%  yy##D)		""4(		  &r!   c                     ddl m}  || | j                        }|j                          |j	                         }|j                          | j                  |       | j                  j                          y)z.Open the server editor to create a new server.r'   ServerEditorDialogr.   N)	server_managerr   r   	ShowModalget_server_idDestroyrb   rB   re   )r   r   r   dlgnew_server_ids        r    rX   zLoginDialog.on_add_server@  sX    6 t':':;))+];		r!   c                    ddl m} | j                         }|s7t        j                  ddt        j
                  t        j                  z         y| j                         } || | j                  |d|      }|j                          |j                         }|j                          | j                  ||       | j                  j                          y)zGOpen the account editor to create a new account on the selected server.r'   AccountEditorDialogPlease select a server first.No Server SelectedN)r   r   r-   )r   r   r   r0   
MessageBoxOKICON_WARNINGr   r   r   get_account_idr   rb   rB   re   )r   r   r   r   r   r   new_account_ids          r    rY   zLoginDialog.on_add_accountK  s    7557	MM/1EruurG^ 99;!$%%yT{
 	++-Y.Y		r!   c                 Z   | j                         }|s7t        j                  ddt        j                  t        j                  z         y| j
                  j                  |      }|s7t        j                  ddt        j                  t        j                  z         yddlm	}  || ||| j
                        }|j                         }|j                         }|j                          |t        j                  k(  r|r| j                  ||	       | j                  j!                          y)
z5Open the registration dialog for the selected server.r   r   NzCould not determine server URL.Errorr'   )RegistrationDialog)r   r   r-   )r   r0   r   r   r   r   get_server_url
ICON_ERRORregistration_dialogr   r   get_registered_account_idr   rM   rb   rB   re   )r   r   r   r   r   r   resultregistered_account_ids           r    rZ   zLoginDialog.on_register`  s    557	MM/1EruurG^ ((77	B
MM;WbeebmmF[\; zYW[WjWjk # = = ?RXX"7Ncd		r!   c                    | j                         \  }}}|dk(  rMddlm}  || | j                  |      }|j	                          |j                          | j                  |       ne|dk(  r`ddlm} | j                         } || | j                  |||      }|j	                          |j                          | j                  ||       | j                  j                          y	)
z$Edit the selected server or account.rq   r'   r   r   rs   r   )r   r-   N)r   r   r   r   r   r   rb   r   r   rB   re   )	r   r   r   r   r   r   r   r   r   s	            r    r[   zLoginDialog.on_edity  s    +/+G+G+I(	9j :$T4+>+>	JCMMOKKM;)#;==?K%d))9jkC MMOKKMjY		r!   c                 f   | j                         \  }}}| j                  j                         }|dk(  r| j                  j                  |      }t	        j
                  d| ddt        j                  t        j                  z  t        j                  z        }|t        j                  k(  r| j                  j                  |       | j                          n|dk(  r| j                         }| j                  j                  |      }t	        j
                  d| d| ddt        j                  t        j                  z  t        j                  z        }|t        j                  k(  r.| j                  j                  ||       | j                  |	       | j                  j                          y
)z&Delete the selected server or account.rq   zDelete server 'z' and all its accounts?zConfirm Deleters   zDelete account 'z' from ?r   N)r   rB   rc   r   r0   r   YES_NO
NO_DEFAULTr   YESr   delete_serverrb   r   delete_accountre   )	r   r   r   r   r   r   r   r   r   s	            r    r\   zLoginDialog.on_delete  sU   +/+G+G+I(	9jii$$& ))//4K]]!+.EF 		BMM)BOO;F
 ##11)<##%)#==?Kyy,,S1H]]"8*GK=B 		BMM)BOO;F
 ##229jI##Y#?		r!   c                 Z   t        j                         }t        j                         }t        j                         }t        j                         }|j                  |d       |j                  |d       |j                  |d       |j	                  t         j
                  | j                  |       |j	                  t         j
                  | j                  |       |j	                  t         j
                  | j                  |       | j                  |       |j                          y)zEShow advanced options menu (import, export, default options profile).z&Import Server ProfileszE&xport Server ProfileszDefault &Options Profile)idN)r0   MenuNewIdRefAppendrR   EVT_MENU_on_import_profiles_on_export_profiles_on_default_options_profile	PopupMenur   )r   r   menu	import_id	export_id
options_ids         r    r]   zLoginDialog.on_advanced  s    wwyKKM	KKM	[[]
I89I89J :;		"++t77I	F		"++t77I	F		"++t??J	Otr!   c                    | j                         }|yt        | | j                  t        j                  |      }|j                  rG|j                          t        j                  ddt        j                  t        j                  z         y|j                         }|j                          |t        j                  k(  r| j                          yy)zHandle import server profiles.N)imported_dataz{There is no data to import. All servers in this file either already exist with no changes, or the file contains no servers.zNothing to Import)_load_import_filer   r   MODE_IMPORT_no_datar   r0   r   r   ICON_INFORMATIONr   rM   rb   )r   r   r   r   r   s        r    r   zLoginDialog._on_import_profiles  s    ..0 !++'	
 <<KKMMMJ#+++	 RXX! r!   c                 4   | j                   j                         }|s7t        j                  ddt        j                  t        j
                  z         yt        | | j                   t        j                        }|j                          |j                          y)zHandle export server profiles.zNo servers to export.ExportN)
r   r}   r0   r   r   r   r   MODE_EXPORTr   r   )r   r   r   r   s       r    r   zLoginDialog._on_export_profiles  so    %%557MM'+++
 !$(;(;=P=\=\]r!   c                 p    t        j                  ddt         j                  t         j                  z         y)zHandle default options profile.zNot implemented yet.zDefault Options ProfileN)r0   r   r   r   r   s     r    r   z'LoginDialog._on_default_options_profile  s&    
"%EEB'''	
r!   c                 R   t        j                         dz  }|j                         rt        t	        |            }|r|j                  dd      }t        |j                  dd            }t        j                  d| d| dd	t        j                  t        j                  z        }|t        j                  k(  r|S 	 t        j                  | d
t	        t        j                               dt        j                  t        j                  z        }|j                         t        j                   k7  r|j#                          y|j%                         }|j#                          t        |      }|7t        j                  ddt        j&                  t        j(                  z         |j                  dd      }t        |j                  dd            }t        j                  d| d| ddt        j                  t        j                  z        }|t        j                  k(  r|S k)zLoad an import file, with auto-detection and browser fallback.

        Returns:
            Parsed dict if a valid file was loaded, or None to abort.
        zidentities-export.jsondescriptionr   	timestampr   z6Found export file in current directory.

Description: z
Date: z#

Would you like to load this file?zImport Server ProfileszSelect Export File to ImportzJSON files (*.json)|*.json)
defaultDirwildcardr&   Nz-The selected file is not a valid export file.zInvalid FilezDescription: z%

Would you like to import this file?zConfirm Import File)r   cwdexistsr   r   r   r   r0   r   r   ICON_QUESTIONr   
FileDialogFD_OPENFD_FILE_MUST_EXISTr   rM   r   GetPathr   r   )r   	auto_pathr   desctsr   file_dlgchosen_paths           r    r   zLoginDialog._load_import_file  s    HHJ!99	 'I7Dxxr2,TXXk1-EF$$(6 *D !89 -II 0 00 RVV#K }}.txxz?5jj2#8#88H !!#rxx/  ""**,K'4D|C"EEBMM)
  88M2.D(+q)ABB]]vXbT1XY%		B,,,F
 A r!   c                    | j                         \  }}}|dk7  s|r|sQt        j                  ddt        j                  t        j                  z         | j
                  j                          y| j                  j                  ||      }|s7t        j                  ddt        j                  t        j                  z         y|| _	        || _
        |j                  dd      | _        |j                  dd      | _        |j                  d	      | _        |j                  d
      | _        | j                  j!                  |      | _        | j                  j%                  ||       | j'                  t        j(                         y)z0Handle login button click or account activation.rs   zPlease select an account.r   NzAccount not found.r   r   passwordr   r   )r   r0   r   r   r   rB   re   r   get_account_by_idr   r   r   r   r   r   r   r   r   set_last_accountEndModalrM   )r   r   r   r   r   rs   s         r    r^   zLoginDialog.on_login1  s(   +/+G+G+I(	9j	!*MM5w@UVII  %%77	:NMM.9NO"$J3 'J ;$[[9")++.B"C--<<YG 	,,Y
Cbhhr!   c                 B    | j                  t        j                         y)zHandle cancel button click.N)r  r0   rP   r   s     r    r_   zLoginDialog.on_cancelM  s    bll#r!   c           	          | j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  dS )zGet the login credentials.)r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r   s    r    get_credentialszLoginDialog.get_credentialsQ  sN     --!//"&"9"9////"11	
 		
r!   )N)NN)__name__
__module____qualname____doc__r   r   rb   r   r   r   r   staticmethodr   rT   rV   rX   rY   rZ   r[   r\   r]   r   r   r   r   r^   r_   r  __classcell__)r   s   @r    r
   r
      s    I*W+zD%T
*")H    )'	*20<$"8
:z 8$
r!   r
   )r	  r0   syspathlibr   pathinsertr   __file__r   r   r   ui.enhance_wx.tree_selectionr   ui.config_sharingr   r   r   Dialogr
    r!   r    <module>r     s`    
 
  3tH~,,334 5 ( 8 F	
")) F	
r!   