/home/caleb/ASDV-Java/Semester 3/Assignments/MP5-Binary-Files_CalebFontenot/src/com/calebfontenot/mp5/files_calebfontenot/AddressBookFX.java
/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
 */
package com.calebfontenot.mp5.files_calebfontenot;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;

/**
 *
 * @author caleb
 */
public class AddressBookFX extends Application {

    static File addressBook = new File("AddressBookFX.dat");
    static int addressArrayPointer = 0;
    static ArrayList<AddressBookEntry> addressArray = new ArrayList<>();
    static TextField nameTextField = new TextField();
    static TextField streetTextField = new TextField();
    static TextField cityTextField = new TextField();
    static TextField stateTextField = new TextField();
    static TextField zipTextField = new TextField();
    static Label addressBookCounter = new Label("Items in address book:");
    static Label indexLabel = new Label();

    @Override
    public void start(Stage stage) throws Exception
    {
        getData();
        BorderPane primaryBorderPane = new BorderPane();
        GridPane textFieldGridPane = new GridPane();
        GridPane addressFieldPane = new GridPane();
        GridPane buttonFieldPane = new GridPane();

        // Text fields / labels
        textFieldGridPane.add(new Label("Name"), 0, 0);
        textFieldGridPane.add(new Label("Street"), 0, 1);
        textFieldGridPane.add(new Label("City"), 0, 2);
        addressFieldPane.add(new Label("State"), 2, 0);
        addressFieldPane.add(new Label("ZIP"), 4, 0);
        textFieldGridPane.add(nameTextField, 1, 0);
        textFieldGridPane.add(streetTextField, 1, 1);
        textFieldGridPane.add(addressFieldPane, 1, 2);
        addressFieldPane.add(cityTextField, 1, 0);
        addressFieldPane.add(stateTextField, 3, 0);
        addressFieldPane.add(zipTextField, 5, 0);
        textFieldGridPane.getColumnConstraints().add(new ColumnConstraints(50));
        primaryBorderPane.setTop(textFieldGridPane);

        // Buttons
        Button addButton = new Button("Add");
        Button firstButton = new Button("First");
        Button nextButton = new Button("Next");
        Button previousButton = new Button("Previous");
        Button lastButton = new Button("Last");
        Button updateButton = new Button("Update");
        buttonFieldPane.add(indexLabel, 0, 0);
        buttonFieldPane.add(addButton, 1, 0);
        buttonFieldPane.add(firstButton, 2, 0);
        buttonFieldPane.add(nextButton, 3, 0);
        buttonFieldPane.add(previousButton, 4, 0);
        buttonFieldPane.add(lastButton, 5, 0);
        buttonFieldPane.add(updateButton, 6, 0);
        buttonFieldPane.add(addressBookCounter, 7, 0);

        primaryBorderPane.setBottom(buttonFieldPane);
        buttonFieldPane.setAlignment(Pos.CENTER);
        buttonFieldPane.setHgap(10);

        addButton.setOnAction(e -> {
            addressArray.add(new AddressBookEntry());
            updateData();
        });
        firstButton.setOnAction(e -> {
            addressArrayPointer = 0;
            getEntry(addressArrayPointer);
        });
        nextButton.setOnAction(e -> {
            if (addressArrayPointer >= addressArray.size() - 1) {
                addressArrayPointer = 0;
            } else {
                addressArrayPointer++;
            }
            getEntry(addressArrayPointer);
        });
        previousButton.setOnAction(e -> {
            if (addressArrayPointer > 0) {
                addressArrayPointer--;
            } else {
                addressArrayPointer = addressArray.size() - 1;
            }
            getEntry(addressArrayPointer);
        });
        lastButton.setOnAction(e -> {
            addressArrayPointer = addressArray.size() - 1;
            getEntry(addressArrayPointer);
        });
        updateButton.setOnAction(e -> {
            AddressBookEntry entry = addressArray.get(addressArrayPointer);
            entry.setName(nameTextField.getText());
            entry.setCity(nameTextField.getText());
            entry.setStreet(streetTextField.getText());
            entry.setCity(cityTextField.getText());
            entry.setState(stateTextField.getText());
            entry.setZip(zipTextField.getText());
            updateData();
        });

        // init fields with data from first entry
        getEntry(0);

        Scene scene = new Scene(primaryBorderPane);
        stage.setScene(scene);
        stage.show();
    }

    public static AddressBookEntry getEntry(int index)
    {
        AddressBookEntry entry = addressArray.get(index);
        indexLabel.setText("Current index: " + index);
        addressBookCounter.setText("Items in address book: " + addressArray.size());
        nameTextField.setText(entry.getName());
        streetTextField.setText(entry.getStreet());
        cityTextField.setText(entry.getCity());
        stateTextField.setText(entry.getState());
        zipTextField.setText(entry.getZip());
        return entry;
    }

    public static void updateData()
    {
        try (ObjectOutputStream fileStream = new ObjectOutputStream(new FileOutputStream(addressBook))) {
            fileStream.writeObject(addressArray);
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }

    public static void getData()
    {
        if (!addressBook.exists()) {
            addressArray.add(new AddressBookEntry());
            updateData();
        } else {
            try (ObjectInputStream fileStream = new ObjectInputStream(new FileInputStream(addressBook))) {
                addressArray = (ArrayList<AddressBookEntry>) fileStream.readObject();
            } catch (IOException ex) {
                System.out.println(ex);
            } catch (ClassNotFoundException ex) {
                System.out.println(ex);
            }
        }
    }

    public static void main(String[] args)
    {
        launch();
    }
}

class AddressBookEntry implements Serializable {

    private String name;
    private String street;
    private String city;
    private String state;
    private String zip;

    public AddressBookEntry()
    {
        this.name = "Enter a name here.";
        this.street = "Enter a street here.";
        this.city = "Enter a city here.";
        this.state = "Enter a state here.";
        this.zip = "Enter a zip here.";
    }

    public AddressBookEntry(String name, String street, String city, String state, String zip)
    {
        this.name = name;
        this.street = street;
        this.city = city;
        this.state = state;
        this.zip = zip;
    }

    public String getZip()
    {
        return zip;
    }

    public void setZip(String zip)
    {
        this.zip = zip;
    }

    public String getState()
    {
        return state;
    }

    public void setState(String state)
    {
        this.state = state;
    }

    public String getCity()
    {
        return city;
    }

    public void setCity(String city)
    {
        this.city = city;
    }

    public String getStreet()
    {
        return street;
    }

    public void setStreet(String street)
    {
        this.street = street;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

}