#/******************************************************************************
#*                       qt-recordMyDesktop                                    *
#*******************************************************************************
#*                                                                             *
#*           Copyright (C) 2007, 2008  John Varouhakis                         *
#*                                                                             *
#*                                                                             *
#*   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 3 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, see <http://www.gnu.org/licenses/>.     *
#*                                                                             *
#*                                                                             *
#*  For further information contact me at johnvarouhakis@gmail.com             *
#******************************************************************************/


from PyQt4 import QtGui,QtCore
import locale, gettext
import rmdConfig
import re

def _(s):
    return QtCore.QString.fromUtf8(gettext.gettext(s))
gettext.textdomain('qt-recordMyDesktop')
gettext.bindtextdomain('qt-recordMyDesktop',rmdConfig.locale_install_dir)

import rmdTrayPopup as iTP
import rmdMonitor as imon
import os,signal,popen2,fcntl
from rmdStrings import *
#values struct:

#0   fps
#1   mouse
#2   sound on/off
#3   full
#4   path
#5   area
#6   delay
#7   channels
#8   frequency
#9   device
#10  v_quality
#11  s_quality
#12  display
#13  shared memory
#14  drop-frames
#15  shared threshold
#16  quick subsampling


class trayIcon(object):
    state=0#0 stopped,1 recording,2 paused
    rmdPid=None
    optionsOpen=[1]
    reopen=0
    timed_id=None

    def __set_icon__(self,widget,icon):
            widget.setIcon(QtGui.QIcon(self.__get_icon_location__(icon)))


    def __buttonPress__(self,ActivationReason):

        button=0
        if  ActivationReason==QtGui.QSystemTrayIcon.Trigger:
            button=1
        elif ActivationReason==QtGui.QSystemTrayIcon.Context:
            button=3
        #print button
        if button==1 and self.state>=0:
            if self.state == 0:
                if self.optionsOpen[0]==1:
                    self.parent.hide()
                    self.optionsOpen[0]=0
                    self.reopen=1
                self.__set_icon__(self.trayIcon,"stop")
                self.state=1
                self.__execRMD__()
            elif self.state== 1:
                self.__set_icon__(self.trayIcon,"start")
                self.state=0
                self.__stopRMD__()
            elif self.state == 2 :
                self.__set_icon__(self.trayIcon,"stop")
                self.state=1
                self.__pauseRMD__()


        elif button == 3 and self.state>=0:
            if self.state == 0:
                pass
                self.tray_popup.popupmenu.popup(QtGui.QCursor.pos())
            elif self.state == 1:
                self.__set_icon__(self.trayIcon,"pause")
                self.state=2
                self.__pauseRMD__()
            elif self.state ==2:
                self.__set_icon__(self.trayIcon,"stop")
                self.state=1
                self.__pauseRMD__()
    def record_ext(self,button=None):
        if self.state == 0:
            if self.optionsOpen[0]==1:
                self.parent.hide()
                self.optionsOpen[0]=0
                self.reopen=1
            self.__set_icon__(self.trayIcon,"stop")
            self.state=1
            self.__execRMD__()

    def __execRMD__(self):
        self.parent.close_advanced()
        self.parent.update()
        self.ch_err=""
        self.execargs=["recordmydesktop","-o",'%s'%self.parent.values[4],
                  "--fps","%d"%self.parent.values[0]]
        if self.parent.values[2]==False :
            self.execargs.append("--no-sound")
        if self.parent.values[1] == 1:
            self.execargs.append("--dummy-cursor")
            self.execargs.append("white")
        elif self.parent.values[1] == 2:
            self.execargs.append("--dummy-cursor")
            self.execargs.append("black")
        elif self.parent.values[1] == 3:
            self.execargs.append("--no-cursor")

        if self.parent.values[3] == 0:
            self.execargs.append("--full-shots")
        if self.parent.values[13] == 1:
            self.execargs.append("--no-shared")

        if self.parent.values[15]==1:
            if self.parent.values[5][0]>0  :
                self.execargs.append('-x')
                self.execargs.append('%d'%self.parent.values[5][0])
            if self.parent.values[5][1]>0:
                self.execargs.append('-y')
                self.execargs.append('%d'%self.parent.values[5][1])
        if self.parent.values[5][2]>0 and self.parent.values[5][3]>0:
            self.execargs.append('--width')
            self.execargs.append('%d'%(self.parent.values[5][2]-self.parent.values[5][0]))
            self.execargs.append('--height')
            self.execargs.append('%d'%(self.parent.values[5][3]-self.parent.values[5][1]))
            if(not self.parent.values[14]):
                for i in range(4):
                    self.parent.values[5][i]=-1
        if self.parent.values[6]>0:
            self.execargs.append('--delay')
            self.execargs.append('%d'%self.parent.values[6])
        self.execargs.append('--channels')
        self.execargs.append('%d'%self.parent.values[7])
        self.execargs.append('--freq')
        self.execargs.append('%d'%self.parent.values[8])
        if self.parent.values[9]!='DEFAULT':
            self.execargs.append('--device')
            self.execargs.append('%s'%self.parent.values[9])
        self.execargs.append('--v_quality')
        self.execargs.append('%d'%self.parent.values[10])
        self.execargs.append('--s_quality')
        self.execargs.append('%d'%self.parent.values[11])
        if self.parent.values[12] != "$DISPLAY":
            self.execargs.append('--display')
            self.execargs.append('%s'%self.parent.values[12])
        if self.parent.values[16] == 0:
            self.execargs.append('--quick-subsampling')
        self.execargs.append('--workdir')
        self.execargs.append('%s'%self.parent.values[17])
        if self.parent.values[18] == 0:
            self.execargs.append('--on-the-fly-encoding')
        if self.parent.values[19] == 1:
            self.execargs.append('--compress-cache')
        if self.parent.values[20] == True:
            self.execargs.append('--overwrite')
        if self.parent.values[15] == 0:
            self.execargs.append('--follow-mouse')
        if self.parent.values[22] == True:
            self.execargs.append('--use-jack')
            for i in self.parent.values[23]:
                self.execargs.append(i)
        if self.parent.values[25] == 1:
            self.execargs.append('--no-frame')
        if self.parent.values[26] != "":
            for i in self.parent.values[26].split(" "):
                if i!="":
                    self.execargs.append(i)
        #print execargs



        self.childP=popen2.Popen3(self.execargs,"t",0)
        flags = fcntl.fcntl(self.childP.childerr, fcntl.F_GETFL)
        fcntl.fcntl(self.childP.childerr, fcntl.F_SETFL, flags | os.O_NONBLOCK)
        self.rmdPid=self.childP.pid
        self.timed_id=QtCore.QTimer(None)
        self.timed_id.connect(self.timed_id,QtCore.SIGNAL("timeout()"),
                                self.__check_status__)
        self.timed_id.start(1000)

    def __exit_status_dialog(self,status):
        #first try to write down a log for examination
        try:
            error_log=open(os.path.join(os.getenv("HOME"),"qt-recordMyDesktop-crash.log"),"w")
            error_log.write("#This is the command given at initialization:\n")
            for i in self.execargs:
                error_log.write("%s "%i)
            error_log.write("\n\n\n#recordMyDesktop stderror output:\n")
            error_log.write(self.ch_err)
            try:
                for err_line in self.childP.childerr.readlines():
                    error_log.write(err_line)
            except:
                    error_log.write("Couldn't write stderror of recordMyDesktop!\n")
            self.childP.childerr.close()
        except:
            print "Couldn't write error log.\n"
        self.dialog = QtGui.QWidget()
        self.label1=None
        try:
            self.label1 = QtGui.QLabel("\t\t"+TrayIconStr['RecFinishedKnown'] +
            ": %d\n"%(status) + TrayIconStr['ErrDesc'] + ":" +
            (rmdErrStr[int(status)]) + "\n")
        except:
            self.label1 = QtGui.QLabel("\t\t"+TrayIconStr['RecFinishedUnknown']+": %d \n"%(status))
        self.label1.setAlignment(QtCore.Qt.AlignHCenter)
        self.dialogbutton = QtGui.QPushButton("Ok",self.dialog)
        self.dialogbutton.connect(self.dialogbutton,QtCore.SIGNAL("clicked()"),self.dialog.close )
        self.dialogLayout=QtGui.QVBoxLayout()
        self.dialogLayout.addWidget(self.label1)
        self.dialogLayout.addWidget(self.dialogbutton)

        self.label1.show()
        self.dialogbutton.show()
        self.dialog.setLayout(self.dialogLayout)
        self.dialog.resize(300,128)
        self.dialog.show()

    def __pauseRMD__(self):
        os.kill(self.rmdPid,signal.SIGUSR1)

    def __stopRMD__(self,need_kill=True):
        if self.timed_id!=None:
            self.timed_id.stop()
            self.timed_id=None
        exit_ret=os.waitpid(self.rmdPid,os.WNOHANG)
        if exit_ret[0] == 0:
            if need_kill:
                os.kill(self.rmdPid,signal.SIGTERM)
            self.state=-1
            monitor=imon.rmdMonitor(self.childP.fromchild,self.rmdPid,self.parent)
            monitor.exec_()
            self.state=0
        else:
            self.__exit_status_dialog(exit_ret[1])
            self.parent.show()
        self.rmdPid=None
        if self.reopen==1:
            self.optionsOpen[0]=1
            self.reopen=0

        #print exit_ret
    def __check_status__(self):
        if self.rmdPid!=None:
            exit_ret=os.waitpid(self.rmdPid,os.WNOHANG)
            if exit_ret[0] != 0:
                self.state=0
                self.__set_icon__(self.trayIcon,"start")
                self.__exit_status_dialog(exit_ret[1])
                self.rmdPid=None
                if self.reopen==1:
                    self.parent.show()
                    self.optionsOpen[0]=1
                    self.reopen=0
                self.timed_id.stop()
                return False
            else:
                new_stderr=""
                #try:
                while True:
                    try:
                        err_line=self.childP.childerr.readline()
                        new_stderr+=err_line
                    except:
                        break

                self.ch_err+=new_stderr
                if(self.ch_err.find("STATE:RECORDING")>=0):
                    rp=re.compile("STATE:RECORDING")
                    self.ch_err=rp.sub("",self.ch_err)
                    print "EXTERNAL STATE CHANGE:RECORDING"
                    self.__set_icon__(self.trayIcon,"stop")
                    self.state=1
                elif(self.ch_err.find("STATE:PAUSED")>=0):
                    rp=re.compile("STATE:PAUSED")
                    self.ch_err=rp.sub("",self.ch_err)
                    print "EXTERNAL STATE CHANGE:PAUSED"
                    self.__set_icon__(self.trayIcon,"pause")
                    self.state=2
                elif(self.ch_err.find("STATE:ENCODING")>=0):
                    rp=re.compile("STATE:ENCODING")
                    self.ch_err=rp.sub("",self.ch_err)
                    print "EXTERNAL STATE CHANGE:ENCODING"
                    self.__stopRMD__(False)

                return True

        else:
            self.timed_id.stop()
            return False
    def __get_icon_location__(self,name):
        if name=="start":
            return os.path.join(rmdConfig.pixmapdir,"media-record.svg")
        elif name=="stop":
            return os.path.join(rmdConfig.pixmapdir,"media-playback-stop.svg")
        elif name=="pause":
            return os.path.join(rmdConfig.pixmapdir,"media-playback-pause.svg")

    def __init__(self,parent):
        self.parent=parent
        self.trayIcon=QtGui.QSystemTrayIcon(None)
        self.__set_icon__(self.trayIcon,"start")
        self.tray_popup=iTP.TrayPopupMenu(self.parent,self.parent.values,self.optionsOpen)
        self.trayIcon.connect(self.trayIcon,QtCore.SIGNAL("activated(QSystemTrayIcon::ActivationReason)"),self.__buttonPress__)
        self.trayIcon.show()


if __name__ == "__main__":
    import sys

    app=QtGui.QApplication(sys.argv)
    app.values=rmdConfig.default_values
    w = trayIcon(app)
    app.exec_()