"""
AIRLINE RESERVATION SYSTEM
DEVELOPERS
    Stephen Tafoya
    Ryan Hamilton

**** All comments will have ST or RH for ****
**** Stephen Tafoya or Ryan Hamilton     ****

GUI CREATION FILE - CREATES AND HANDLES GUI ELEMENTS
"""

# class WindowObject()


###############################
# IMPORT STATEMENTS
#       This handles all imports required for
#       the GUI to function.
###############################
from mainGui import mainGui                 # ST import mainGui
from mainGui import window_edit             # ST import window_edit
from mainGui import intro                   # ST import intro

import locale                               # ST for money format

from PyQt5 import QtWidgets as QWgts        # ST import QtWidgets (for gui)
# ST import QtMultimedia (for sound)
from PyQt5 import QtMultimedia as QMedia
# ST import QtGui (for animated gif)
from PyQt5 import QtGui
# ST import QtCore (to hide borders for animation)
from PyQt5 import QtCore


locale.setlocale(locale.LC_ALL, '')  # ST set localtime


def findTbl(tbl, item):  # ST simple find in table function
    """
        CODER: Stephen Tafoya
        FUNCTION:
            Used by several Querries from sql database
            returns if item is found
    """
    for index in tbl:  # ST itterate each item
        if index == item:  # ST check if index is item
            return True  # ST return True

    return False  # ST return False

###############################
# INTRO_WINDOW
#   programmer: Ryan Hamilton
#   desc: Create an object to handle intro gui
#   Documentation:
#       Creates the intro window, handles display of gif image and playing of audio file
#       Closes and runs main window. takes main window as an argument
###############################


class INTRO_WINDOW(QWgts.QMainWindow, intro.Ui_MainWindow):
    def __init__(self, master, parent=None):
        """
            CODER: Stephen Tafoya
            Function called on creation of an
                Intro_Window
        """
        super(INTRO_WINDOW, self).__init__(parent)  # ST
        self.setupUi(self)  # ST

        self.master = master  # ST stores master

        # ST make it borderless
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

        # add playable gif animation
        self.movie = QtGui.QMovie(
            "resource/planecrash.gif")  # RH load animated

        # RH apply to viewarea
        self.ViewArea.setMovie(self.movie)
        # RH change gif animation speed
        self.movie.setSpeed(100)
        self.movie.start()  # RH start the movie playback
        self.movie.setScaledSize(QtCore.QSize(500, 500))  # RH setScale

        self.PlaneCrashSound = QMedia.QSound(
            "resource/introswell.wav")  # RH load a QSound from Resource
        self.PlaneCrashSound.play()  # RH make sound play

        self.timer = QtCore.QTimer(self)  # ST create timer
        self.timer.setInterval(4000)      # ST make it sleep for 4 seconds
        # ST connect its timeout function
        self.timer.timeout.connect(self.finishtimer)
        self.timer.start()            # ST start timer

    def finishtimer(self):  # called on finish timer
        self.timer.stop()  # stops timer
        self.hide()  # hides widget
        self.master.show()  # shows master form


###############################
# COMBOBOX
#   programmer: Stephen Tafoya
#   desc: combobox class
#   Documentation:
#       created to handle currentindexchanged
#       used in the qtablewidget to handle updates.
###############################

class COMBOBOX(QWgts.QComboBox):
    def __init__(self, index, master):  # ST
        # ST call parent function
        super(COMBOBOX, self).__init__()
        self.index = index  # ST store index
        self.master = master  # ST store master
        super(COMBOBOX, self).currentIndexChanged[
            int].connect(self._currentIndexChanged)  # ST connect parent function

    # ST accessor for index
    def getPersonIndex(self):
        return self.index  # ST

    # ST cloned parent function
    def _currentIndexChanged(self, index):
        self.master.personList[self.index].setSeatType(index)  # ST changes value in person class


###############################
# COMBOBOXSEAT
#   programmer: Stephen Tafoya
#   desc: combobox class
#   Documentation:
#       created to handle currentindexchanged
#       inherets from COMBOBOX
#       used to keep track of seating in qtablewidget
###############################

