
# CMPT 200 Lab 5 Queue Management System
# 
# Author: Winston Kouch
# MacEwan ID: 1645889
#
# Date: November 3, 2014
#
# To start program:  type in console:       main()
#          WARNING:  !!! to avoid graphics.py crashes, use the rectangular exit
#                        buttons within the menu instead of clicking x or pressing
#                        alt+f4      !!!
#
#            The program will boot up the graphics menu when you run
#            this command.
#
# I/O Test Files: load.txt - load packages only text file
#                 YardData.txt - load container/package data state that was saved from last time
#                 SaveData.txt - saved text file of load.txt after being entered into system
#
# Description: Queue Management System to simulate shipping packages in a shipyard.
#              The menu is done in graphics.py and fully functional (there are some
#              exception handles such as weight not allowed to exceed 2000 lbs
#              and system generated id cannot be altered by user.
#              Functionality works regardless of lower and upper-case.
#
# Note: I did not perform print shipping manifest functions in graphics
#       display because I did not know how to create an autoflow method
#       for text in the case where the shipping manifest would be too
#       large to fit all the text on the screen. 
#
# Important: To exit a menu/form, do not use the x button, use the Exit boxes.
#            Please view the print outs in the python console after clicking
#            the option and then clicking update console.

from graphics import *
# QMS.py contains my shipyard class which also contain package and container
# class inside it
from QMS import *
import time

# Menu where you can choose to perform several functions in the system
# Functions: Load from packages, Load Yard Data, Save Yard Data, and
#            many other Shipyard Package Functions
def graph_menu():
    # Functional menu done in graphics.py
    front = "Winston's QMS Menu V1.0011"
    front_Text = Text(Point(630, 25), front)
    front_Text.setSize(16)    
    front_Text.draw(win)
    
    # Shipyard logo modified and found from
    # https://www.iconfinder.com/icons/175943/
    # basic_ship_shipyard_traffic_transport_transportation_travel_icon
    logo = Image(Point(710,110), "shipyardlogo.gif")
    
    # The 4 Menu Options (graphics.py)
    opt1 = Rectangle(Point(150, 190), Point(600, 240))
    opt2 = Rectangle(Point(150, 260), Point(600, 310))
    opt3 = Rectangle(Point(150, 330), Point(600, 380))
    opt4 = Rectangle(Point(150, 400), Point(600, 450))
    opt1.setFill('yellow')
    opt2.setFill('yellow')
    opt3.setFill('yellow')
    opt4.setFill('yellow')
    
    # Help and Exit Button Drawing (graphics.py)
    opt5 = Rectangle(Point(700, 520), Point(780, 580)) # box for exit
    opt6 = Rectangle(Point(20, 480), Point(140, 580))   # box for help
    opt5.setFill('red')
    opt6.setFill('green')
    opt1.draw(win)
    opt2.draw(win)
    opt3.draw(win)
    opt4.draw(win)
    opt5.draw(win)
    opt6.draw(win)
    exit_Text = Text(Point(740, 550), 'Exit') # box is opt 5
    help_Text = Text(Point(80,530), 'Help') # box is opt 6
    help_Text.draw(win)
    exit_Text.draw(win)
    logo.draw(win)
    
    # Option Texts
    txt1 = Text(Point(375, 215), "Load New Packages Into System From File (ie. load.txt)")
    txt2 = Text(Point(375, 285), "Load Container and Package Data From File (ie. YardData.txt)")
    txt3 = Text(Point(375, 355), "Save Yard System Data To File (ie. YardData.txt)")
    txt4 = Text(Point(375, 425), "Launch System Functions Menu (New Window)")
    txt1.draw(win)
    txt2.draw(win)
    txt3.draw(win)
    txt4.draw(win)    
    
# splash screen to program
def splash_Screen():
    closing = ""
    intro = """
    Hi! Welcome to the shipyard management system, QMS.
    
    Note: Many functions present information in graphics.py.
          The print shipping information functions will ONLY print data
          to the python console because the information will
          likely not fit in a graphics.py window.
          
    Please click your option after the system has loaded. Enjoy!
    """    
    # Draws the rectangle splash box
    rect = Rectangle(Point(10, 10), Point(790, 590))
    rect.setFill('grey')
    rect.draw(win)
    
    # Draw Splash Title of Game and set constraints for text style.
    banner_Text = Text(Point(400, 350), 'System Loading!')
    banner_Text.setSize(32)
    banner_Text.setFace('helvetica')
    banner_Text.setStyle('bold italic')
    intro_Text = Text(Point(380, 200), intro)
    intro_Text.setSize(14)
    closing_Text = Text(Point(640, 470), closing)
    closing_Text.draw(win)
    intro_Text.draw(win)
    banner_Text.draw(win)
    
    # Keeps splash screen on screen using 1 second sleeps for a total of 3 secs.
    for i in range(3):
        closing = "Closing in " + str(3-i) + " . . ."
        closing_Text.setText(closing)
        time.sleep(1)
        
    # undraw splash elements
    closing_Text.undraw()
    banner_Text.undraw()
    intro_Text.undraw()
    
