# Script Version: 3.0.0.2
# Script Name: app-b-acd
# April 26, 2004 Satish Ananthanarayana
#
# Copyright (c) 2008 by Cisco Systems, Inc.
# All rights reserved.
#-----------------------------------------------------
# Modification History:
#
# Modified by: Yawming Chen
# Modified Date: Sep 24, 2008
# - added support for MLPP queuing
#
# Modifed by: Jasmine Kalaiselvan
# Modified Date: 04/10/2008
# - Incorportated fix for CSCso70767
# - Removed the "\" that provided line break between loops
#
# Modifed by: Satish Ananthanarayana
# Modified Date: 06/23/2006
# - Added support for ISN
#
# Modifed by: Satish Ananthanarayana
# Modified Date:
# - Added support for drop through mode
# - Added support for multiple auto attendants or
#   call directors. Changed maximum number of hunt
#   groups to 10 to support this
#-----------------------------------------------------
# Cisco CME B-ACD Call Queuing Application
#
#-----------------------------------------------------
#

# >>>> QueueManager.Start <<<<
#
# Procedure is initiated by ev_session_indication
#
proc init { } {
	global CLI
	global qNum
	global allAgentsLogout
	global statCollect
	global aaHuntGroup
	global queueLen
	global serviceStat
	global stat
	global stat1
	global stat2
	global stat3
	global stat4
	global stat5
	global stat6
	global stat7
	global stat8
	global stat9
	global qEmpty
	global vmSource
	global helloInterval
	global maxHuntGroups
	global tempVar
	global sumOfAbanTime
	global sumOfAnsTime
	global huntCount

	if {[info exists CLI]} {
		unset CLI
	}
	if {[info exists qNum]} {
		unset qNum
	}
	if {[info exists allAgentsLogout]} {
		unset allAgentsLogout
	}
	if {[info exists statCollect]} {
		unset statCollect
	}
	if {[info exists queueLen]} {
		unset queueLen
	}
	if {[info exists aaHuntGroup]} {
		unset aaHuntGroup
	}
	if {[info exists serviceStat]} {
		unset serviceStat
	}
	if {[info exists stat]} {
		unset stat
	}
	if {[info exists stat1]} {
		unset stat1
	}
	if {[info exists stat2]} {
		unset stat2
	}
	if {[info exists stat3]} {
		unset stat3
	}
	if {[info exists stat4]} {
		unset stat4
	}
	if {[info exists stat5]} {
		unset stat5
	}
	if {[info exists stat6]} {
		unset stat6
	}
	if {[info exists stat7]} {
		unset stat7
	}
	if {[info exists stat8]} {
		unset stat8
	}
	if {[info exists stat9]} {
		unset stat9
	}
	if {[info exists qEmpty]} {
		unset qEmpty
	}
	if {[info exists sumOfAbanTime]} {
		unset sumOfAbanTime
	}
	if {[info exists sumOfAnsTime]} {
		unset sumOfAnsTime
	}
	if {[info exists vmSource]} {
		unset vmSource
	}
	if {[info exists helloInterval]} {
		unset helloInterval
	}
	if {[info exists maxHuntGroups]} {
		unset maxHuntGroups
	}
	if {[info exists tempVar]} {
		unset tempVar
	}
	if {[info exists huntCount]} {
		unset huntCount
	}
	set serviceStat 0
	set huntCount 0
	set vmSource 0
	set helloInterval 20
	set maxHuntGroups 10
}