class COMBOBOXSEAT(COMBOBOX):  # ST
    def __init__(self, index, master):  # ST
        super(COMBOBOXSEAT, self).__init__(
            index, master)  # ST call parent function

    def _currentIndexChanged(self, index):  # ST
        self.master.personList[self.index].setIsIsle(
            {1: True, 0: False}[index])  # ST


###############################
# SPINBOX
#   programmer: Stephen Tafoya
#   desc: spinbox class
#   Documentation:
#       created to handle currentindexchanged
#       inherets from qspinbox
###############################

class SPINBOX(QWgts.QSpinBox):  # ST
    def __init__(self, index, master=None):  # ST call parent function
        super(SPINBOX, self).__init__()  # ST
        self.index = index  # ST
        self.master = master  # ST
        super(SPINBOX, self).valueChanged.connect(self._valueChanged)  # ST

    def _valueChanged(self):  # ST
        self.master.personList[self.index].setBags(self.value())  # ST


###############################
# NAMELINEEDIT
#   programmer: Stephen Tafoya
#   desc: spinbox class
#   Documentation:
#       Handle The name box for the tablewidget
#       simplify by putting 3 widgets in a layout together
#       adds 3 lineedits
###############################

class NAMELINEEDIT(QWgts.QWidget):  # ST
    def __init__(self, index, master, parent=None):  # ST
        super(NAMELINEEDIT, self).__init__(parent)  # ST

        self.index = index  # ST define index
        self.master = master  # ST define master

        # ST create a Horizonatl Layout
        layout = QWgts.QHBoxLayout()

        layout.setContentsMargins(0, 0, 0, 0)  # ST remove margins
        layout.setSpacing(0)  # ST remove spacing

        # ST add all three lineedit boxes
        self.firstN = QWgts.QLineEdit()
        self.middlN = QWgts.QLineEdit()  # ST
        self.lastN = QWgts.QLineEdit()  # ST

        # Connect all change functions
        self.firstN.textChanged.connect(self.fn_changed)  # ST
        self.middlN.textChanged.connect(self.mn_changed)  # ST
        self.lastN.textChanged.connect(self.ln_changed)  # ST

        # ST insert widgets to layout
        layout.addWidget(self.firstN)
        layout.addWidget(self.middlN)  # ST
        layout.addWidget(self.lastN)  # ST

        # ST apply the layout to this
        self.setLayout(layout)

    def fn_changed(self, str):                              # ST if first name changes
        self.master.personList[self.index].setFName(str)    # ST update person

    def mn_changed(self, str):                              # ST if middle name changes
        self.master.personList[self.index].setMName(str)    # ST update person

    def ln_changed(self, str):                              # ST if last name changes
        self.master.personList[self.index].setLName(str)    # ST update person

    def setName(self, f, m, l):  # ST applies all names to line edit boxes
        self.firstN.setText(f)  # ST
        self.middlN.setText(m)  # ST
        self.lastN.setText(l)  # ST


###############################
# MAIN_WINDOW
#   programmer: Stephen Tafoya and Ryan Hamilton
#   desc: Create a main object to handle gui creation
#   Documentation:
#       Uses several custom classes,
#       has 4 pages, page 1 handles flight details
#       page 2 handles passenger reservations
#       page 3 handles contact info and special instructions
#       page 4 handles payment and finish
###############################

