# $Id: settings.py 4704 2014-01-16 05:30:46Z ming $
#
# pjsua Python GUI Demo
#
# Copyright (C)2013 Teluu Inc. (http://www.teluu.com)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
#
import sys
if sys.version_info[0] >= 3: # Python 3
	import tkinter as tk
	from tkinter import ttk
	from tkinter import messagebox as msgbox
else:
	import Tkinter as tk
	import tkMessageBox as msgbox
	import ttk

import pjsua2 as pj
#import application

# Transport setting
class SipTransportConfig:
	def __init__(self, type, enabled):
		#pj.PersistentObject.__init__(self)
		self.type = type
		self.enabled = enabled
		self.config = pj.TransportConfig()
	def readObject(self, node):
		child_node = node.readContainer("SipTransport")
		self.type = child_node.readInt("type")
		self.enabled = child_node.readBool("enabled")
		self.config.readObject(child_node)
	def writeObject(self, node):
		child_node = node.writeNewContainer("SipTransport")
		child_node.writeInt("type", self.type)
		child_node.writeBool("enabled", self.enabled)
		self.config.writeObject(child_node)

# Account setting with buddy list
class AccConfig:
	def __init__(self):
		self.enabled = True
		self.config = pj.AccountConfig()
		self.buddyConfigs = []
	def readObject(self, node):
		acc_node = node.readContainer("Account")
		self.enabled = acc_node.readBool("enabled")
		self.config.readObject(acc_node)
		buddy_node = acc_node.readArray("buddies")
		while buddy_node.hasUnread():
			buddy_cfg = pj.BuddyConfig()
			buddy_cfg.readObject(buddy_node)
			self.buddyConfigs.append(buddy_cfg)
	def writeObject(self, node):
		acc_node = node.writeNewContainer("Account")
		acc_node.writeBool("enabled", self.enabled)
		self.config.writeObject(acc_node)
		buddy_node = acc_node.writeNewArray("buddies")
		for buddy in self.buddyConfigs:
			buddy_node.writeObject(buddy)

	
# Master settings
class AppConfig:
	def __init__(self):
		self.epConfig = pj.EpConfig()	# pj.EpConfig()
		self.udp = SipTransportConfig(pj.PJSIP_TRANSPORT_UDP, True)
		self.tcp = SipTransportConfig(pj.PJSIP_TRANSPORT_TCP, True)
		self.tls = SipTransportConfig(pj.PJSIP_TRANSPORT_TLS, False)
		self.accounts = []		# Array of AccConfig
		
	def loadFile(self, file):
		json = pj.JsonDocument()
		json.loadFile(file)
		root = json.getRootContainer()
		self.epConfig = pj.EpConfig()
		self.epConfig.readObject(root)
		
		tp_node = root.readArray("transports")
		self.udp.readObject(tp_node)
		self.tcp.readObject(tp_node)
		if tp_node.hasUnread():
			self.tls.readObject(tp_node)
			
		acc_node = root.readArray("accounts")
		while acc_node.hasUnread():
			acfg = AccConfig()
			acfg.readObject(acc_node)
			self.accounts.append(acfg)
			
	def saveFile(self,file):
		json = pj.JsonDocument()
		
		# Write endpoint config
		json.writeObject(self.epConfig)
		
		# Write transport config
		tp_node = json.writeNewArray("transports")
		self.udp.writeObject(tp_node)
		self.tcp.writeObject(tp_node)
		self.tls.writeObject(tp_node)
		
		# Write account configs
		node = json.writeNewArray("accounts")
		for acc in self.accounts:
			acc.writeObject(node)
				
		json.saveFile(file)
		

