#!/usr/bin/env python3

from appJar import gui
from datetime import datetime
from time import gmtime, strftime, sleep
import os
from picamera import PiCamera
from time import sleep
from threading import Thread


### Default cam settings
currentRes = (3240,2464)
global picPreview
picPreview = 60
picDuration = 30
picCount = 0
global camOpt


### for low light
camOptions = {'sensor_mode': 3,
              'iso': 800,
              'resolution': (3240, 2464),
              'exposure_mode': 'auto',
              'hflip': False,
              'vflip': True,
              'awb_mode': 'auto',
              'awb_sleep': 3,
              'shutter_speed': 6000000,
              'framerate': 'Fraction(1, 6)'}

camOpt = camOptions
picInterval = 5
maxPics = 5

### Directory to save files into (today's date)
myDate = datetime.today().strftime('%Y%m%d')
global saveLoc
saveLoc = '/home/pi/Desktop/' + str(myDate)
#saveLoc = '/home/karl/Desktop/' + str(myDate)

def prepDir( myDir ):
    # print("prepDir: " + str(myDir))
    global saveLoc
    #saveLoc = '/home/pi/Desktop/' + str(myDate)
    if (os.path.isdir( saveLoc )):
        print("Good Save Directory :" + str(saveLoc))
    else:
        #print("Creating Save Directory")
        os.makedirs(saveLoc)

def updStat():
    global currentRes
    global picPreview
    global picCount
    global camOpt
    currentRes = camOpt['resolution']
    app.setStatusbar("Count: " + str(picCount), 0)
    app.setStatusbar("Preview: " + str(picPreview), 1)
    app.setStatusbar("Camera Res: " + str(currentRes), 2)

def previewPress(btn):
    global picPreview
    global currentRes
    if btn=="10s":
        picPreview = 10; updStat()
    elif btn=="30s":
        picPreview = 30; updStat()
    elif btn=="60s":
        picPreview = 60; updStat()
    elif btn=="120s":
        picPreview = 120; updStat()
    elif btn=="300s":
        picPreview = 300; updStat()
    elif btn=="600s":
        picPreview = 600; updStat()

def takePic(maxP, picInterval):
    global picPreview
    global currentRes
    global camOpt
    global saveLoc
    global picCount
    ### Interval
    #picInterval = 2
    camera = PiCamera()
    camera.resolution = camOpt['resolution']
    camera.iso = camOpt['iso']
    camera.awb_mode = camOpt['awb_mode']
    camera.hflip = camOpt['hflip']
    camera.vflip = camOpt['vflip']
    camera.start_preview()
    ### Let the automatic gain controls settle down before fixing them
    sleep(camOpt['awb_sleep'])
    ### Now fix the values to get consistent images (if light levels are consistent)
    camera.shutter_speed = camera.exposure_speed
    camera.exposure_mode = 'off'
    ### Get the automatic white balance gain levels and fix them
    g = camera.awb_gains
    camera.awb_mode = 'off'
    camera.awb_gains = g
    camera.stop_preview()
    ### pic counter starts at 1
    n = 1
    os.chdir(saveLoc)
    picCount = 0
    updStat()
    for filename in camera.capture_continuous('img_{timestamp:%Y%m%d_%H%M%S}.jpg', format='jpeg', quality=100):
    #for filename in camera.capture_continuous(str('fname'), format='jpeg', quality=100):
        # print('Captured %s' % filename)
        # print("N = ", str(n))
        picCount = picCount + 1
        print("picCount: " + str(picCount))
        updStat()
        if (n >= maxP):
            break
        n = n + 1
        ### Takes about 1 second to snap a pic, so building that into interval estimation
        sleep(picInterval - 1)
    picCount = 0
    camera.close()
    #updStat()


### Prepare the UI
def press(btn):
    global picPreview
    global currentRes
    global camOpt
    if btn == "Cancel":
        app.stop()
    elif btn == "Preview":
        ### Create a thread for the preview mode so the UI works behind it.
        #print("pre picPreview" + str(picPreview))
        myPreview = myPreviewThread(camOpt, picPreview)
        myPreview.start()
    elif btn == "Capture 1":
        takePic(2, 1)
    elif btn == "Capture 12 at 5s":
        takePic(12, 5)
    elif btn == "Capture 6 at 20s":
        takePic(6, 20)
    elif btn == "Stop Preview":
        myPreview.signal = False

### Update the value of preview by checking the value of preview
### menu whenever it changes
def updPrev( toss ):
    preview = app.getMenuRadioButton("Preview", str(toss) )
    previewPress( preview )

def updScreen(toss):
    scrn = app.getMenuRadioButton("Screen", str(toss))
    if (scrn == "FullmyPreviewThread"):
        app.setGeometry("fullscreen")
    elif (scrn == "Window"):
        app.exitFullscreen()

class myPreviewThread(Thread):
    def __init__(self, camOpt, picPreview):
        Thread.__init__(self)
        #print("Thread Init")
        self.signal = True
        camOpt = camOpt
        picPreview = picPreview
    def run(self):
        #print("Preview Thread Starting")
        camera = PiCamera()
        camera.resolution = camOpt['resolution']
        #print("Camera resolution = ", str(camOpt['resolution']))
        camera.iso = camOpt['iso']
        camera.awb_mode = camOpt['awb_mode']
        camera.hflip = camOpt['hflip']
        camera.vflip = camOpt['vflip']
        ### Start the preview and let it run for the length of picPreview
        camera.start_preview()
        n=1
        while self.signal:
            while (n < picPreview):
                sleep(1)
                n = n+1
            self.signal = False
        camera.stop_preview()
        camera.close()


### Row number (I got tired of moving things around and
### having to renumber the entries
r = 0
### Create the gui
app = gui("Karl's PiKam","500x380")
#app = gui("Karl's PiKam")
app.setGeometry("fullscreen")
app.setPadX(5)
app.setPadY(3)
app.setFont(10)
### Add a status bar at the bottom and set width of each field
app.addStatusbar(fields=3)
app.setStatusbarWidth(width=12,field=0)
app.setStatusbarWidth(width=13,field=1)
app.setStatusbarWidth(width=25,field=2)

### Fullscreen Toggle
app.createMenu("Screen")
app.addMenuRadioButton("Screen", "screen", "Full", updScreen)
app.addMenuRadioButton("Screen", "screen", "Window", updScreen)
app.setMenuRadioButton("Screen", "screen", "Full")

updStat()

### Interval menu (default to 10seconds)
app.createMenu("Preview")
app.addMenuRadioButton("Preview", "preview", "10s", updPrev)
app.addMenuRadioButton("Preview", "preview", "30s", updPrev)
app.addMenuRadioButton("Preview", "preview", "60s", updPrev)
app.addMenuRadioButton("Preview", "preview", "120s", updPrev)
app.addMenuRadioButton("Preview", "preview", "300s", updPrev)
app.addMenuRadioButton("Preview", "preview", "600s", updPrev)
app.setMenuRadioButton("Preview", "preview", "60s")

### Shutdown
app.addButtons(["Preview","Stop Preview"], press, 6, 0)
app.addButtons(["Capture 1"], press, 7, 0)
app.addButtons(["Capture 12 at 5s","Capture 6 at 20s"], press, 8, 0)
app.addButtons(["Cancel"], press, 9, 0)

### Run the UI
prepDir(saveLoc)
app.go()