class MAIN_WINDOW(QWgts.QMainWindow, mainGui.Ui_MainWindow):  # ST

    def __init__(self, database, parent=None):  # ST
        super(MAIN_WINDOW, self).__init__(parent)  # ST
        self.setupUi(self)  # ST

        self.db = database[0]  # ST  loads database containing airports
        self.fdb = database[1]  # ST   loads database containing flights

        self.EditWindow = None  # ST  Makes sure edit window is non existent
        self.personList = []  # ST  declares empty personlist

        """
            Connect Buttons for all pages
        """
        # binds the click function to self.BACK
        self.BACK_BUTTON.clicked.connect(self.BACK)  # ST
        self.BACK_BUTTON.setDisabled(True)  # ST

        # binds the click function to self.FORWARD
        self.FORWARD_BUTTON.clicked.connect(self.FORWARD)  # ST

        """
            Connects buttons for page 2
        """
        self.ADD_BUTTON.clicked.connect(self.ADD)  # ST
        self.REMOVE_BUTTON.clicked.connect(self.REMOVE)  # ST

        self.windows = [        # ST simplify calling window check functions
            self.window_1,      # ST called by next function page 1
            self.window_2,      # ST called by next function page 2
            self.window_3,      # ST called by next function page 3
            self.window_4,      # ST called by next function page 4
        ]

        """
            setup qtablewidget on page 2
        """
        self.EDIT_TABLE.setSelectionMode(
            QWgts.QAbstractItemView.ExtendedSelection)  # ST makes it so rows select
        self.EDIT_TABLE.setSelectionBehavior(
            QWgts.QAbstractItemView.SelectRows)  # ST disables selecting columns

        head = self.EDIT_TABLE.horizontalHeader()  # ST
        head.setSectionResizeMode(1, QWgts.QHeaderView.Stretch)  # ST change fitting for table
        head.setSectionResizeMode(2, QWgts.QHeaderView.Stretch)  # ST change fitting for table
        head.setSectionResizeMode(3, QWgts.QHeaderView.Stretch)  # ST change fitting for table
        self.EDIT_TABLE.setColumnWidth(0, 250)          # ST force width of first column
        head.setSectionResizeMode(0, QWgts.QHeaderView.Fixed)    # ST make it unchangeable

        """
            Connect page 1 buttons
        """
        self.CB_O_COUNTRY.currentIndexChanged[
            int].connect(self.CBOCountry)     # ST
        self.CB_O_STATE.currentIndexChanged[
            int].connect(self.CBOState)       # ST
        self.CB_O_AIRPORT.currentIndexChanged[
            int].connect(self.CBOAirport)     # ST

        self.CB_D_COUNTRY.currentIndexChanged[
            int].connect(self.CBDCountry)     # ST
        self.CB_D_STATE.currentIndexChanged[
            int].connect(self.CBDState)       # ST

        self.CB_O_COUNTRY.addItem("")   # ST makes sure first line is blank

        self.CB_D_COUNTRY.addItem("")   # ST makes sure first line is blank

        countries = self.db.loadCountries()     # RH loads countries from AirDB
        for i in range(0, len(countries)):      # RH loop for adding countries
            country = countries[i]              # RH Extracts countries from list
            if self.CB_O_COUNTRY.findText(country) == -1:   # RH Removes repeats
                self.CB_O_COUNTRY.addItem(country)          # RH adds to origin
                self.CB_D_COUNTRY.addItem(country)          # RH adds ti destination

        """
            Handle PayPal Button
        """
        icon = QtGui.QIcon()                # ST
        icon.addPixmap(QtGui.QPixmap("resource/paypal.jpg"))    # ST

        self.PAYPAL_BUTTON.setIcon(icon)                        # ST
        self.PAYPAL_BUTTON.setIconSize(QtCore.QSize(198, 88))   # ST
        self.PAYPAL_BUTTON.setHidden(True)                      # ST

        """
            Connect page 4 buttons
        """
        self.RB_CREDIT_CARD.toggled.connect(self.PayChange)     # ST
        self.BILLING_CHECKBOX.stateChanged.connect(self.BillingChange)  # ST

        self.SUBMIT.clicked.connect(self.SUBMITCLICK)                # ST

    def SUBMITCLICK(self):               # ST handles the final steps
        """
            CODER: Stephen Tafoya
            Called on clicking the Final button on page4
            Makes sure all input is met
            and then creates strings and ints to
            send to the sql database
        """
        if not self.RB_CREDIT_CARD.isChecked() or self.RB_CREDIT_CARD.isChecked() and self.CARD_NUMBER.text() != "" and self.CARD_CODE.text() != "" and self.CARD_DATE1.text() != "" and self.CARD_NAME.text != "":
            if self.BILLING_CHECKBOX.isChecked() or not self.RB_CREDIT_CARD.isChecked() or not self.BILLING_CHECKBOX.isChecked() and self.BILLING_STREET.text() != "" and self.BILLING_CITY.text() != "" and self.BILLING_STATE.text() != "" and self.BILLING_CODE.text() != "":
                OAirport = self.db.findAirport(
                    self.CB_O_AIRPORT.currentText())  # ST
                DAirport = self.db.findAirport(
                    self.CB_D_AIRPORT.currentText())  # ST

                flightInfo = ""  # ST create empty string
                flightInfo += {True: "1",  # ST add all nessisairy info to flight
                               False: "0"}[self.RB_ONE_WAY.isChecked()]  # ST
                flightInfo += ";"  # ST
                flightInfo += {True: "1",  # ST
                               False: "0"}[self.RB_DIRECT.isChecked()]  # ST
                flightInfo += ";"  # ST

                flightInfo += (self.NAME_FIRST.text() + ";" +
                               self.NAME_MIDDLE.text() + ";" + self.NAME_LAST.text())  # ST
                flightInfo += ";" + self.EMAIL.text()  # ST
                flightInfo += ";" + self.PHONE_BOX1.text() + self.PHONE_BOX2.text() + \
                    self.PHONE_BOX3.text()  # ST
                flightInfo += ";" + self.SPECIAL_INSTRUCTIONS.toPlainText()  # ST

                flightAddress = ""  # ST
                flightAddress += self.ADDRESS_STREET.text() + ";" + self.ADDRESS_CITY.text() + \
                    ";" + self.ADDRESS_STATE.text() + ";" + self.ADDRESS_CODE.text()  # ST

                billingAddress = ""  # ST create empty string
                if self.BILLING_CHECKBOX.isChecked():  # ST if we use same billing address as contact
                    billingAddress = flightAddress  # ST just copy contact address
                else:  # ST
                    billingAddress += self.BILLING_STREET.text() + ";" + self.BILLING_CITY.text() + \
                        ";" + self.BILLING_STATE.text() + ";" + self.BILLING_CODE.text()  # ST
                costtype = {True: 1, False: 0}[
                    self.RB_CREDIT_CARD.isChecked()]  # ST use a dict to convert booleans to ints
                cardinfo = ""  # ST
                cardinfo += self.CARD_NUMBER.text() + ";" + self.CARD_CODE.text() + ";" + \
                    self.CARD_DATE1.text() + ";" + self.CARD_NAME.text()  # ST
                cost = self.priceTotal()  # ST gets cost from cost function

                self.fdb.insertFlight(
                    [OAirport, DAirport, flightInfo, flightAddress, billingAddress, cost, costtype, cardinfo])

                flightid = self.fdb.nextIndex()  # ST find flight index from db

                for person in self.personList:  # ST Itterate through all persons,
                    name = person.getName()  # ST     input the person's data into the
                    sname = name[0] + name[1] + name[2]  # ST  person database
                    bags = person.getBags()  # ST
                    seating = str(person.getSeatType()) + ";" + \
                        str(person.isIsle())  # ST

                    self.fdb.insertPassenger(
                        [flightid, sname, bags, seating])  # ST

                self.close()  # ST close the main window

            else:
                showError("ERROR: No Billing info Provided.")  # ST show an error, input was not met
        else:
            showError("ERROR: missing credit info.")  # ST show an error, the input was not met

    def PayChange(self, enabled):   # ST
        """
            CODER: Stephen Tafoya
            Handles changeing element visibility on page 4
            called on all updates of first radio buttons
        """
        if enabled:                 # ST
            self.PAYPAL_BUTTON.setHidden(True)  # ST
            self.groupBox_2.setHidden(False)    # ST
            self.groupBox.setHidden(False)      # ST
            self.BILLING_CHECKBOX.setCheckState(0)  # ST
        else:
            self.PAYPAL_BUTTON.setHidden(False)     # ST
            self.groupBox_2.setHidden(True)     # ST
            self.groupBox.setHidden(True)       # ST

    def BillingChange(self, state):             # ST
        """
            CODER: Stephen Tafoya
            called on billing check box change
            on page 4
        """
        if state > 0:                           # ST
            self.groupBox.setHidden(True)       # ST
        else:
            self.groupBox.setHidden(False)      # ST

    def CBOCountry(self, index):  # ST called by combobox Country
        country = str(self.CB_O_COUNTRY.currentText())  # RH grabs entry in combobox country
        self.CB_O_STATE.clear()             # ST
        self.CB_O_STATE.addItem("")         # ST
        if index <= 0:                      # ST
            self.CB_O_STATE.setDisabled(True)   # ST
        else:
            self.CB_O_STATE.setDisabled(False)  # ST

            states = self.db.loadStates(country)    # RH loads states from AirDB
            for i in range(0, len(states)):         # RH loop to add states
                state = states[i]                   # RH extracts state from list
                self.CB_O_STATE.addItem(state)      # RH adds state to combobox

    def CBOState(self, index):  # ST called by combobox State
        state = str(self.CB_O_STATE.currentText())  # RH finds entry in state combobox
        self.CB_O_AIRPORT.clear()                   # ST
        self.CB_O_AIRPORT.addItem("")               # ST
        if index <= 0:                              # ST
            self.CB_O_AIRPORT.setDisabled(True)     # ST
        else:
            self.CB_O_AIRPORT.setDisabled(False)    # ST
            airports = self.db.loadAirports(state)  # RH loads airports from AirDB
            for i in range(0, len(airports)):       # RH loop to add airports
                airport = airports[i]               # RH extracts airport from list
                self.CB_O_AIRPORT.addItem(airport)  # RH adds airport to combobox

    def CBOAirport(self, index):  # ST called by combobox Airport
        if index <= 0:                              # ST
            self.CB_D_COUNTRY.setDisabled(True)     # ST
            self.CB_D_COUNTRY.setCurrentIndex(0)
        else:
            self.CB_D_COUNTRY.setDisabled(False)    # ST

    def CBDCountry(self, index):  # ST called by combobox Country
        country = str(self.CB_D_COUNTRY.currentText())  # RH gets entry from combobox country
        self.CB_D_STATE.clear()                     # ST
        self.CB_D_STATE.addItem("")                 # ST
        if index <= 0:                              # ST
            self.CB_D_STATE.setDisabled(True)       # ST
        else:
            self.CB_D_STATE.setDisabled(False)      # ST
            states = self.db.loadStates(country)    # RH loads states from AirDB
            for i in range(0, len(states)):         # RH loop to add states
                state = states[i]                   # RH extracts state from list
                if state != self.CB_O_STATE.currentText():  # ST
                    self.CB_D_STATE.addItem(state)          # ST

    def CBDState(self, index):                      # ST
        state = str(self.CB_D_STATE.currentText())  # RH gets entry from combobox state
        self.CB_D_AIRPORT.clear()                   # ST
        self.CB_D_AIRPORT.addItem("")               # ST
        if index <= 0:                              # ST
            self.CB_D_AIRPORT.setDisabled(True)     # ST
        else:
            self.CB_D_AIRPORT.setDisabled(False)    # ST
            airports = self.db.loadAirports(state)  # RH loads airports from AirDB
            for i in range(0, len(airports)):       # RH loop to add airports
                airport = airports[i]               # RH extracts airport from list
                self.CB_D_AIRPORT.addItem(airport)  # RH adds airport to box

    def window_1(self):                                 # RH checks window 1 inputs
        oCountry = self.CB_O_COUNTRY.currentIndex()     # RH
        oState = self.CB_O_STATE.currentIndex()         # RH
        oAirport = self.CB_O_AIRPORT.currentIndex()     # RH
        dCountry = self.CB_D_COUNTRY.currentIndex()     # RH
        dState = self.CB_D_STATE.currentIndex()         # RH
        dAirport = self.CB_D_AIRPORT.currentIndex()     # RH

        # RH Shows error if boxs not filled in
        if oCountry <= 0 or oState <= 0 or oAirport <= 0 or dCountry <= 0 or dState <= 0 or dAirport <= 0:
            showError("ERROR: did not fill in required information.")
            return False                    # RH
        else:
            return True                     # RH

    def window_2(self):                     # RH checks window 2 inputs
        if len(self.personList) == 0:       # RH
            showError("ERROR: no passangers added.")  # RH shows error if missing info
            return False                    # RH
        else:                               # RH
            return True                     # RH

    def window_3(self):                     # RH checks window 3 inputs
        if self.NAME_FIRST.text() == "" or self.NAME_LAST.text() == "" or self.EMAIL.text() == "" or self.PHONE_BOX1.text() == "" or self.PHONE_BOX2.text() == "" or self.PHONE_BOX3.text() == "" or self.ADDRESS_STREET.text() == "" or self.ADDRESS_CITY.text() == "" or self.ADDRESS_STATE.text() == "" or self.ADDRESS_CODE.text() == "":
            showError("ERROR: please fill out required information.")  #shows error if missing info
            return False                    # RH
        else:
            subtotal = self.priceSubtotal()     # ST
            tax = self.priceTax()               # ST
            total = self.priceTotal()           # ST

            # ST
            self.SUBTOTAL_LABEL.setText(
                "Subtotal: " + locale.currency(subtotal, grouping=True))
            self.TAX_LABEL.setText(
                "Tax: " + locale.currency(tax, grouping=True))
            self.TOTAL_LABEL.setText(
                "Total: " + locale.currency(total, grouping=True))
            return True                         # ST

    def window_4(self):  # checks window 4 inputs
        return True

    def updateTable(self):  # ST
        """
            CODER: Stephen Tafoya
            Function called whenever a change is made to the personList
            This makes sure all persons in PersonList are displayed correctly
        """
        self.EDIT_TABLE.setRowCount(len(self.personList))   # ST

        for i in range(len(self.personList)):               # ST
            name = self.personList[i].getName()             # ST
            bags = self.personList[i].getBags()             # ST
            seat = self.personList[i].getSeatType()         # ST
            isle = self.personList[i].isIsle()              # ST

            namebox = NAMELINEEDIT(i, self)                 # ST
            namebox.setName(name[0], name[1], name[2])      # ST

            number = SPINBOX(i, self)  # ST
            number.setMaximum(3)  # ST
            number.setMinimum(0)  # ST
            number.setValue(bags)  # ST

            cb_seat = COMBOBOX(i, self)  # ST
            cb_seat.addItem("Economy")  # ST
            cb_seat.addItem("Busness")  # ST
            cb_seat.addItem("First Class")  # ST
            cb_seat.setCurrentIndex(seat)   # ST

            cb_isle = COMBOBOXSEAT(i, self)  # ST
            cb_isle.addItem("Isle")  # ST
            cb_isle.addItem("Window")  # ST
            cb_isle.setCurrentIndex({True: 1, False: 0}[isle])  # ST

            self.EDIT_TABLE.setCellWidget(i, 0, namebox)    # ST
            self.EDIT_TABLE.setCellWidget(i, 1, number)     # ST
            self.EDIT_TABLE.setCellWidget(i, 2, cb_seat)    # ST
            self.EDIT_TABLE.setCellWidget(i, 3, cb_isle)    # ST

    def ADD(self):                      # ST add data to tableview
        """
            CODER: Stephen Tafoya
            displays edit window
        """
        if self.EditWindow is None:     # ST check if a window is already open
            self.EditWindow = EDIT_WINDOW(self)     # ST if not create new one
            self.EditWindow.EDIT_WIN_LABEL.setText("Add New Entry")     # ST
            self.EditWindow.exec_()     # ST and show it to the world

    def REMOVE(self):                   # ST
        """
            CODER: Stephen Tafoya
            removes selected row person
        """
        cur_row = self.EDIT_TABLE.currentRow()  # ST
        if cur_row < 0:                 # ST
            return                      # ST

        length = len(self.personList)   # ST

        self.personList = self.personList[
            0:cur_row] + self.personList[cur_row + 1:length]    # ST
        self.updateTable()              # ST

    def canBACK(self):  # ST determines if the user can go back
        cur_I = self.tabWidget.currentIndex()   # ST

        if cur_I < 1:  # ST if we are at first tab dont go back
            return False

        return True    # ST if all returns are passed return True

    def BACK(self):    # ST
        """
            CODER: Stephen Tafoya
            Goes back 1 page if possible
        """
        if self.canBACK():  # ST check if we can go back
            self.tabWidget.setCurrentIndex(self.tabWidget.currentIndex() - 1)

        if not self.canBACK():  # ST
            self.BACK_BUTTON.setDisabled(True)  # ST

        if self.canFORWARD():                   # ST
            self.FORWARD_BUTTON.setDisabled(False)  # ST

    def canFORWARD(self):  # ST determins if the user can go forward

        cur_I = self.tabWidget.currentIndex()  # ST

        if cur_I > 2:   # ST check if we are at max tab
            return False

        return True     # ST if all others pass return True

    def FORWARD(self):  # ST
        """
            CODER: Stephen Tafoya
            Goes forward 1 page if possible
        """
        cur_I = self.tabWidget.currentIndex()   # ST
        if not self.windows[cur_I]():           # ST check if we can progress
            return      # ST

        if self.canFORWARD():   # ST check if we can go forward
            self.tabWidget.setCurrentIndex(self.tabWidget.currentIndex() + 1)

        if not self.canFORWARD():   # ST
            self.FORWARD_BUTTON.setDisabled(True)   # ST

        if self.canBACK():          # ST
            self.BACK_BUTTON.setDisabled(False)     # ST

    def priceSubtotal(self):    # RH finds the subtotal price
        interNational = False   # RH
        subtotal = 0            # RH
        o_country = self.CB_O_COUNTRY.currentText()     # RH
        d_country = self.CB_D_COUNTRY.currentText()     # RH
        if o_country != d_country:      # RH
            interNational = True        # RH
        else:                   # RH
            interNational = False       # RH

        if interNational is False:      # RH
            pricePerPerson = 200        # RH
        else:                           # RH
            pricePerPerson = 500        # RH

        for i in range(0, len(self.personList)):    # RH
            bags = self.personList[i].getBags()     # RH
            seat = self.personList[i].getSeatType()  # RH
            if seat == "Economy":         # RH
                seatPrice = 50            # RH
            elif seat == "Busness":       # RH
                seatPrice = 75            # RH
            else:
                seatPrice = 100           # RH
            subtotal += (pricePerPerson + seatPrice + 25 * bags)
        return subtotal                   # RH

    def priceTax(self):         # RH finds the amount of tax for subtotal
        subtotal = self.priceSubtotal()  # RH
        tax = (subtotal * .051)         # RH
        return tax                      # RH

        # RH adds tax and subtotal together for total.
    def priceTotal(self):
        subtotal = self.priceSubtotal()  # RH
        tax = self.priceTax()            # RH
        total = (subtotal + tax)         # RH
        return total                     # RH