proc init_ConfigVars { } {
	global CLI
	global aaHuntGroup
	global stat1
	global stat3
	global stat2
	global stat6
	global stat5
	global queueLen
	global allAgentsLogout
	global statCollect
	global stat4
	global stat7
	global stat8
	global stat9
	global sumOfAbanTime
	global sumOfAnsTime
	global qEmpty
	global configFail
	global maxHuntGroups
	global tempVar
	global huntCount

	#MLPP image flag
	global isMLPPcode
	# check MLPP image
	catch {infotag get leg_precedence_info 1234} result

	if {[regexp "Unrecognized.*VAR_TAG" $result]} {

		set isMLPPcode 0
	    # is not MLPP image
	} else {

		set isMLPPcode 1
	    # is MLPP image
	}

	set configFail 0
	# CLI: queue-manager-debugs 0 or 1 default 1, 0 for disable, 1 for enable
	set result [init_cfgAvPair queue-manager-debugs 1 0 1]
	switch $result {
		{invalid type} {
			puts -nonewline "TCL B-ACD: -- ERROR: Optional parameter queue-manager-debugs $result"
			set configFail 1
			call close
		}
		{does not exist} {
			puts -nonewline "TCL B-ACD: -- Optional parameter queue-manager-debugs $result"
			puts -nonewline "TCL B-ACD: -- Setting default to true"
			set CLI(queue-manager-debugs) 1
		}
		default {
			puts -nonewline "TCL B-ACD: -- Valid optional parameter queue-manager-debugs = $CLI(queue-manager-debugs) --"
		}
	}

	# CLI: queue-len (1-30) default 10
	set result [init_cfgAvPair queue-len 10 1 30]
	switch $result {
		{invalid type} {
			puts -nonewline "TCL B-ACD: -- ERROR: Mandatory parameter queue-len $result"
			set configFail 1
			call close
		}
		{does not exist} {
			puts -nonewline "TCL B-ACD: -- Mandatory parameter queue-len $result"
			puts -nonewline "TCL B-ACD: -- Setting default to 10"
			set CLI(queue-len) 10
		}
		default {
			puts -nonewline "TCL B-ACD: -- Valid Mandatory parameter queue-len = $CLI(queue-len) --"
		}
	}


	# CLI: number-of-hunt-grps (1 - 10) default 3
	set result [init_cfgAvPair number-of-hunt-grps 3 1 10]
	switch $result {
		{invalid type} {
			puts -nonewline "TCL B-ACD: -- ERROR: Mandatory parameter number-of-hunt-grps $result"
			set configFail 1
			call close
		}
		{does not exist} {
			puts -nonewline "TCL B-ACD: -- Mandatory parameter number-of-hunt-grps $result"
			puts -nonewline "TCL B-ACD: -- Setting default to 3"
			set CLI(number-of-hunt-grps) 3
		}
		default {
			puts -nonewline "TCL B-ACD: -- Valid Mandatory parameter number-of-hunt-grps = $CLI(number-of-hunt-grps) --"
		}
	}

	set aaHuntGroup(0) 0
	if { $configFail == 0 } {
		for {set var 1} { $var <= $maxHuntGroups } {incr var} {
			if [infotag get cfg_avpair_exists aa-hunt$var] {
				set aaHuntGroup($var) [string trim [infotag get cfg_avpair aa-hunt$var]]
				set stat1($aaHuntGroup($var)) 0
				set stat3($aaHuntGroup($var)) 0
				set stat2($aaHuntGroup($var)) 0
				set stat6($aaHuntGroup($var)) 0
				set queueLen($aaHuntGroup($var)) 0
				set allAgentsLogout($aaHuntGroup($var)) 0
				set statCollect($aaHuntGroup($var)) 0
				set stat5($aaHuntGroup($var)) 0
				set stat4($aaHuntGroup($var)) 0
				set stat7($aaHuntGroup($var)) 0
				set stat8($aaHuntGroup($var)) 0
				set stat9($aaHuntGroup($var)) 0
				set sumOfAbanTime($aaHuntGroup($var)) 0
				set sumOfAnsTime($aaHuntGroup($var)) 0
				set qEmpty($aaHuntGroup($var)) 1
				QueueManager.PrintStats $aaHuntGroup($var)
				incr huntCount
				set tempVar($huntCount) $aaHuntGroup($var)
				if { $huntCount > $CLI(number-of-hunt-grps) } {
					puts -nonewline "TCL B-ACD: -- ERROR: Number of hunt groups configured exceeds the number hunt groups allowed, set using the number-of-hunt-grps parameter --"
					set configFail 1
				}
			}
		}
	}
}

