# Time-stamp: <2002-01-23 19:33:46 crabbkw>
# Code and design by Casey Crabb (crabbkw@rose-hulman.edu)
# This code is licensed under the BSD license.
# See the LICENSE file for details
#
# Copyright Casey Crabb (crabbkw@rose-hulman.edu) July 2001
#

# from __future__ import nested_scopes
from threading import *
import string
import os
import time
import sys

class AutoStatus(Thread):
    def __init__(self, cli, profile ):
        Thread.__init__(self)
        self.cli = cli
        self.profile = profile
        self.colors = self.profile.colors.sessioncolors
        self.idleTime = 0
        # since we don't die 'til up to 60 seconds after
        # everyone else we should run in the background
        self.setDaemon(1)
        self.running = 1
        self.currentStatusType = "auto"


    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # -------------------------------------------------------------------------
    #  API Functions
    # -------------------------------------------------------------------------
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    def setProfile( self, profile ):
        self.profile = profile
        self.colors = self.profile.colors.sessioncolors

    def setParent(self, cli):
        self.cli = cli

    def setIdleTime( self, idle ):
        self.idleTime = idle

    def getIdleTime( self ):
        return self.idleTime

    def statusChange( self, status, statusreason ):
        self.currentStatusType = "manual"

    def kill( self ):
        self.running = 0

    def doAutoStatus( self ):
        if (self.profile.switches["autostatus"][0] != "true" ):
            return

        if self.cli.debug and self.cli.debugdetails["autostatus"]:
            print "idle is " + str( self.idleTime )

        #
        # autoStatusList tuple:
        # [0] = begin time for rule (hour, min) ( -1, -1 means all)
        # [1] = end time for rule (hour, min) (-1, -1 means all)
        # [2] = current status for rule ("all" means all)
        # [3] = current status was set automatically - auto, manual, all
        # [4] = number of minutes idle, treated as = not >=
        # [5] = status to change to
        # [6] = status message to change to
        #
        # self.autoStatusList.append( ( ['-1','-1'], ['-1','-1'], 
        #   ['away'], 'all' , 1, 'away', 'I like to be away' ) )

        if self.cli.debug and self.cli.debugdetails["autostatus"]:
            print "beginning list"
            print self.profile.autoStatusList
            print "\n";
        #
        # does the idle time match?
        #
        templist = []
        for entry in self.profile.autoStatusList:
            if entry[4] == self.idleTime:
                templist.append( entry )

        if len( templist ) == 0:
            return

        if self.cli.debug and self.cli.debugdetails["autostatus"]:
             print "after idletime check:"
             print templist
             print "\n"

        #
        # check for status set automatically
        #
        templist2 = []
        for entry in templist:
            if entry[3] == 'all':
                templist2.append( entry )
            else:
                if( entry[3] == self.currentStatusType ):
                    templist2.append( entry )

        if len( templist2 ) == 0:
            return
        if self.cli.debug and self.cli.debugdetails["autostatus"]:
            print "after autostatus check:"
            print templist2
            print "\n"

        #
        # check for our current status
        #
        templist = []
        for entry in templist2:
            if entry[2][0] == 'all':
                templist.append( entry )
            else:
                for status in entry[2]:
                   if( status == self.cli.currentStatus ):
                      templist.append( entry )
        if len( templist ) == 0:
            return

        if self.cli.debug and self.cli.debugdetails["autostatus"]:
            print "after current status check:"
            print templist
            print "\n"

        #
        # check the time restrictions
        #
        templist2 = []
        for entry in templist:
            if entry[0][0] == -1:
                templist2.append( entry )
            else:
                if( self.timeInRange( time.time(), entry[0], entry[1] ) ):
                    templist2.append( entry )

        templist = templist2
        if len( templist ) == 0:
            return

        if self.cli.debug and self.cli.debugdetails["autostatus"]:
            print "after time check:"
            print templist
            print "\n"

        if len( templist ) > 1:
            #
            # in a perfect world we'd choose the best (most specific)
            # match, but this isn't a perfect world yet :)
            #
            self.cli.output( self.colors["error"] + "Warning: " + 
                self.colors["status"] + \
                "more than one autostatus rule matches" )
            #for x in templist:
            #    self.output( formatAutoStatus( x ) )

        # here we actually change status
        self.cli.currentStatusReason = templist[0][6]
        self.currentStatusType = "auto"
        self.cli.currentStatus = templist[0][5]

        if templist[0][5] == "away":
            self.cli.imcom.sendAway(self.cli.currentStatusReason)
        elif templist[0][5] == "online":
            self.cli.imcom.sendOnline(self.cli.currentStatusReason)
        elif templist[0][5] == "chat":
            self.cli.imcom.sendChat()
        elif templist[0][5] == "xa":
            self.cli.imcom.sendXA(self.cli.currentStatusReason)
        elif templist[0][5] == "dnd":
            self.cli.imcom.sendDND(self.cli.currentStatusReason)

        #
        # I miss my ? :.....
        #
        if( self.idleTime == 1 ):
            minutestring = ""
        else:
            minutestring = "s"

        self.cli.output( "Idle " + str( self.idleTime ) + " minute" +
                minutestring + "; setting status to " +
                self.colors["status"] + templist[0][5] + 
                self.colors["default"] +
                " with reason: " + self.colors["desc"] + 
                self.cli.currentStatusReason +
                self.colors["default"] )

        return

    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # -------------------------------------------------------------------------
    #  Utility Functions
    # -------------------------------------------------------------------------
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    def timeInRange( self, unixTime, beginTime, endTime ):
        curtime = time.localtime( unixTime )
        beginTime = 0, 0, 0, int( beginTime[0] ), int( beginTime[1] ), \
            0, 0, 0, curtime[8]
        endTime = 0, 0, 0, int( endTime[0] ), int( endTime[1] ), \
            0, 0, 0, curtime[8]
        curtime = 0, 0, 0, curtime[3], curtime[4], 0, 0, 0, curtime[8]

        if( ( time.mktime( curtime ) >= time.mktime( beginTime ) ) and
            ( time.mktime( curtime ) <= time.mktime( endTime ) ) ):
            return 1

        return 0

    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    # -------------------------------------------------------------------------
    #  "main"
    # -------------------------------------------------------------------------
    # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    # Send keepalive packets every 60 seconds
    def run(self):
        while(self.running):
            time.sleep(60)
            if( self.running ):
                self.idleTime += 1
                self.doAutoStatus()