###############################
# ERROR_DISPLAY
#   programmer: Stephen Tafoya
#   desc: Create an error message
#   Documentation:
#       Pretty self explanitory
###############################
def showError(text):            # RH function that gets called to display errors
    msg = QWgts.QMessageBox()   # RH
    msg.setIcon(QWgts.QMessageBox.Critical)  # RH

    msg.setText(text)       # RH
    msg.exec_()             # RH


###############################
# EDIT_WINDOW
#   programmer: Stephen Tafoya
#   desc: Create an object to edit
#   Documentation:
#       Pretty self explanitory
###############################

class EDIT_WINDOW(QWgts.QDialog, window_edit.Ui_Dialog):    # ST
    def __init__(self, master, parent=None):                # ST
        super(EDIT_WINDOW, self).__init__(master)           # ST

        self.setupUi(self)    # ST

        self.master = master  # ST store master

        self.buttonBox.button(QWgts.QDialogButtonBox.Cancel).clicked.connect(
            self.CANCEL)  # ST connect Cancel
        self.buttonBox.button(QWgts.QDialogButtonBox.Ok).clicked.connect(
            self.OK)  # ST connect ok

        self.BAGS_SLIDER.valueChanged.connect(
            self.BAGS_NUMBER.setValue)  # ST connect slider to num disp
        self.BAGS_NUMBER.valueChanged.connect(
            self.BAGS_SLIDER.setValue)  # ST connect num disp to slider

    def CANCEL(self):   # ST
        self.close()    # ST close itself
        self.master.EditWindow = None   # ST Reset place holder var

    def OK(self):       # ST
        if self.NAME_FIRST.text() == "" or self.NAME_LAST.text() == "":
            showError("ERROR: did not supply a name")
            return      # ST

        name = [self.NAME_FIRST.text(
        ), self.NAME_MIDDLE.text(), self.NAME_LAST.text()]
        newPerson = PERSON(name, self.BAGS_NUMBER.value(), self.CB_SEATING.currentIndex(
        ), self.RB_WINDOW.isChecked())  # ST
        self.close()        # ST close itself
        self.master.EditWindow = None   # ST reset place holder var
        self.master.personList.append(newPerson)    # ST
        self.master.updateTable()       # ST

    def closeEvent(self, evnt):         # ST
        self.master.EditWindow = None   # ST