proc init_cfgAvPair {name default lower upper} {

	global CLI

	if {[infotag get cfg_avpair_exists $name]} {
		set tmpStr [string trim [infotag get cfg_avpair $name]]
		if {[regexp {^([0-9]+)$} $tmpStr d CLI($name)]} {
			if {$CLI($name) < 0} {
				puts -nonewline "TCL AA: -- ERROR: ++ $name is to a negative value ++"
				return "invalid type"
			} elseif {$CLI($name) < $lower} {
				set CLI($name) $lower
				QueueManager.Debug "TCL B-ACD: ++ $name is set to less than minimum allowed value of $lower ++"
				QueueManager.Debug "TCL B-ACD: ++ Setting $name to minimum value of $lower ++"
			} elseif {$CLI($name) > $upper} {
				set CLI($name) $upper
				QueueManager.Debug "TCL B-ACD: ++ $name is set to more than maximum allowed value of $upper ++"
				QueueManager.Debug "TCL B-ACD: ++ Setting $name to maximum value of $upper ++"
			}
		} else {
			return "invalid type"
		}
	} else {
			return "does not exist"
	}
}

proc QueueManager.Debug {comment} {
	global CLI

	if {$CLI(queue-manager-debugs) == 1} {
		puts -nonewline "$comment"
	}
}

proc QueueManager.Init {qvar} {
	upvar 1 $qvar bACDQueue
	set bACDQueue [list]
}
# modified the following procedure for MLPP
proc QueueManager.Enqueue {qvar elem} {
	global isMLPPcode
	upvar 1 $qvar bACDQueue

	if {$isMLPPcode == 1} {
		 if {[info exists bACDQueue]} {
		   # if not an empty queue
		      set idx 0
		      set lln [llength $bACDQueue]
		      # modified for MLPP, find out the length of queue

		      while  {$idx < $lln} {
		      # find out the position where new element should be inserted
		        set queue_elem [lindex $bACDQueue $idx]
		      # queue_elem is the existing element in the queue, elem is the new one to be inserted
		      # index of precedence is 3
		        if {[lindex $queue_elem 3] > [lindex $elem 3]} {
		           break
		        }
		        incr idx
		     }
		     # end of while
		     QueueManager.Debug  "TCL B-ACD: >>> Queue index is $idx <<<"
		     set tmp [linsert $bACDQueue $idx $elem]
		     set bACDQueue $tmp
		 } else {
		  # append new element when queue is empty
		        QueueManager.Debug "TCL B-ACD: >>> THE QUEUE IS EMPTY -- Append Element <<<"
		        lappend bACDQueue $elem
		 }
  		 QueueManager.Debug "TCL B-ACD:  >>> THE QUEUE NOW IS $bACDQueue <<<"

  	} else {
  	# not MLPP code
		lappend bACDQueue $elem
		QueueManager.Debug "TCL B-ACD:  >>> THE QUEUE IS $bACDQueue <<<"
	}
}

proc QueueManager.Dequeue {qvar} {
	upvar 1 $qvar bACDQueue
	set headOfQueue [lindex $bACDQueue 0]
	set bACDQueue [lrange $bACDQueue 1 end]
	return $headOfQueue
}

proc QueueManager.Empty {qvar} {
	upvar 1 $qvar bACDQueue
	return [expr {[llength $bACDQueue] == 0}]
}

proc QueueManager.Replace {qvar idx elem} {
	upvar 1 $qvar bACDQueue
	if {$elem != 0 } {
		set bACDQueue [lreplace $bACDQueue $idx $idx $elem]
		QueueManager.Debug "TCL B-ACD:  >>> THE QUEUE IS $bACDQueue <<<"
	} else {
		set bACDQueue [lreplace $bACDQueue $idx $idx]
		QueueManager.Debug "TCL B-ACD:  >>> THE QUEUE IS $bACDQueue <<<"
	}
}

proc QueueManager.Search {qvar src} {
	upvar 1 $qvar bACDQueue
	set elemIdx 0
	foreach var $bACDQueue {
		set elem [lsearch $var $src]
		if { $elem == 0 } {
			return $elemIdx
		} else {
			incr elemIdx
		}
	}
	return -1
}
proc QueueManager.GetHandle {qvar idx} {
	upvar 1 $qvar bACDQueue
	set elem [lindex $bACDQueue $idx]
	return [lindex $elem 0]
}