# Bring up the help menu when called
def help_menu():
    helptext = """
    
    
       User guide for shipyard controls...     (click to return)
       
       Click Load New Packages into System From File
       to Load Packages from a Text File
       
       Click Load Container and Package Data From File
       to Restore Saved Yard Data
       
       Click Save Yard System Data to Save Yard Data To File
       
       Click Launch System Functions Menu to Open A New Window
       With Functions to Operate The System
       
       Remember: New windows must be closed to use the main menu.
       """    
    
    # Draws the rectangle splash box
    helprect = Rectangle(Point(10, 180), Point(790, 590))
    helprect.setFill('brown')
    helprect.draw(win)    
    intro_Text = Text(Point(380, 320), helptext)
    intro_Text.setSize(14)       
    intro_Text.draw(win)

    # Wait for user mouse click to go back to the program
    win.getMouse()
    # undraw code
    helprect.undraw()   
    intro_Text.undraw()
    
# Mouse Click Event Handler for main menu
def detect_actions():
    global win2
    program_running = True
    textentry = Text(Point(250, 100), "Please enter filename here:")
    filenameentry = Entry(Point(300,150), 20)
    filenameentry.setText("Filename?")
    filenameentry.draw(win)    
    textentry.draw(win)
    while program_running:
        #detect mouse clicks
        mouseCoord = win.getMouse()
            
        # if click option 1
        if mouseCoord.x >= 150 and mouseCoord.x <= 600 and mouseCoord.y >= 190 and mouseCoord.y <= 240:
            print("Option 1 Initial Load Data New System clicked")
            file = filenameentry.getText()
            print ("Loading", str(file))
            textentry.setText("Your file should have loaded.\nCheck console for filename if you like.\nClick anywhere again to allow navigation.")
            win.getMouse()
            textentry.setText("Please enter filename here:")
            # Run the load packages from a specified file
            q.loadPackagesFromFile(file)
                
        # if click option 2    
        if mouseCoord.x >= 150 and mouseCoord.x <= 600 and mouseCoord.y >= 260 and mouseCoord.y <= 310:
            print("Option 2 Load Packages and Containers into system")        
            file = filenameentry.getText()
            print ("Loading", str(file))
            textentry.setText("Your file should have loaded.\nCheck console for filename if you like.\nClick anywhere again to allow navigation.")
            win.getMouse()
            textentry.setText("Please enter filename here:")                
            # Run the Load Yard Data Function from a specified file
            q.loadYardData(file)
        
        # if click option 3, saving data
        if mouseCoord.x >= 150 and mouseCoord.x <= 600 and mouseCoord.y >= 330 and mouseCoord.y <= 380:
            print("Option 3 Save Yard Data")        
            file = filenameentry.getText()
            print ("Saving", str(file))
            textentry.setText("Your file is saved.\nCheck console for filename if you like.\nClick anywhere again to allow navigation.")
            win.getMouse()
            textentry.setText("Please enter filename here:")            
            # Save the Yard Data to a specified file
            q.saveYardData(file)
        
        # if click option 4
        if mouseCoord.x >= 150 and mouseCoord.x <= 600 and mouseCoord.y >= 400 and mouseCoord.y <= 450:
            print("Option 4 Launch Package Functions")
            
            # open win2 with launch package function
            win2 = GraphWin("Package Functions - QMS", 600, 300)
            win2.setBackground('lightblue')
            findPackageGUI() # reads user input to find specific package info
            win2.getMouse()
            
        # Detect mouse click in help/exit
        if mouseCoord.x >= 700 and mouseCoord.x <= 780 and mouseCoord.y >= 520 and mouseCoord.y <= 580:
            print("Exiting")
            win.close()
        if mouseCoord.x >= 20 and mouseCoord.x <= 140 and mouseCoord.y >= 480 and mouseCoord.y <= 580:
            print("Help Clicked")
            help_menu() # launch help menu window
                
