#
# feedback.py
# Bernard Sypniewski
#
# This is a first attempt to create an object-oriented linkage simulation in PYTHON.
# It briefly models a situation in which two people are in a club talking about something,
# when feedback from a sound system interrupts their conversation.
#
# begun 02/06/08
#
import random
#
# The Linkage class models an HSL linkage with a top level task
#
class Linkage:
    def __init__( self ):
        self.name = "AB"
#
# The descriptor is for the user's convenience and is not part of the HSL model.
#
    def printDescriptor( self ):
        print "The ",self.name,"linkage models the situation in which two friends talk to each other in a club or resturaunt\n while a third person adjusts the sound system. The sound system creates feedback, interrupting\n the conversation."
#
# The top_level_task method represents an SL top level task for the [AB] linkage. It prints some status information (not part of the HSL model),
# has Able and Baker greet each other, talk for a while, whereupon the sound system is turned on. Able and Baker react if there is feedback but
# contnue their conversation otherwise.
#
    def top_level_task( self ):
        self.printDescriptor()
        ss.printStatus()
        print "\n[", self.name,"]<top level task>"
        print "The conversation begins:"
        Able.greet()
        Baker.answerGreeting()
        Able.converse()
        Baker.converse()
        ss.turnOn()
        Able.converse()
        Baker.converse()
        print "\n20 seconds later, the sound system is turned of..."
        ss.setonOff(0)
        ss.printStatus()
        Able.converse()
        Baker.converse()
#
# The ChannelPart class is used to represent the [feedback] channel part. Initially, there is no feedback.
#
class ChannelPart:
    def __init__( self ):
        self.isFeedback = 0
        self.sound = "none"
#
# The setFeedback method sets isFeedback to either 1 (yes, there is feedback) or 0 (no, there isn't).
#
    def setFeedback( self, f ):
        if f <> 0:
            self.isFeedback = 1
        else:
            self.isFeedback = 0
#
# The next method simply returns the feedback status.
#
    def getFeedback( self ):
        return self.isFeedback
#
# setFeedbackSound is implimented as a private method. It sets the sound if there is feedback but eliminates the sound if there is no feedback.
#
    def __setFeedbackSound( self ):
        if self.isFeedback == 1:
            self.sound = "Shreeeeeek!"
        else:
            self.sound = "none"
#
# The next method calls the private method above and returns the sound thus created.
#
    def getFeedbackSound( self ):
        self.__setFeedbackSound()
        return self.sound
#
# The Sound_System class represents the HSL [sound system] prop part. Initially, the sound system is off with no volume.
#
class Sound_System:
    def __init__( self ):
        self.onOff = 0
        self.volume = "none"
#
# This method determines whether there is feedback. If the sound system is on and the volume is loud or very loud, then there is feedback.
# Otherwise, no feedback.
#
    def setFeedback (self ):
        if self.onOff == 1 and (self.volume == "loud" or self.volume == "very loud"):
            feedback.setFeedback(1)
        else:
            feedback.setFeedback(0)
#
# A method that turns the sound system on (1) or off (0).
#
    def setonOff( self, onOff ):
        self.onOff = onOff
        if onOff == 0:
            self.setVolume("none")
            self.setFeedback()
#
# This method allows the volume to be set.
#
    def setVolume( self, volume ):
        self.volume = volume
#
# This method prints out the current status of the sound system. This is not part of the HSL model, although this information
# could easily be derived from the HSL model.
#
    def printStatus( self ):
        print "\nCurrent Sound System status:"
        if self.onOff == 0:
            print "The sound system is off."
        else:
            print "The sound system is on."
            
        if self.volume == "none":
            print "The sound system is making no noise."
        else:
            print "The sound system's volume is ", self.volume
            
        if feedback.getFeedback() == 0:
            print "No feedback"
        else:
            print "Lots of feedback"
#
# This is the method that actually turns the sound system on. Note that it sets some properties, including the properties
# that determine whether Able and Baker can actually hear each other.
#
    def turnOn( self ):
        ss.setonOff(1)
        ss.setVolume("loud")
        ss.setFeedback()
        ss.printStatus()

        if feedback.getFeedback() == 1:
            Able.sethearCompanion(0)
            Baker.sethearCompanion(0)
#
# The RolePArt class is an attempt to create a generic (for this linkage) role part.
#
class RolePart:
    def __init__( self ):
        self.name = ""
        self.hearCompanion = 1
        #
        # feedback comments - fc
        #
        self.fc = ("Yow!",
                "That hurts the old ears!",
                "Can't they turn that thing down?",
                "Holy Smoke!",
                "Good Grief!")
        
        self.greetingsQ = ("Hey, how are you?",
                                    "You're looking good; how are things going?",
                                    "What's up?")
        self. greetingsR = ("Pretty good.",
                                        "No sense complaining...",
                                        "Same old same old.")
#
# Can a communicating individual (in this case, Able or Baker) hear his companion? yes = 1, no = 0.
#
    def sethearCompanion( self, hc ):
        self.hearCompanion = hc
#
# This method allows on person to greet another.
#
    def greet( self ):
        print "[",self.name,"]<greet>",self.greetingsQ[random.randrange(2)]
#
# Respond to the greeting.
#
    def answerGreeting( self ):
        print "[", self.name, "]<answer greeting>", self.greetingsR[random.randrange(2)]
#        
# If there is no feedback, Able and Baker chatter at each other. If there is feedback but they can't hear each other (volume = "loud" or "very loud")
# they comment on the feedback. If the feedback volume does not disturb them, they might not comment on the feedback or they might not even
# notice it.
#
    def converse( self ):
        if feedback.isFeedback == 0:
            self.hearCompanion = 1
        if self.hearCompanion == 1:
            print "[",self.name,"]<converse>  Chatter! Chatter! Chatter!"
        elif self.hearCompanion == 0 and feedback.isFeedback == 1:
            print "\n[",self.name,"]<comment on feedback>", self.fc[random.randrange(4)]
        
#
# Main part of the program. Create object instances, assign role part names, and call the top level task.
#
AB = Linkage()
ss = Sound_System()
feedback = ChannelPart()

Able = RolePart()
Able.name = "Able"
     
Baker = RolePart()
Baker.name = "Baker"
AB.top_level_task()