#!/usr/bin/env python
import gtk
import time
import os
import math,getpass,sys

class DateTimeSettings:
    DEF_PAD = 3
    Ybase=100
    Xbase=100
    UPDATE_TIME = True
    NTP_AVAILABLE = False
    ntpservers = ["","",""]
    ntpinterval = ["16 sec","32 sec","64 sec","2 min","4 min","8 min","17 min","34 min","1 hr 8 min","2 hr 27 min","4 hr 55 min","9 hr 10 min","18 hr 20 min","36 hr 40 min"]
    ntpupdate_min = [6,6,6]
    if os.name == "nt":
	ntpconfigfile = "C:\\python24\\pdaxrom\\misc\\ntp.conf"
	ntpdriftfile = "C:\\python24\\pdaxrom\\misc\\ntp.drift"
    else:
	ntpconfigfile = "/etc/ntp.conf"
	ntpdriftfile = "/etc/ntp.drift"

    def make_date_format(self):
        year, month, day = self.window.get_date()
        hours = self.hourspinner.get_value_as_int()
        minutes = self.minspinner.get_value_as_int()
        secs = self.secspinner.get_value_as_int()
        mytime = time.mktime((year, month+1, day, hours, minutes, secs, 0, 0, -1))
        return time.strftime("%m%d%H%M%Y.%S", time.localtime(mytime))

    def stopcounter(self,widget):
    	if self.UPDATE_TIME:
		self.UPDATE_TIME = False
	else:
		self.make_clock()
	return

    def updatentpserver(self,widget,noserver):
    	self.ntpservers[noserver] = widget.get_text()
    	return

    def change_interval(self, combobox,updateitem):
	active = combobox.get_active()
    	self.ntpupdate_min[updateitem] = int(active)+4
	return	

    def close_and_update(self,widget):
        dateset = "/bin/date "+self.make_date_format()
	os.system("/usr/X11R6/bin/xset s off")
	os.system("/usr/X11R6/bin/xset dpms 0 0 0")
	os.system("/usr/X11R6/bin/xset -dpms")
	os.system(dateset)
	os.system("/usr/bin/sethwclock")
	os.system("/sbin/sltime -set")
	os.system("/usr/X11R6/bin/xset s reset") 
	os.system("killall -SIGUSR1 openbox")
	os.system("/usr/X11R6/bin/xrefresh")

	if (self.NTP_AVAILABLE):
		# NTP Time settings
		f=file(self.ntpconfigfile, "w")
		f.write ("#Auto generated file from Zaurus datentime.py script\n\n")
		if os.path.isfile(self.ntpdriftfile):
			f.write ("driftfile " + self.ntpdriftfile + "\n\n")
		i = 0
		while i <= 2:
			if (self.ntpservers[i] != ""):
				f.write ("server " + self.ntpservers[i] + " iburst")
				if (self.ntpupdate_min[i] != ""):
					f.write (" minpoll " + str(self.ntpupdate_min[i]))
				f.write (" maxpoll 17 \n")
			i = i + 1
		f.write ("\nrestrict default kod notrap nomodify nopeer noquery\n")
		f.write ("restrict 127.0.0.1 nomodify\n")
		f.close()
       	gtk.main_quit()
    
    def __init__(self):
	if (getpass.getuser().lower() != "root"):
		Warningdialog = gtk.MessageDialog(None,gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,gtk.MESSAGE_WARNING,gtk.BUTTONS_OK,"You need to be root in order to run this program.")
		Warningdialog.run()
		Warningdialog.destroy()
		sys.exit()
        self.window = None

        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title("Time and Date settings")
        window.set_border_width(5)
	window.set_position(gtk.WIN_POS_CENTER)
        window.connect("destroy", gtk.main_quit)
        window.set_resizable(gtk.FALSE)

        MainBox = gtk.VBox(gtk.FALSE, self.DEF_PAD)
        window.add(MainBox)
        
        if os.path.isfile("/usr/bin/ntpd"):
        	self.NTP_AVAILABLE = True
        
        # hbox is used for the two top frames
       	notebook = gtk.Notebook()
	notebook.set_tab_pos(gtk.POS_TOP)
	notebook.show()
	MainBox.pack_start(notebook, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

	settimeframe = gtk.Frame()
	settimeframe.show()
	
	label = gtk.Label("Date & Time")
	notebook.append_page(settimeframe, label)
     	settimebox = gtk.VBox(gtk.FALSE, self.DEF_PAD)
	settimeframe.add(settimebox)
	self.NTP_AVAILABLE = True
	if (self.NTP_AVAILABLE):
		ntpframe = gtk.Frame()
		ntpframe.show()
		
		label = gtk.Label("Network time")
		notebook.append_page(ntpframe, label)
	     	ntpbox = gtk.VBox(gtk.FALSE, self.DEF_PAD)
		ntpframe.add(ntpbox)
	
	hbox = gtk.HBox(gtk.FALSE, self.DEF_PAD)
	settimebox.pack_start(hbox, gtk.FALSE, gtk.FALSE, self.DEF_PAD)

        # Calendar frame and widgets
        dateframe = gtk.Frame("Date")
        hbox.pack_start(dateframe, gtk.FALSE, gtk.TRUE, self.DEF_PAD)
        calendar = gtk.Calendar()
        self.window = calendar
        calendar.display_options(gtk.CALENDAR_SHOW_HEADING|gtk.CALENDAR_SHOW_DAY_NAMES|gtk.CALENDAR_WEEK_START_MONDAY)
        dateframe.add(calendar)

	# Time frame and widgets
        timeframe = gtk.Frame("Time")
        hbox.pack_start(timeframe, gtk.TRUE, gtk.TRUE, 0)
        vbox3 = gtk.VBox(gtk.FALSE, 0)
        vbox3.set_border_width(5)
        timeframe.add(vbox3)

        # analog clock
        self.area = gtk.DrawingArea()
        self.area.set_size_request(self.Ybase, self.Xbase)
        vbox3.pack_start(self.area, gtk.TRUE, gtk.TRUE, 2)

        # Hours, minutes, seconds spinners
        hbox = gtk.HBox(gtk.FALSE, 0)
        vbox3.pack_start(hbox, gtk.TRUE, gtk.TRUE, self.DEF_PAD)
  
  	# 	Hours
        vbox2 = gtk.VBox(gtk.FALSE, 0)
        hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

        label = gtk.Label("Hours:")
        label.set_alignment(0, 0.5)
        vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)
  
        adj = gtk.Adjustment(int(time.strftime("%H")), 0, 23, 1, 1, 0)
        self.hourspinner = gtk.SpinButton(adj, 0, 0)
        self.hourspinner.set_wrap(gtk.TRUE)
        self.hourspinner.connect("value-changed", self.stopcounter)
        vbox2.pack_start(self.hourspinner, gtk.FALSE, gtk.TRUE, 0)
  
  	# 	Minutes
        vbox2 = gtk.VBox(gtk.FALSE, 0)
        hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, self.DEF_PAD)
  
        label = gtk.Label("Minutes:")
        label.set_alignment(0, 0.5)
        vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)

        adj = gtk.Adjustment(int(time.strftime("%M")), 0, 59, 1, 1, 0)
        self.minspinner = gtk.SpinButton(adj, 0, 0)
        self.minspinner.set_wrap(gtk.TRUE)
        self.minspinner.connect("value-changed", self.stopcounter)
        vbox2.pack_start(self.minspinner, gtk.FALSE, gtk.TRUE, 0)
  
  	# 	Seconds
        vbox2 = gtk.VBox(gtk.FALSE, 0)
        hbox.pack_start(vbox2, gtk.TRUE, gtk.TRUE, self.DEF_PAD)
  
        label = gtk.Label("Seconds:")
        label.set_alignment(0, 0.5)
        vbox2.pack_start(label, gtk.FALSE, gtk.TRUE, 0)
  
        adj = gtk.Adjustment(int(time.strftime("%S")), 0, 59, 1, 1, 0)
        self.secspinner = gtk.SpinButton(adj, 0, 0)
        self.secspinner.set_wrap(gtk.TRUE)
        self.secspinner.connect("value-changed", self.stopcounter)
        vbox2.pack_start(self.secspinner, gtk.FALSE, gtk.TRUE, 0)

	if (self.NTP_AVAILABLE):
		# NTP Time settings
		if os.path.isfile(self.ntpconfigfile):
			f=file(self.ntpconfigfile, "r")
			counter = 0
			for line in f:
				if (line[0:6].lower() == "server"):
					temp = line.split(" ")
					self.ntpservers[counter] = temp[1].strip()
					if (len(temp) >= 5):
						if (temp[3] != "" and temp[3].lower() == "minpoll" and temp[4] != ""):
							self.ntpupdate_min[counter] = temp[4].strip()
					counter = counter+1
				if (counter >= 3):
					break
			f.close()
		else:
			self.ntpservers = ["0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org"]

	     	vbox = gtk.VBox(gtk.FALSE, 0)
		ntpbox.pack_start(vbox, gtk.TRUE, gtk.TRUE, 0)
		
		label = gtk.Label("The Network Time Protocol (NTP) is used\nto synchronizethe time of a computer client\nto anotherserver or reference\ntime source. Below you can configure\nwhich servers you want the NTP system\nto use to synchronize your clock.")
		vbox.pack_start(label, gtk.FALSE, gtk.FALSE, 2)
	
	        hbox = gtk.HBox(gtk.TRUE,0)
	        vbox.pack_start(hbox, gtk.TRUE, gtk.TRUE, 0)
	        label = gtk.Label("Server address")
		hbox.pack_start(label, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

	        label = gtk.Label("Update interval")
		hbox.pack_start(label, gtk.FALSE, gtk.FALSE, 0)	
	# 1
	        hbox = gtk.HBox(gtk.TRUE, self.DEF_PAD)
	        vbox.pack_start(hbox, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

	        ntpserver1 = gtk.Entry(0)
	        ntpserver1.set_text(self.ntpservers[0])
	        ntpserver1.set_size_request(150,30)
	        ntpserver1.connect("changed", self.updatentpserver,0)
	        hbox.pack_start(ntpserver1, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

		min_interval_1 = gtk.combo_box_new_text()
		i = 0
	      	for strtxt in self.ntpinterval:
	        	min_interval_1.append_text(strtxt) 
	        	if (int(self.ntpupdate_min[0]) == int(i+4)):
	        		min_interval_1.set_active(i)
	        	i += 1
	        min_interval_1.connect('changed', self.change_interval,0)
	        min_interval_1.set_size_request(150,30)

		hbox.pack_start(min_interval_1, gtk.TRUE, gtk.TRUE, self.DEF_PAD)


	# 2
	        hbox = gtk.HBox(gtk.TRUE, self.DEF_PAD)
	        vbox.pack_start(hbox, gtk.TRUE, gtk.TRUE, self.DEF_PAD)
	        
	        self.ntpserver2 = gtk.Entry(0)
	        self.ntpserver2.set_text(self.ntpservers[1])
	        self.ntpserver2.set_size_request(150,30)
	        self.ntpserver2.connect("changed", self.updatentpserver,1)
	        hbox.pack_start(self.ntpserver2, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

		min_interval_2 = gtk.combo_box_new_text()
		i = 0
	      	for strtxt in self.ntpinterval:
	        	min_interval_2.append_text(strtxt) 
	        	if (int(self.ntpupdate_min[1]) == int(i+4)):
	        		min_interval_2.set_active(i)
	        	i += 1
	        min_interval_2.connect('changed', self.change_interval,1)
	        min_interval_2.set_size_request(150,30)
		hbox.pack_start(min_interval_2, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

	#3
	        hbox = gtk.HBox(gtk.TRUE, self.DEF_PAD)
	        vbox.pack_start(hbox, gtk.TRUE, gtk.TRUE, self.DEF_PAD)
       
	        self.ntpserver3 = gtk.Entry(0)
	        self.ntpserver3.set_text(self.ntpservers[2])
	        self.ntpserver3.set_size_request(150,30)
	        self.ntpserver3.connect("changed", self.updatentpserver,2)
	        hbox.pack_start(self.ntpserver3, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

		min_interval_3 = gtk.combo_box_new_text()
		i = 0
	      	for strtxt in self.ntpinterval:
	        	min_interval_3.append_text(strtxt) 
	        	if (int(self.ntpupdate_min[2]) == int(i+4)):
	        		min_interval_3.set_active(i)
	        	i += 1
	        min_interval_3.connect('changed', self.change_interval,2)
	        min_interval_3.set_size_request(150,30)
		hbox.pack_start(min_interval_3, gtk.TRUE, gtk.TRUE, self.DEF_PAD)

   	# ok and cancel button
        bbox = gtk.HButtonBox ()
        MainBox.pack_start(bbox, gtk.FALSE, gtk.FALSE, 0)
        bbox.set_layout(gtk.BUTTONBOX_END)

        cancel_button = gtk.Button("Cancel",gtk.STOCK_CANCEL)
        cancel_button.connect("clicked", gtk.main_quit)
        bbox.add(cancel_button)	

        okbutton = gtk.Button("Ok",gtk.STOCK_OK)
        okbutton.connect("clicked", self.close_and_update)
        bbox.add(okbutton)
        okbutton.set_flags(gtk.CAN_DEFAULT)
        okbutton.grab_default()

        # Make dot circle data
    	# i = 0
    	# dots = 12
    	# split = 360/dots
    	# self.dotset = "["
    	# while i < dots:
	#	doty = self.Ybase*math.sin(-1.56 +i*split*math.pi/180)/2
 	#	dotx = self.Xbase*math.cos(-1.56 +i*split*math.pi/180)/2
 	#	self.dotset = self.dotset + "("+str(int(dotx+95))+","+str(int(doty+50))+")"
        #	i = i + 1
        #	if i < dots:
       	#		self.dotset = self.dotset + ","
       	#self.dotset = self.dotset +"]"
        #print self.dotset
     
        # Setup and display
        self.area.connect("expose-event", self.area_expose_cb)
        self.area.show()
        window.show_all()

        #Start clock updater


    def area_expose_cb(self, area, event):
	self.style = self.area.get_style()
	self.gc = self.style.fg_gc[gtk.STATE_NORMAL]
	self.make_clock()
        return gtk.TRUE

    def make_clock(self):  	
    	if self.UPDATE_TIME:
    		sec = -1.57 + math.pi * int(time.strftime("%S"))/30;
    		mins = -1.57 + math.pi * int(time.strftime("%M"))/30;
    		hours = -1.57 + math.pi * int(time.strftime("%H"))/6 + math.pi*int(time.strftime("%M"))/360;
    		self.secspinner.set_value(int(time.strftime("%S")))
    		self.minspinner.set_value(int(time.strftime("%M")))
    		self.hourspinner.set_value(int(time.strftime("%H")))
    		self.UPDATE_TIME = True
	else:
    		sec = -1.57 + math.pi * self.secspinner.get_value_as_int()/30;
    		mins = -1.57 + math.pi * self.minspinner.get_value_as_int()/30;
    		hours = -1.57 + math.pi * self.hourspinner.get_value_as_int()/6 + math.pi*self.minspinner.get_value_as_int()/360;
    		
	# should be replace with area.draw_lines(gc, points) which one need one call
    	self.area.window.clear()
	self.area.window.draw_points(self.gc, [(95,0),(120,6),(138,25),(144,50),(138,75),(119,93),(94,99),(69,93),(51,74),(45,49),(51,24),(70,6)])
    	self.drawclock(sec,1.85)
    	self.drawclock(mins,1.6)
	self.drawclock(hours,1.1)

    def drawclock(self,data,length):
    	y = int(length*self.Ybase/4.1*math.sin(data))
    	x = int(length*self.Xbase/4.1*math.cos(data))
	style = self.area.get_style().copy()
	self.area.set_style(style)
        self.area.window.draw_line(self.gc, self.Xbase/2+45, self.Ybase/2, x+(self.Xbase/2)+45, y+(self.Ybase/2))
	return True

        
def main():
    gtk.main()
    return 0

if __name__ == "__main__":
    DateTimeSettings()
    main()