proc QueueManager.GetState {qvar idx} {
	upvar 1 $qvar bACDQueue
	set elem [lindex $bACDQueue $idx]
	return [lindex $elem 1]
}

proc QueueManager.GetTimeStamp {qvar idx} {
	upvar 1 $qvar bACDQueue
	set elem [lindex $bACDQueue $idx]
	return [lindex $elem 2]
}

proc QueueManager.SendMsg {idx optnID cState target} {
	global qNum
	global queueLen
	global stat

	set replyMessage(callState) $cState
	set replyMessage(optionIDX) $optnID
	set sendMsgFlag [sendmsg $target -p replyMessage]
	if {$sendMsgFlag == "unavailable"} {
		set elem 0
		QueueManager.Replace qNum($optnID) $idx $elem
		incr queueLen($optnID) -1
		QueueManager.PrintStats	$optnID
		return "send failure"
	}
	return "send success"
}

proc QueueManager.PrintStats {var1} {
	global stat
	global stat1
	global stat2
	global stat3
	global stat4
	global stat5
	global stat6
	global stat7
	global stat8
	global stat9
	global queueLen

	set stat($var1) "\{[concat "\"Total calls presented to the queue: \"" $stat1($var1)]\}
	\{[concat "\"Calls answered by agents: \"" $stat2($var1)]\}
	\{[concat "\"Number of calls in the queue: \"" $queueLen($var1)]\}
	\{[concat "\"Average time to answer (secs): \"" $stat4($var1)]\}
	\{[concat "\"Longest time to answer (secs): \"" $stat5($var1)]\}
	\{[concat "\"Number of abandoned calls: \"" $stat6($var1)]\}
	\{[concat "\"Average time before abandon (secs): \"" $stat7($var1)]\}
	\{[concat "\"Calls forwarded to voice mail: \"" $stat8($var1)]\}
	\{[concat "\"Calls answered by voice mail: \"" $stat9($var1)]\}"
}

proc QueueManager.Start { } {
	global CLI
	global qNum
	global aaHuntGroup
	global helloInterval
	global serviceStat
	global configFail
	global maxHuntGroups
	global initialized

      if { $initialized == 0 } {
           init_ConfigVars
           set initialized 1
      }

	if { $configFail == 0} {
	set tmpLeg [string trim [infotag get evt_legs]]
	set registerQueue [service register B-ACD-SERVICE]

	if { $registerQueue == "registered" } {
    	timer start named_timer 60 QUEUE_MANAGER_TIMER
	incr serviceStat
		log -s INFO "TCL B-ACD:  >>> B-ACD Service Started <<<"
		QueueManager.Debug "TCL B-ACD:  >>> B-ACD Service Started <<<"
	} elseif { $registerQueue == "service already registered" } {
		timer start named_timer 60 QUEUE_MANAGER_TIMER
		QueueManager.Debug "TCL B-ACD:  >>> B-ACD Service Running <<<"
		set refreshTimer [infotag get evt_timer_name]
		set currTime [clock seconds]
		if { $refreshTimer == "QUEUE_MANAGER_TIMER" } {
			for {set var 1} { $var <= $maxHuntGroups } {incr var} {
				if {[info exists aaHuntGroup($var)]} {
					if {[info exists qNum($aaHuntGroup($var))] == 1} {
						if {[QueueManager.Empty qNum($aaHuntGroup($var))] != 1} {
							QueueManager.Debug "TCL B-ACD: >>> $qNum($aaHuntGroup($var)) <<<"
							for {set i 0} {$i < [llength $qNum($aaHuntGroup($var))]} {incr i} {
								set timeStamp [QueueManager.GetTimeStamp qNum($aaHuntGroup($var)) $i]
								if {[expr $currTime - $timeStamp] > $helloInterval} {
									set aaHandle [QueueManager.GetHandle qNum($aaHuntGroup($var)) $i]
									if {[QueueManager.SendMsg $i $aaHuntGroup($var) CALL_ALIVE $aaHandle] == "send failure"} {
										incr i -1
										QueueManager.Debug "TCL B-ACD: +++ AA $aaHandle not responding, flushed from Queue +++"
									}
								}
							}
						}
					}
				}
			}
		}
	} elseif { $registerQueue == "service registered by another session" } {
		log -s INFO "TCL B-ACD:  >>> B-ACD Service already Running, started by another session <<<"
		QueueManager.Debug "TCL B-ACD:  >>> ERROR: B-ACD Service already Running, started by another session <<<"
	}
	if {$tmpLeg != ""} {
		set hstring [infotag get evt_handoff_string]
		if { [llength $hstring] == 2} {
			puts -nonewline "TCL B-ACD: >>> Handoff String = $hstring <<<"
			set hstringidx [lindex $hstring 1]
			handoff appl $tmpLeg [lindex $hstring 0] -s $hstringidx
		} else {
			puts -nonewline "TCL B-ACD: >>> Handoff String = $hstring <<<"
			handoff appl $tmpLeg $hstring
		}
	}
	} else {
		QueueManager.SessionCleanup
	}
}