# detect mouse events in the second window for package functions                
# traverseGrabPackageInside uses traverseGrabPackage to get the package information
# from within the container
# it then displays the package information for the user to see.
def detect_pkg_actions():
    global win3, win4, win5
    func_running = True
    while func_running:
        # listen for mouse click on package window
        mouseCoord = win2.getMouse()
        
        # if click search button
        if mouseCoord.x >= 400 and mouseCoord.x <= 580 and mouseCoord.y >= 20 and mouseCoord.y <= 100:
            print("Search clicked")
            # perform search and grab results change to search inside containers function after from shipyard
            grabid = pkgidbox.getText()
            # get the 5 values from the container and package retrieved by matching package id
            storage = q.traverseGrabPackageInside(str(grabid))
            pkgidbox.setText(storage[0])
            pkgidname.setText(storage[1])
            pkgiddest.setText(storage[2])
            pkgidweight.setText(storage[3])
            pkgidCID.setText(storage[4])
        
        # if click exit button        
        if mouseCoord.x >= 450 and mouseCoord.x <= 590 and mouseCoord.y >= 240 and mouseCoord.y <= 290:
            print ("Exit function")
            win2.close()
            func_running = False
            # run event handler for main menu
            detect_actions()
        
        # if click print func button
        if mouseCoord.x >= 300 and mouseCoord.x <= 420 and mouseCoord.y >= 240 and mouseCoord.y <= 290:
            # open win3 with print functions
            win3 = GraphWin("Print Functions - QMS", 600, 300)
            win3.setBackground('purple')   
            # run print menu event handler
            print_menu()
            
        # if click add func button
        if mouseCoord.x >= 10 and mouseCoord.x <= 160 and mouseCoord.y >= 240 and mouseCoord.y <= 290:
            # open win4 with add package function
            win4 = GraphWin("Add Package Window - QMS", 600, 300)
            win4.setBackground('lightgreen')       
            # run add menu event handler
            add_menu()        
            
        # if click del func button
        if mouseCoord.x >= 170 and mouseCoord.x <= 290 and mouseCoord.y >= 240 and mouseCoord.y <= 290:
            # open win4 with add package function
            win5 = GraphWin("Delete Package Window - QMS", 600, 300)
            win5.setBackground('orange')        
            # run delete menu event handler
            del_menu()                    
            

# Description: A new window that has buttons to initiate delete package function.
#              it calls deletePackageByIDInside in Shipyard class which finds the
#              container and used the deltePackageByID method in the container
#              class to remove the package.
#
# Functions used: deletePackageByIDInside, deletePackageByID
#
# deletePackageByIDInside finds the container holding the package and passes
# package id to deletePackageByID to delete the package
def del_menu():
    # Text Displays for information on packages
    del_text = Text(Point(180,20), "Delete Package From System")
    del_text.setSize(18)
    del_text.draw(win5)
    delpkgid=Text(Point(120,50),"Package ID: ")
    delpkgid.draw(win5)                
    del_running = True
    
    # Create entry boxes to get & set input data
    delpkgidbox = Entry(Point(300,50), 20)
    delpkgidbox.setText("1")
    delpkgidbox.draw(win5)                
    
    # Draws the rectangle splash box
    delsearchbox = Rectangle(Point(400, 40), Point(580,100))
    delsearchbox.setFill('green')
    delsearchbox.draw(win5)  
    
    # Search text to tell user to click here to interact                    
    delpkgsearch=Text(Point(490,50),"<---  Enter Package ID")
    delpkgsearch.draw(win5)
    delpkgsearch1=Text(Point(490,80),"Click to delete package")
    delpkgsearch1.draw(win5)
    
    # Exit button
    delexitFunc = Rectangle(Point(450, 240), Point(590, 290)) # box for exit
    delexitFunc.setFill('red')
    delexitText = Text(Point(520, 265), "Exit")
    delexitFunc.draw(win5)
    delexitText.draw(win5)    
        
    while del_running:
        # listen for mouse click on package window
        mouseCoord = win5.getMouse()
            
        # if click exit button        
        if mouseCoord.x >= 450 and mouseCoord.x <= 590 and mouseCoord.y >= 240 and mouseCoord.y <= 290:
            print ("Exit function")
            win5.close()
            del_running = False
            # run specify package event menu handler
            detect_pkg_actions()  
            
        # if click search button
        if mouseCoord.x >= 400 and mouseCoord.x <= 580 and mouseCoord.y >= 20 and mouseCoord.y <= 100:
            print("Delete package clicked")
            one = delpkgidbox.getText()
            
            # perform search and grab results change to search inside containers function after from shipyard
            thereturn = q.deletePackageByIDInside(str(one))
            print ("Package Delete Clicked")
            delpkgidbox.setText(str(one) + " is removed!")
            if (thereturn[0] == "Package Not Found"):
                delpkgidbox.setText("Package not found!")

            
# Description: A new window that has buttons to initiate print functions.
#              Destination Box is used to specific destination.
#
# Functions used: createPackage, traverseGrabPackageInside, traverseGrabPackage 
#
# createPackage creates a package after getting information from the user
# traverseGrabPackageInside is used to make sure unique package id is ready
def add_menu():

    # Text Displays for information on packages
    add_text = Text(Point(140,20), "Add Package to System")
    add_text.setSize(18)
    add_text.draw(win4)
    addpkgid=Text(Point(120,50),"Package ID: ")
    addpkgid.draw(win4)                
    addpkgowner=Text(Point(120,90),"Package Owner: ")
    addpkgowner.draw(win4)                                
    addpkgdest=Text(Point(120,130),"Package Destination: ")
    addpkgdest.draw(win4)                                
    addpkgweight=Text(Point(120,170),"Package Weight: ")
    addpkgweight.draw(win4)    