#!/usr/bin/python3 

##################################################################################
##################################################################################


import gi
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit2', '4.1')
from gi.repository import GObject, Gtk, Gdk, WebKit2, GLib
import os, sys, re
import json
from time import sleep
import subprocess

import configparser



class Accept(object):

    window = None
    view = None
    timeout_started = False
    activity_check_id = None

    def __init__(self):

        main_loop = GLib.MainLoop()


        display = Gdk.Display.get_default()
        monitor = display.get_primary_monitor()
        geometry = monitor.get_geometry()
        screen_width = geometry.width
        screen_height = geometry.height


        self.window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        self.window.connect("destroy", Gtk.main_quit)
        self.window.app_paintable = True
        self.window.set_default_size(screen_width, screen_height)


	#this line changes to scrollbar enabled window
        self.scrolled_window = Gtk.ScrolledWindow()
        #default# self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC,Gtk.PolicyType.AUTOMATIC) 


        #self.window.realize()
        self.window.fullscreen()
        #self.window.activate_focus()
        #self.window.present()

        self.view = WebKit2.WebView()
        #if there is no window manager there is no default cursor - set LEFT_PTR on realize
        self.view.connect("realize", self.on_webview_realize)
        settings = self.view.get_settings()
        settings.set_property('enable-developer-extras', False);

        accept_url = self.getUrl()
        if ( accept_url == "error" ):
            self.acceptExit(33,"no url specificed in config file")

        '''
        f = open(root_web_dir + "/index.html", 'r')
        self.view.load_html_string(
            f.read(), "file://%s/" % root_web_dir)
        f.close()
        '''

        #self.view.load_uri("file://" + root_web_dir + "/"+theme+"/index.html")
        self.view.load_uri(accept_url);

        #self.view.connect("resource-response-received", self.webkit_response_received_cb)
        #self.view.connect("resource-load-failed", self.webkit_load_failed_cb)
        self.view.connect('load-failed', self.load_error_cb)

        self.view.connect("decide-policy", self.navigation_cb)

        # need to wait until document is loaded before running webkit execute_script call, otherwise we get "ReferenceError: Can't find variable"
        self.view.connect("load-changed", self.webkit_document_load_finished_cb)

        #these 2 lines change to scrollbar enabled window
        self.scrolled_window.add(self.view)
        self.window.add(self.scrolled_window)
	#old non-scrollbar enabled window:
        #self.window.add(self.view)


        self.window.show_all()
        
        #key to getting focus so blinking cursors appear without clicking somewhere first in lightdm
        self.window.present()


        #can't do this too quick, must wait until webkit initialized, otherwise we get: "ReferenceError: Can't find variable" during execute_script call
        #self.init_timer_value=100
        #self.greeter.timeout_id=GObject.timeout_add(self.init_timer_value, self.get_pacrez_status, False ) 

        self.timeOut=self.getTimeout()
        self.startTimeoutAfterActivity=self.getStartTimeoutAfterActivity()
        
        #self.greeter.timeout_id=GObject.timeout_add(self.repeat_timer_value, self.get_pacrez_status, True ) 
        if (self.timeOut > 0 ):
            if (self.startTimeoutAfterActivity):
                # Don't start timeout immediately, wait for X activity first
                self.log("Waiting for X activity before starting timeout")
                # Check for activity every second
                self.activity_check_id = GObject.timeout_add(1000, self.checkForActivity)
            else:
                # Start timeout immediately (original behavior)
                #wrong# self.greeter.timeout_id=GObject.timeout_add(self.timeOut, self.acceptExit(34,"timeout reached")) 
                self.timeout_id=GObject.timeout_add(self.timeOut, self.acceptExit,34,"timeout reached") 


        main_loop.run()

    def checkForActivity(self):
        """Check if there has been X activity and start the timeout if so"""
        try:
            result = subprocess.run(['/usr/bin/groovix-xserver-inactivity-time'], 
                                    capture_output=True, text=True, timeout=1)
            inactivity_ms = int(result.stdout.strip())
            
            # If inactivity time is low (less than 1 second), it means there was recent activity
            if inactivity_ms < 1000:
                if not self.timeout_started:
                    self.log(f"X activity detected (inactivity: {inactivity_ms}ms), starting timeout")
                    self.timeout_started = True
                    # Start the actual timeout now
                    self.timeout_id = GObject.timeout_add(self.timeOut, self.acceptExit, 34, "timeout reached")
                    # Stop checking for activity
                    return False
            
            # Continue checking
            return True
            
        except Exception as e:
            self.log(f"Error checking for activity: {e}")
            # On error, start the timeout anyway to avoid hanging
            if not self.timeout_started:
                self.log("Error checking activity, starting timeout anyway")
                self.timeout_started = True
                self.timeout_id = GObject.timeout_add(self.timeOut, self.acceptExit, 34, "timeout reached")
            return False

    def acceptExit(self,code,message):
         self.log("exiting: "+message);
         exit(code)
         #Gtk.main_quit

    def getTimeout(self):
        try:
            config=configparser.ConfigParser()
            config.read("/etc/groovix/accept.conf")
            timeout=config.getint('accept','timeout')
            return timeout

        except:
            pass
    
        return 0;

    def getStartTimeoutAfterActivity(self):
        try:
            config=configparser.ConfigParser()
            config.read("/etc/groovix/accept.conf")
            start_timeout_after_activity=config.getboolean('accept','start-timeout-after-x-activity')
            return start_timeout_after_activity

        except:
            pass
    
        return False;

    def getUrl(self):
        try:
            config=configparser.ConfigParser()
            config.read("/etc/groovix/accept.conf")
            acceptUrl=config.get('accept','mainurl')
            return acceptUrl

        except:
            pass
    
        return ("error");


    def webkit_document_load_finished_cb(self, web_view, load_event):
            if load_event == WebKit2.LoadEvent.FINISHED:
                # WebKit2 doesn't provide direct access to network response in load-changed
                # This functionality would need to be implemented differently in WebKit2
                self.log("Document load finished")

            #if message:
            #    print ('message method:' + str(message.props.method))
            #    print ('message uri:' + str(message.props.uri))
            #    print ('message http_version:' + str(message.props.http_version))
            #    print ('message flags:' + str(message.props.flags))
            #    print ('message server_side:' + str(message.props.server_side))
            #    print ('message status_code:' + str(message.props.status_code))
            #    print ('message reason_phrase:' + str(message.props.reason_phrase))
            #    print ('message first_party:' + str(message.props.first_party))
            #    print ('message request_body:' + str(message.props.request_body))
            #    print ('message request_headers:' + str(message.props.request_headers))
            #    print ('message tls_certificate:' + str(message.props.tls_certificate))
            #    print ('message tls_errors:' + str(message.props.tls_errors))

       

    # left in here to show example of how to execute javascript from python
    def show_message_cb(self, greeter, text, type):
        self.log("show_message_cb "+text)
        self.view.run_javascript("show_message(%s);" % json.dumps(text))


    #def webkit_load_failed_cb(self, view, frame, resource, error, data=None):
    #    self.log("error is "+str(error))

    #def webkit_response_received_cb(self, view, frame, resource, response, data=None):
    #    self.log("response is "+str(self.webkit_network_response_get_message(response)))

    def load_error_cb(self, web_view, load_event, failing_uri, error):
            self.log ('ERROR LOADING URL: '+ str(error))
            self.acceptExit(22,str(error) );

    def navigation_cb(self, web_view, decision, decision_type):
        if decision_type == WebKit2.PolicyDecisionType.NAVIGATION_ACTION:
            uri = decision.get_request().get_uri()
            scheme, path=uri.split(':', 1)
            if scheme == 'gaccept':
                answer=path
                self.log("accept answer is %s" % answer)
                if answer=="yes":
                    self.acceptExit(0,"accepted");
                else:
                    self.acceptExit(31,"not accepted");
                decision.ignore()
                return True
            else:
                # means that it is a true navigation request, let it go through
                decision.use()
                return True
        return False

    def on_webview_realize(self, webview):
        gdk_window = webview.get_window()
        if gdk_window:
            cursor = Gdk.Cursor.new_for_display(
                gdk_window.get_display(),
                Gdk.CursorType.LEFT_PTR
            )
            gdk_window.set_cursor(cursor)

    def log(self, text):
        print("groovix-accept-use log: "+text, file=sys.stderr)

    #self.view.connect("context-menu", self.right_click_cb)
    def right_click_cb(self, view, menu, htr, twk, data=None):
            self.log("right click")
            return True



if __name__ == '__main__':
    Accept()
    Gtk.main()