# Settings dialog
class Dialog(tk.Toplevel):
	"""
	This implements account settings dialog to manipulate account settings.
	"""
	def __init__(self, parent, cfg):
		tk.Toplevel.__init__(self, parent)
		self.transient(parent)
		self.parent = parent
		self.title('Settings')
		
		self.frm = ttk.Frame(self)
		self.frm.pack(expand='yes', fill='both')
		
		self.isOk = False
		self.cfg = cfg
		
		self.createWidgets()
	
	def doModal(self):
		if self.parent:
			self.parent.wait_window(self)
		else:
			self.wait_window(self)
		return self.isOk
		
	def createWidgets(self):
		# The notebook
		self.frm.rowconfigure(0, weight=1)
		self.frm.rowconfigure(1, weight=0)
		self.frm.columnconfigure(0, weight=1)
		self.frm.columnconfigure(1, weight=1)
		self.wTab = ttk.Notebook(self.frm)
		self.wTab.grid(column=0, row=0, columnspan=2, padx=10, pady=10, ipadx=20, ipady=20, sticky=tk.N+tk.S+tk.W+tk.E)
		
		# Main buttons
		btnOk = ttk.Button(self.frm, text='Ok', command=self.onOk)
		btnOk.grid(column=0, row=1, sticky=tk.E, padx=20, pady=10)
		btnCancel = ttk.Button(self.frm, text='Cancel', command=self.onCancel)
		btnCancel.grid(column=1, row=1, sticky=tk.W, padx=20, pady=10)
		
		# Tabs
		self.createBasicTab()
		self.createNetworkTab()
		self.createMediaTab()

	def createBasicTab(self):
		# Prepare the variables to set/receive values from GUI
		self.cfgLogFile = tk.StringVar(value=self.cfg.epConfig.logConfig.filename)
		self.cfgLogAppend = tk.BooleanVar(value=True if (self.cfg.epConfig.logConfig.fileFlags & pj.PJ_O_APPEND) else False)
		
		# Build the tab page
		frm = ttk.Frame(self.frm)
		frm.columnconfigure(0, weight=1)
		frm.columnconfigure(1, weight=2)
		row = 0
		ttk.Label(frm, text='User Agent:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Label(frm, text=self.cfg.epConfig.uaConfig.userAgent).grid(row=row, column=1, sticky=tk.W, pady=2, padx=6)
		row += 1
		ttk.Label(frm, text='Max calls:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Label(frm, text=str(self.cfg.epConfig.uaConfig.maxCalls)).grid(row=row, column=1, sticky=tk.W, pady=2, padx=6)
		row += 1
		ttk.Label(frm, text='Log file:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Entry(frm, textvariable=self.cfgLogFile, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Checkbutton(frm, text='Append log file', variable=self.cfgLogAppend).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)

		self.wTab.add(frm, text='Basic')
		
	def createNetworkTab(self):
		self.cfgNameserver = tk.StringVar()
		if len(self.cfg.epConfig.uaConfig.nameserver):
			self.cfgNameserver.set(self.cfg.epConfig.uaConfig.nameserver[0])
		self.cfgStunServer = tk.StringVar()
		if len(self.cfg.epConfig.uaConfig.stunServer):
			self.cfgStunServer.set(self.cfg.epConfig.uaConfig.stunServer[0])
		self.cfgStunIgnoreError = tk.BooleanVar(value=self.cfg.epConfig.uaConfig.stunIgnoreFailure)
		
		self.cfgUdpEnabled = tk.BooleanVar(value=self.cfg.udp.enabled)
		self.cfgUdpPort = tk.IntVar(value=self.cfg.udp.config.port)
		self.cfgTcpEnabled = tk.BooleanVar(value=self.cfg.tcp.enabled)
		self.cfgTcpPort = tk.IntVar(value=self.cfg.tcp.config.port)
		self.cfgTlsEnabled = tk.BooleanVar(value=self.cfg.tls.enabled)
		self.cfgTlsPort = tk.IntVar(value=self.cfg.tls.config.port)
		
		self.cfgTlsCaFile = tk.StringVar(value=self.cfg.tls.config.tlsConfig.CaListFile)
		self.cfgTlsCertFile = tk.StringVar(value=self.cfg.tls.config.tlsConfig.certFile)
		self.cfgTlsVerifyClient = tk.BooleanVar(value=self.cfg.tls.config.tlsConfig.verifyClient)
		self.cfgTlsVerifyServer = tk.BooleanVar(value=self.cfg.tls.config.tlsConfig.verifyServer)
		
		# Build the tab page
		frm = ttk.Frame(self.frm)
		frm.columnconfigure(0, weight=1)
		frm.columnconfigure(1, weight=2)
		row = 0
		#ttk.Label(frm, text='UDP transport:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Checkbutton(frm, text='Enable UDP transport', variable=self.cfgUdpEnabled).grid(row=row, column=0, sticky=tk.W, padx=6, pady=2)
		row += 1
		ttk.Label(frm, text='UDP port:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgUdpPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
		ttk.Label(frm, text='(0 for any)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
		row += 1
		#ttk.Label(frm, text='TCP transport:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Checkbutton(frm, text='Enable TCP transport', variable=self.cfgTcpEnabled).grid(row=row, column=0, sticky=tk.W, padx=6, pady=2)
		row += 1
		ttk.Label(frm, text='TCP port:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgTcpPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
		ttk.Label(frm, text='(0 for any)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
		row += 1
		#ttk.Label(frm, text='TLS transport:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Checkbutton(frm, text='Enable TLS transport', variable=self.cfgTlsEnabled).grid(row=row, column=0, sticky=tk.W, padx=6, pady=2)
		row += 1
		ttk.Label(frm, text='TLS port:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=0, to=65535, textvariable=self.cfgTlsPort, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
		ttk.Label(frm, text='(0 for any)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
		row += 1
		ttk.Label(frm, text='TLS CA file:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Entry(frm, textvariable=self.cfgTlsCaFile, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Label(frm, text='TLS cert file:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Entry(frm, textvariable=self.cfgTlsCertFile, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Checkbutton(frm, text='TLS verify server', variable=self.cfgTlsVerifyServer).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
		row += 1
		ttk.Checkbutton(frm, text='TLS verify client', variable=self.cfgTlsVerifyClient).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
		row += 1
		ttk.Label(frm, text='DNS and STUN:').grid(row=row, column=0, sticky=tk.W, pady=2, padx=8)
		row += 1
		ttk.Label(frm, text='Nameserver:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Entry(frm, textvariable=self.cfgNameserver, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Label(frm, text='STUN Server:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Entry(frm, textvariable=self.cfgStunServer, width=32).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Checkbutton(frm, text='Ignore STUN failure at startup', variable=self.cfgStunIgnoreError).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
		
		self.wTab.add(frm, text='Network')

	def createMediaTab(self):
		self.cfgClockrate = tk.IntVar(value=self.cfg.epConfig.medConfig.clockRate)
		self.cfgSndClockrate = tk.IntVar(value=self.cfg.epConfig.medConfig.sndClockRate)
		self.cfgAudioPtime = tk.IntVar(value=self.cfg.epConfig.medConfig.audioFramePtime)
		self.cfgMediaQuality = tk.IntVar(value=self.cfg.epConfig.medConfig.quality)
		self.cfgCodecPtime = tk.IntVar(value=self.cfg.epConfig.medConfig.ptime)
		self.cfgVad = tk.BooleanVar(value=not self.cfg.epConfig.medConfig.noVad)
		self.cfgEcTailLen = tk.IntVar(value=self.cfg.epConfig.medConfig.ecTailLen)
		
		# Build the tab page
		frm = ttk.Frame(self.frm)
		frm.columnconfigure(0, weight=1)
		frm.columnconfigure(1, weight=2)
		row = 0
		ttk.Label(frm, text='Max media ports:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Label(frm, text=str(self.cfg.epConfig.medConfig.maxMediaPorts)).grid(row=row, column=1, sticky=tk.W, pady=2, padx=6)
		row += 1
		ttk.Label(frm, text='Core clock rate:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=8000, to=48000, increment=8000, textvariable=self.cfgClockrate, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Label(frm, text='Snd device clock rate:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=0, to=48000, increment=8000, textvariable=self.cfgSndClockrate, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
		ttk.Label(frm, text='(0: follow core)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
		row += 1
		ttk.Label(frm, text='Core ptime:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=10, to=400, increment=10, textvariable=self.cfgAudioPtime, width=3).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Label(frm, text='RTP ptime:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=20, to=400, increment=10, textvariable=self.cfgCodecPtime, width=3).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Label(frm, text='Media quality (1-10):').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=1, to=10, textvariable=self.cfgMediaQuality, width=5).grid(row=row, column=1, sticky=tk.W, padx=6)
		row += 1
		ttk.Label(frm, text='VAD:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		ttk.Checkbutton(frm, text='Enable', variable=self.cfgVad).grid(row=row, column=1, sticky=tk.W, padx=6, pady=2)
		row += 1
		ttk.Label(frm, text='Echo canceller tail length:').grid(row=row, column=0, sticky=tk.E, pady=2, padx=8)
		tk.Spinbox(frm, from_=0, to=400, increment=10, textvariable=self.cfgEcTailLen, width=3).grid(row=row, column=1, sticky=tk.W, padx=6)
		ttk.Label(frm, text='(ms, 0 to disable)').grid(row=row, column=1, sticky=tk.E, pady=6, padx=6)
		
		self.wTab.add(frm, text='Media')

	def onOk(self):
		# Check basic settings
		errors = "";
		if errors:
			msgbox.showerror("Error detected:", errors)
			return
		
		# Basic settings
		self.cfg.epConfig.logConfig.filename = self.cfgLogFile.get()
		flags = pj.PJ_O_APPEND if self.cfgLogAppend.get() else 0
		self.cfg.epConfig.logConfig.fileFlags = self.cfg.epConfig.logConfig.fileFlags | flags 
		
		# Network settings
		self.cfg.epConfig.uaConfig.nameserver.clear()
		if len(self.cfgNameserver.get()): 
			self.cfg.epConfig.uaConfig.nameserver.append(self.cfgNameserver.get())
		self.cfg.epConfig.uaConfig.stunServer.clear()
		if len(self.cfgStunServer.get()):
			self.cfg.epConfig.uaConfig.stunServer.append(self.cfgStunServer.get())
			
		self.cfg.epConfig.uaConfig.stunIgnoreFailure = self.cfgStunIgnoreError.get()
		
		self.cfg.udp.enabled 	= self.cfgUdpEnabled.get()
		self.cfg.udp.config.port = self.cfgUdpPort.get()
		self.cfg.tcp.enabled 	= self.cfgTcpEnabled.get()
		self.cfg.tcp.config.port = self.cfgTcpPort.get()
		self.cfg.tls.enabled 	= self.cfgTlsEnabled.get()
		self.cfg.tls.config.port = self.cfgTlsPort.get()
		
		self.cfg.tls.config.tlsConfig.CaListFile = self.cfgTlsCaFile.get()
		self.cfg.tls.config.tlsConfig.certFile   = self.cfgTlsCertFile.get()
		self.cfg.tls.config.tlsConfig.verifyClient = self.cfgTlsVerifyClient.get()
		self.cfg.tls.config.tlsConfig.verifyServer = self.cfgTlsVerifyServer.get()

		# Media
		self.cfg.epConfig.medConfig.clockRate	= self.cfgClockrate.get()
		self.cfg.epConfig.medConfig.sndClockRate = self.cfgSndClockrate.get()
		self.cfg.epConfig.medConfig.audioFramePtime = self.cfgAudioPtime.get()
		self.cfg.epConfig.medConfig.quality	= self.cfgMediaQuality.get()
		self.cfg.epConfig.medConfig.ptime	= self.cfgCodecPtime.get()
		self.cfg.epConfig.medConfig.noVad	= not self.cfgVad.get()
		self.cfg.epConfig.medConfig.ecTailLen	= self.cfgEcTailLen.get()
		
		self.isOk = True
		self.destroy()
		
	def onCancel(self):
		self.destroy()


if __name__ == '__main__':
	#application.main()
	acfg = AppConfig()
	acfg.loadFile('pygui.js')

	dlg = Dialog(None, acfg)
	if dlg.doModal():
		acfg.saveFile('pygui.js')
		