###############################
# PERSON CLASS
#   programmer: Stephen Tafoya
#   desc: create a person class that handles data handoff between gui and main
#   Documentation:
#       This is a person class that stores info for handling the seating for
#       the program. The person class takes a name, a number of bags, type of seating
#       isle seating, and any special instructions.
#       contains accessor and mutator functions and a str function
###############################
# Some Constant variables
SEAT_ECONOMY = 0  # constant for Economy seating
SEAT_BUSINESS = 1  # constant for Business seating
SEAT_FIRST_CLASS = 2  # constant for first class


class PERSON(object):
    """
        Simple person class stores
            name
            bags
            seating
                class and isle
            special
    """
    # construct( <list name>, <int bags>, <int seating>, <bool isle>, <list
    # special> )

    def __init__(self, _name, _bags, _seating, _isle, *_special):
        self.name = _name
        self.bags = _bags
        self.seat_type = _seating
        self.isle = _isle
        self.special = _special

    # Accessors
    def getName(self):  # ST return name
        return self.name

    def getBags(self):  # ST return bags
        return self.bags

    def getSeatType(self):  # ST return seat type
        return self.seat_type

    def isIsle(self):  # ST return if isle seat or not
        return self.isle

    def Special(self):  # ST return any special info
        return self.special

    # ST Pass all data at once function
    def format(self):
        return [self.name, self.bags, [self.seat_type, self.isle], self.special]

    # Mutators
    def setName(self, newName):     # ST update name
        self.name = newName         # ST

    def setFName(self, fName):      # ST
        self.name[0] = fName        # ST

    def setMName(self, mName):      # ST
        self.name[1] = mName        # ST

    def setLName(self, lName):      # ST
        self.name[2] = lName        # ST

    def setBags(self, newBags):     # ST update bags
        self.bags = newBags         # ST

    def setSeatType(self, newType):  # ST update seat type
        self.seat_type = newType    # ST

    def setIsIsle(self, newIsle):   # ST update if in isle
        self.isle = newIsle

    def setSpecial(self, *newSpecial):  # ST update special instructions
        self.special = newSpecial       # ST

    # String function
    def __str__(self):         # ST
        return self.name[0] + self.name[1] + self.name[2] + "\n" \
            "\t bags:" + str(self.bags) + "\n" \
            "\t seating:" + str(self.seat_type) + ", " + str(self.isle) + "\n" \
            "\t special:" + str(self.special) + "\n"


###############################
# MAIN FUNCTION
#   programmer: Stephen Tafoya
#   Documentation:
#       Function that handles dev work on gui,
#       not to be used for the main program, but is a
#       convenience function for development.
###############################


def main():  # ST debug function for working on gui
    print("Do not run this file! Run main.py instead!")


if __name__ == "__main__":  # ST if this is the file run, call the gui main function
    main()