proc QueueManager.Get { } {
	global CLI
	global qNum
	global aaHuntGroup
	global serviceStat
	global stat
	global stat1
	global stat3
	global stat2
	global stat6
	global queueLen
	global allAgentsLogout
	global statCollect
	global stat5
	global stat4
	global stat7
	global stat8
	global stat9
	global qEmpty
	global sumOfAbanTime
	global sumOfAnsTime
	global vmSource
	global maxHuntGroups
	global tempVar
	global huntCount
	# added for MLPP
	global isMLPPcode

	set legState CALL_INIT
	set optionID 0
	set src [infotag get evt_msg_source]
	infotag get evt_msg msg_array

	if { ([info exists msg_array(optionIDX)] == 1) && ([info exists msg_array(callState)] ==1) && ([info exists msg_array(keepTime)] == 1)} {
		if {[info exists aaHuntGroup($msg_array(optionIDX))]} {
			set optionID $aaHuntGroup($msg_array(optionIDX))
			set legState $msg_array(callState)
			set keepTime $msg_array(keepTime)
			# added for MLPP
			if {$isMLPPcode == 1} {
				set legPrecedence $msg_array(Precedence)
			}
			# added for MLPP
		} elseif {$msg_array(optionIDX) == "NULL"} {
			set optionID $tempVar($huntCount)
			set legState $msg_array(callState)
			set keepTime $msg_array(keepTime)
			# added for MLPP
			if {$isMLPPcode == 1} {
				set legPrecedence $msg_array(Precedence)
			}
			# added for MLPP
		} else {
			set replyMessage(callState) NO_HUNT_GROUP
			set rval [sendmsg $src -p replyMessage]
		}
	} elseif {([info exists msg_array(allAgentsLogoutPilotNum)] == 1) && ([info exists msg_array(allAgentsLogoutFlag)] == 1)} {
		set optionID $msg_array(allAgentsLogoutPilotNum)
		set allAgentsLogout($optionID) $msg_array(allAgentsLogoutFlag)
	} elseif {([info exists msg_array(statCollectPilotNum)] == 1) && ([info exists msg_array(statCollectFlag)] == 1)} {
		set optionID $msg_array(statCollectPilotNum)
		set statCollect($optionID) $msg_array(statCollectFlag)
		if {$msg_array(statCollectFlag) == 1} {
			set stat1($optionID) 0
			set stat2($optionID) 0
			set stat3($optionID) 0
			set stat4($optionID) 0
			set stat5($optionID) 0
			set stat6($optionID) 0
			set stat7($optionID) 0
			set stat8($optionID) 0
			set stat9($optionID) 0
			set sumOfAbanTime($optionID) 0
			set sumOfAnsTime($optionID) 0
			QueueManager.PrintStats $optionID
			QueueManager.Debug "TCL B-ACD:  >>> Stat collection enabled for queue $optionID <<<"
		} else {
			QueueManager.Debug "TCL B-ACD:  >>> Stat collection disabled for queue $optionID <<<"
		}
	} elseif {[info exists msg_array(readStatDone)] == 1} {
		QueueManager.Debug "TCL B-ACD: >>> Reading Stat Done = $msg_array(readStatDone) <<<"
		if {$msg_array(readStatDone) == 1} {
		QueueManager.Debug "TCL B-ACD: >>> Clearing Queue Stats <<<"
			for {set var 1} { $var <= $maxHuntGroups } {incr var} {
				if {[info exists aaHuntGroup($var)]} {
					if {[info exists qNum($aaHuntGroup($var))] == 1} {
						set stat1($aaHuntGroup($var)) 0
						set stat3($aaHuntGroup($var)) 0
						set stat2($aaHuntGroup($var)) 0
						set stat6($aaHuntGroup($var)) 0
						set stat5($aaHuntGroup($var)) 0
						set stat4($aaHuntGroup($var)) 0
						set stat7($aaHuntGroup($var)) 0
						set stat8($aaHuntGroup($var)) 0
						set stat9($aaHuntGroup($var)) 0
						set sumOfAbanTime($aaHuntGroup($var)) 0
						set sumOfAnsTime($aaHuntGroup($var)) 0
						if {$statCollect($aaHuntGroup($var)) == 1} {
							QueueManager.PrintStats $aaHuntGroup($var)
						}
					}
				}
			}
		}
	} else {
		QueueManager.Debug "TCL B-ACD: ++ No message received ++ "
	}
	switch -exact $legState {
		CALL_NEW {
			if { $queueLen($optionID) < $CLI(queue-len) } {
				QueueManager.Debug "TCL B-ACD: +++ New incoming call to queue $optionID +++"

				# modified for MLPP
				if {$isMLPPcode == 1} {
					QueueManager.Enqueue qNum($optionID) "$src {$legState} {$keepTime} {$legPrecedence}"
			    } else {

					QueueManager.Enqueue qNum($optionID) "$src {$legState} {$keepTime}"
				}
				set qEmpty($optionID) 0
				incr serviceStat
				incr stat1($optionID)
				incr queueLen($optionID)
				QueueManager.Debug "TCL B-ACD: +++ $optionID Queue Length = $queueLen($optionID) +++"
				QueueManager.PrintStats $optionID
				set idx [QueueManager.Search qNum($optionID) $src]
				if {$idx == 0} {
					if {$allAgentsLogout($optionID) == 0} {
						QueueManager.SendMsg $idx $optionID CALL_HUNT $src
					} else {
						if {[QueueManager.SendMsg $idx $optionID CALL_NAGT $src] == "send success"} {
							set legState CALL_HOLD
							# modified for MLPP
						    if {$isMLPPcode == 1} {
								set elem "$src {$legState} {$keepTime} {$legPrecedence}"
							} else {
								set elem "$src {$legState} {$keepTime}"
				  			}
							QueueManager.Replace qNum($optionID) $idx $elem
						}
					}
				} else {
					set statePrevCall [QueueManager.GetState qNum($optionID) [expr $idx -1]]
					if { ($statePrevCall == "CALL_PROGRESS") || ($statePrevCall == "CALL_HANDOFF") || ($statePrevCall == "CALL_HANGUP") || ($statePrevCall == "CALL_NEW") } {
						if {$allAgentsLogout($optionID) == 0} {
							QueueManager.SendMsg $idx $optionID CALL_HUNT $src
						} else {
							if {[QueueManager.SendMsg $idx $optionID CALL_NAGT $src] == "send success"} {
								set legState CALL_HOLD
								# modified for MLPP
								if {$isMLPPcode == 1} {
									set elem "$src {$legState} {$keepTime} {$legPrecedence}"
								} else {
									set elem "$src {$legState} {$keepTime}"
				  				}
								QueueManager.Replace qNum($optionID) $idx $elem
							}
						}
					} else {
						if {[QueueManager.SendMsg $idx $optionID CALL_HOLD $src] == "send success"} {
							set legState CALL_HOLD
							# modified for MLPP
						    if {$isMLPPcode == 1} {
								set elem "$src {$legState} {$keepTime} {$legPrecedence}"
							} else {
								set elem "$src {$legState} {$keepTime}"
				  			}
							QueueManager.Replace qNum($optionID) $idx $elem
						}
					}
				}
			} else {
				QueueManager.Debug "TCL B-ACD:  >>> QUEUE IS FULL: Call Rejected <<<"
				log -s INFO "TCL B-ACD:  ++ QUEUE $optionID IS FULL: Call Rejected ++"
				set replyMessage(callState) CALL_REJECT
				set rval [sendmsg $src -p replyMessage]
			}
		}
		HELLO {
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				set stateOfCall [QueueManager.GetState qNum($optionID) $idx]
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$stateOfCall} {$keepTime} {$legPrecedence}"
			    } else {
				    set elem "$src {$stateOfCall} {$keepTime}"
	        	}
				QueueManager.Replace qNum($optionID) $idx $elem
				QueueManager.Debug "TCL B-ACD: >>> Received HELLO from $src <<<"
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_PROGRESS {
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_RETRY_PROGRESS {
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
				}

				QueueManager.Replace qNum($optionID) $idx $elem
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_VM {
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				if {[info exists msg_array(vmStat)] == 1} {
					incr stat8($optionID)
					QueueManager.PrintStats $optionID
				}
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_HANDOFF {
			if {[info exists msg_array(ansTime)] == 1} {
				QueueManager.Debug "TCL B-ACD:  >>> Time to Answer = $msg_array(ansTime) Seconds<<<"
				if {[info exists msg_array(vmStat)] == 1} {
					QueueManager.Debug "TCL B-ACD: +++ Call answered by voice mail; Agent stats not calculated +++"
					incr stat9($optionID)
				} else {
					incr stat2($optionID)
				}
				set sumOfAnsTime($optionID) [expr $sumOfAnsTime($optionID) + $msg_array(ansTime)]
				set stat4($optionID) [expr $sumOfAnsTime($optionID)/($stat2($optionID) + $stat9($optionID))]
				if {$stat5($optionID) < $msg_array(ansTime)} {
					set stat5($optionID) $msg_array(ansTime)
				}
				QueueManager.PrintStats $optionID
			}
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_BUSY {
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_TEMP_FAILURE {
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_RETRY {
			set idx [QueueManager.Search qNum($optionID) $src]
			if {$idx == 0} {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
				if {$allAgentsLogout($optionID) == 0} {
					QueueManager.SendMsg $idx $optionID CALL_RETRY $src
				} else {
					if {[QueueManager.SendMsg $idx $optionID CALL_NAGT $src] == "send success"} {
						set legState CALL_HOLD
						# modified for MLPP
						if {$isMLPPcode == 1} {
							set elem "$src {$legState} {$keepTime} {$legPrecedence}"
						} else {
							set elem "$src {$legState} {$keepTime}"
			   			}

						QueueManager.Replace qNum($optionID) $idx $elem
					}
				}
			} elseif {$idx > 0} {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
				set statePrevCall [QueueManager.GetState qNum($optionID) [expr $idx -1]]
				if { ($statePrevCall == "CALL_PROGRESS") || ($statePrevCall == "CALL_HANDOFF") || ($statePrevCall == "CALL_HANGUP") || ($statePrevCall == "CALL_NEW") } {
					if {$allAgentsLogout($optionID) == 0} {
						QueueManager.SendMsg $idx $optionID CALL_RETRY $src
					} else {
						if {[QueueManager.SendMsg $idx $optionID CALL_NAGT $src] == "send success"} {
							set legState CALL_HOLD
							# modified for MLPP
							if {$isMLPPcode == 1} {
								set elem "$src {$legState} {$keepTime} {$legPrecedence}"
							} else {
									set elem "$src {$legState} {$keepTime}"
			    			}

							QueueManager.Replace qNum($optionID) $idx $elem
						}
					}
				} else {
					if {[QueueManager.SendMsg $idx $optionID CALL_HOLD $src] == "send success"} {
						set legState CALL_HOLD
						# modified for MLPP
						if {$isMLPPcode == 1} {
							set elem "$src {$legState} {$keepTime} {$legPrecedence}"
						} else {
							set elem "$src {$legState} {$keepTime}"
			    		}

						QueueManager.Replace qNum($optionID) $idx $elem
					}
				}
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_NOAN {
			set idx [QueueManager.Search qNum($optionID) $src]
			if { $idx != "-1" } {
				# modified for MLPP
				if {$isMLPPcode == 1} {
					set elem "$src {$legState} {$keepTime} {$legPrecedence}"
				} else {
					set elem "$src {$legState} {$keepTime}"
			    }

				QueueManager.Replace qNum($optionID) $idx $elem
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		CALL_HANGUP {
			incr stat3($optionID)
			if {[info exists msg_array(abandonTime)] == 1} {
				QueueManager.Debug "TCL B-ACD:  >>> Call Abandoned Time = $msg_array(abandonTime) Seconds<<<"
				incr stat6($optionID)
				set sumOfAbanTime($optionID) [expr $sumOfAbanTime($optionID) + $msg_array(abandonTime)]
				set stat7($optionID) [expr $sumOfAbanTime($optionID)/$stat6($optionID)]
			}
			QueueManager.Debug "TCL B-ACD ++ Service Counter = $serviceStat ++"
			if {$statCollect($optionID) == 1} {
				QueueManager.PrintStats $optionID
				QueueManager.Debug "TCL B-ACD: >>> Queue $optionID Statistics = $stat($optionID) <<<"
			}
			set idx [QueueManager.Search qNum($optionID) $src]
			set elem 0
			if {$idx == 0} {
				QueueManager.Dequeue qNum($optionID)
				if { $queueLen($optionID) > 0} {
					incr queueLen($optionID) -1
					QueueManager.Debug "TCL B-ACD: +++ $optionID Queue Length = $queueLen($optionID) +++"
					QueueManager.PrintStats $optionID
				}
				QueueManager.Debug "TCL B-ACD:  >>> $optionID Queue Length = $queueLen($optionID) <<<"
				if {[QueueManager.Empty qNum($optionID)] == 1} {
					set qEmpty($optionID) 1
					QueueManager.Debug "TCL B-ACD:  >>> Queue $optionID is Empty <<<"
				} else {
					set qEmpty($optionID) 0
				}
			} elseif {$idx > 0} {
				QueueManager.Replace qNum($optionID) $idx $elem
				if { $queueLen($optionID) > 0} {
					incr queueLen($optionID) -1
					QueueManager.Debug "TCL B-ACD: +++ $optionID Queue Length = $queueLen($optionID) +++"
					QueueManager.PrintStats $optionID
				}
				QueueManager.Debug "TCL B-ACD:  >>> $optionID Queue Length = $queueLen($optionID) <<<"
				if {[QueueManager.Empty qNum($optionID)] == 1} {
					set qEmpty($optionID) 1
					QueueManager.Debug "TCL B-ACD:  >>> Queue $optionID is Empty <<<"
				} else {
					set qEmpty($optionID) 0
				}
			} else {
				QueueManager.Debug "TCL B-ACD: >>> Element Not Found in the Queue <<<"
			}
		}
		default {
			QueueManager.Debug "TCL B-ACD: ++ Message received from IOS ++"
		}
	}
}


# >>>> QueueManager.SessionCleanup <<<<
#
# Procedure is initiated by a ev_session_terminate event
# initiates a close call.
#
proc QueueManager.SessionCleanup { } {

	log -s INFO "TCL B-ACD:  >>> B-ACD Service Terminated <<<"
	call close
}

requiredversion 2.0
init
set initialized 0
#init_ConfigVars
#----------------------------------
#   State Machine
#----------------------------------

  set fsm(CALL_INIT,ev_session_indication)  "QueueManager.Start           NEXTSTATE"
  set fsm(CALL_INIT,ev_handoff)  "QueueManager.Start           NEXTSTATE"
  set fsm(any_state,ev_msg_indication)	"QueueManager.Get same_state"
  set fsm(any_state,ev_named_timer)	"QueueManager.Start	same_state"
  set fsm(any_state,ev_session_terminate)	"QueueManager.SessionCleanup  same_state"

  fsm define fsm CALL_INIT

