<file_sep>package front_end;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import back_end.DietaryAccount;
import back_end.Transaction;

public class DietaryAccountView extends JPanel implements ActionListener, Observer{
	private BarGraphView barGraph;
	private DietaryAccount dietaryAccount;
	private JTextField calBalanceTextField, prefField;
	private JLabel calBalanceLabel, newCalLabel, unusedCalLabel, mealCalLabel, snackCalLabel, sodaCalLabel, prefLabel, newPref;
	private JPanel maxCalPanel, prefPanel, graphLabelPanel, topPanel;
	private int mCal, snCal, soCal, totalCal;
	public DietaryAccountView(DietaryAccount dietaryAccount) {
		this.setLayout(new BorderLayout());
		
		this.dietaryAccount = dietaryAccount;

		this.maxCalPanel = new JPanel();
		this.prefPanel = new JPanel();
		this.topPanel = new JPanel();
		
		maxCalPanel.setLayout(new FlowLayout());
		prefPanel.setLayout(new FlowLayout());
		topPanel.setLayout(new BoxLayout(topPanel,1));
		
		this.calBalanceLabel = new JLabel("Daily Calories: " + this.dietaryAccount.getMaxCalBalance());
		this.maxCalPanel.add(this.calBalanceLabel);
		this.newCalLabel = new JLabel("        Set a New Daily Calorie Limit: ");
		this.maxCalPanel.add(this.newCalLabel);
		this.prefLabel = new JLabel("Preferences: " + this.dietaryAccount.getPreferences());
		this.prefPanel.add(prefLabel);
		this.newPref = new JLabel("   New Preference: ");
		this.prefPanel.add(newPref);
		
		this.calBalanceTextField = new JTextField(6);
		this.maxCalPanel.add(this.calBalanceTextField);
		this.prefField = new JTextField(12);
		this.prefPanel.add(this.prefField);	

		this.calBalanceTextField.addActionListener(this);
		this.prefField.addActionListener(this);
		
		topPanel.add(maxCalPanel);
		topPanel.add(prefPanel);
		
		this.add(topPanel, BorderLayout.NORTH);
		
		//this.transactionPanel = new JPanel();
		ArrayList<Transaction> transactions = this.dietaryAccount.getTransactions();

		mCal=snCal=soCal=0;
		for (int i = 0; i < transactions.size(); ++i) {
			mCal += transactions.get(i).getMealCal();
			snCal += transactions.get(i).getSnackCal();
			soCal += transactions.get(i).getSodaCal();
		}
		int nums[] = {dietaryAccount.getCalBalance(),mCal,snCal,soCal};
		barGraph = new BarGraphView(nums);
		
		this.add(barGraph, BorderLayout.CENTER);
		
		unusedCalLabel = new JLabel("Unused: " + dietaryAccount.getCalBalance());
		mealCalLabel = new JLabel("Meal: " + mCal);
		snackCalLabel = new JLabel("Snack: " + snCal);
		sodaCalLabel = new JLabel("Soda: " + soCal);
		
		graphLabelPanel = new JPanel();
		
		graphLabelPanel.setLayout(new FlowLayout(1,75,0));
		
		graphLabelPanel.add(unusedCalLabel);
		graphLabelPanel.add(mealCalLabel);
		graphLabelPanel.add(snackCalLabel);
		graphLabelPanel.add(sodaCalLabel);
		
		this.add(graphLabelPanel, BorderLayout.SOUTH);
		
	}

	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==calBalanceTextField)
		{
			int newCalBalance = this.dietaryAccount.getMaxCalBalance();
		
			try {
				String temp = calBalanceTextField.getText();
				newCalBalance= Integer.parseInt(temp);
			} catch (Exception ex){
				return;
				}
		
			this.dietaryAccount.setMaxCalBalance(newCalBalance);

			this.calBalanceLabel.setText("Daily Calories: " + this.dietaryAccount.getMaxCalBalance());
			
			ArrayList<Transaction> transactions = this.dietaryAccount.getTransactions();
			
			mCal=snCal=soCal=0;
			for (int i = 0; i < transactions.size(); ++i) {
				mCal += transactions.get(i).getMealCal();
				snCal += transactions.get(i).getSnackCal();
				soCal += transactions.get(i).getSodaCal();
			}
		
			int nums[] = {dietaryAccount.getCalBalance(),mCal,snCal,soCal};
			this.remove(barGraph);
			barGraph = new BarGraphView(nums);
			this.add(barGraph, BorderLayout.CENTER);
		
			unusedCalLabel.setText("Unused: " + dietaryAccount.getCalBalance());
			mealCalLabel.setText("Meal: " + mCal);
			snackCalLabel.setText("Snack: " + snCal);
			sodaCalLabel.setText("Soda: " + soCal);
		}
		if(e.getSource()==prefField)
		{
			if(prefField.getText().equals("Delete"))
				this.dietaryAccount.removePreferences();
			
			else
			{
				for(int i=0; i<dietaryAccount.getPreferences().size(); i++)
				{
					if(prefField.getText().toUpperCase().equals(dietaryAccount.getPreferences().get(i)))
							return;
				}
				this.dietaryAccount.addPreference(prefField.getText().toUpperCase());
				this.prefLabel.setText("Preferences: " + this.dietaryAccount.getPreferences());
			}
			
		}
		this.revalidate();
		this.repaint();
	}
	
	public void update(Observable o, Object arg)
	{
		this.calBalanceLabel.setText("Daily Calories: " + this.dietaryAccount.getMaxCalBalance());
		
		ArrayList<Transaction> transactions = this.dietaryAccount.getTransactions();
		
		mCal=snCal=soCal=0;
		for (int i = 0; i < transactions.size(); ++i) {
			mCal += transactions.get(i).getMealCal();
			snCal += transactions.get(i).getSnackCal();
			soCal += transactions.get(i).getSodaCal();
		}
	
		int nums[] = {dietaryAccount.getCalBalance(),mCal,snCal,soCal};
		this.remove(barGraph);
		barGraph = new BarGraphView(nums);
		this.add(barGraph, BorderLayout.CENTER);
	
		unusedCalLabel.setText("Unused: " + dietaryAccount.getCalBalance());
		mealCalLabel.setText("Meal: " + mCal);
		snackCalLabel.setText("Snack: " + snCal);
		sodaCalLabel.setText("Soda: " + soCal);
		
		this.revalidate();
		this.repaint();

	}
	

}
<file_sep>#Tue Mar 05 15:34:41 PST 2019
org.eclipse.core.runtime=2
org.eclipse.platform=4.10.0.v20181206-0815
<file_sep>package back_end;

import java.io.Serializable;

public class User implements Serializable {
	private String password;
	private ExpenseAccount expenseAccount;
	private DietaryAccount dietaryAccount;

	public User(String password) {
		this.password = <PASSWORD>;
		expenseAccount = new ExpenseAccount(0);
		dietaryAccount = new DietaryAccount(2000);
	}
	
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public ExpenseAccount getExpenseAccount() {
		return expenseAccount;
	}

	public DietaryAccount getDietaryAccount() {
		return dietaryAccount;
	}

	public void setExpenseAccount(ExpenseAccount expenseAccount) {
		this.expenseAccount = expenseAccount;
	}

	public void setDietaryAccount(DietaryAccount dietaryAccount) {
		this.dietaryAccount = dietaryAccount;
	}
}
<file_sep>package back_end;

import java.awt.Point;
import java.util.ArrayList;
import java.util.Observer;

public class Cafe extends FoodProvider{
	public Cafe(String name, ArrayList<Food> menu, Point location) {
		super(name, menu, location);
	}
	
	public String getPickupLocation()
	{
		return "Pickup your order at "+ this.getName();
	}
	
}
<file_sep>package front_end;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import back_end.Cafe;
import back_end.Food;
import back_end.FoodProvider;
import back_end.Transaction;
import back_end.User;

public class FoodProviderView extends JPanel implements ActionListener {
	private FoodProvider foodProvider;
	private JButton orderButton;
	private JLabel nameLabel;
	private JPanel menuPanel;
	private JCheckBox[] menuItems;

	public FoodProviderView(FoodProvider foodProvider) {
		this.setLayout(new BorderLayout());

		this.foodProvider = foodProvider;

		this.orderButton = new JButton("Order");
		this.orderButton.addActionListener(this);
		this.add(this.orderButton, BorderLayout.SOUTH);

		this.nameLabel = new JLabel(this.foodProvider.getName(), JLabel.CENTER);
		this.nameLabel.setFont(new Font("Serif", Font.BOLD, 16));
		this.add(this.nameLabel, BorderLayout.NORTH);

		this.menuPanel = new JPanel();
		this.menuPanel.setLayout(new BoxLayout(this.menuPanel, BoxLayout.Y_AXIS));
		ArrayList<Food> menuOptions = this.foodProvider.getMenu();
		this.menuItems = new JCheckBox[menuOptions.size()];

		for (int i = 0; i < menuOptions.size(); ++i) {
			JCheckBox menuItem = new JCheckBox(menuOptions.get(i).toString());
			this.menuItems[i] = menuItem;
			this.menuPanel.add(menuItem);
		}

		this.add(this.menuPanel, BorderLayout.CENTER);

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (MainView.currentUser != null) {
			User user = MainView.currentUser;
			ArrayList<Food> selectedItems = new ArrayList<Food>();

			for (int i = 0; i < this.menuItems.length; i++) {
				if (this.menuItems[i].isSelected()) {
					selectedItems.add(this.foodProvider.getMenu().get(i));
				}
			}

			Food[] selectedItemsArray = new Food[selectedItems.size()];
			selectedItemsArray = selectedItems.toArray(selectedItemsArray);

			Transaction transaction = new Transaction(user, selectedItemsArray);

			Boolean insufficientBalance = user.getExpenseAccount().getBalance() < transaction.getTotalCost();
			Boolean insufficientCalBal = user.getDietaryAccount().getCalBalance() < transaction.getCal();

			if (insufficientBalance) {
				JOptionPane.showMessageDialog(null, "Not enough balance in expense account");
			} else if (insufficientCalBal) {
				JOptionPane.showMessageDialog(null, "Exceeding your calorie balance");
			} else {
				this.foodProvider.updateAccounts(transaction);
				
				if (this.foodProvider instanceof Cafe) {
					JOptionPane.showMessageDialog(null, ((Cafe) this.foodProvider).getPickupLocation());
				} else {
					JOptionPane.showMessageDialog(null, "Vending machine has dispensed your food");
				}
				
				this.setVisible(false);
			}
		}
	}

	public FoodProvider getFoodProvider() {
		return foodProvider;
	}
}
<file_sep>package back_end;

import java.io.Serializable;
import java.util.ArrayList;

public class ExpenseAccount implements Serializable {
	private double balance;
	private ArrayList<Transaction> transactions;

	public ExpenseAccount(double balance) {
		this.balance = balance;
		this.transactions = new ArrayList<Transaction>();
	}

	public double getBalance() {
		return balance;
	}

	public void setBalance(double balance) {
		this.balance = balance;
	}
	
	private void decrementBalance(double amount) {
		this.setBalance(this.balance - amount);
	}

	public ArrayList<Transaction> getTransactions() {
		return transactions;
	}

	public void addTransaction(Transaction transactions) {
		this.transactions.add(transactions);
		this.decrementBalance(transactions.getTotalCost());
	}

	@Override
	public String toString() {
		return balance + ";" + transactions;
	}
}
<file_sep>package back_end;

import java.io.Serializable;

public class Soda extends Food implements Serializable {

	public Soda(String name, int CalCount, double price) {
		super(name, CalCount, price);
	}
}
<file_sep>package front_end;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JTabbedPane;

import back_end.Cafe;
import back_end.DietaryAccount;
import back_end.ExpenseAccount;
import back_end.Food;
import back_end.Meal;
import back_end.User;
import back_end.UserManager;
import back_end.UserValidator;

public class MainView implements Observer {

	public static User currentUser;
	public static ExpenseAccountView expenseAccountView;
	public static DietaryAccountView dietaryAccountView;

	private JFrame frame;
	private JTabbedPane tabbedPane;
	private UserManager userData;
	private CampusMapView mapView;
	
	public MainView() {
		currentUser = null;

		this.frame = new JFrame("CampusSmartCafe");
		this.frame.setLayout(new BorderLayout());

		this.tabbedPane = new JTabbedPane();
		this.userData = new UserManager();
		this.userData.readFromFile();

		UserValidator userValid = new UserValidator(this.userData);
		LoginTotalView loginView = new LoginTotalView(userValid, this);

		this.tabbedPane.addTab("Login", loginView.getLoginPanel());

		this.frame.add(this.tabbedPane, BorderLayout.CENTER);

		this.frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				userData.writeToFile();
			}
		});

		this.frame.setSize(600, 800);
		this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.frame.setLocationRelativeTo(null);
		this.frame.setVisible(true);
	}

	@Override
	public void update(Observable o, Object arg) {
		User user = (User) arg;
		MainView.currentUser = user;

		this.tabbedPane.remove(this.mapView);
		this.tabbedPane.remove(expenseAccountView);
		this.tabbedPane.remove(dietaryAccountView);

		expenseAccountView = new ExpenseAccountView(user.getExpenseAccount());
		dietaryAccountView = new DietaryAccountView(user.getDietaryAccount());
		this.mapView = new CampusMapView();

		this.tabbedPane.addTab("Map", mapView);
		this.tabbedPane.addTab("Expenses", expenseAccountView);
		this.tabbedPane.addTab("Diet", dietaryAccountView);

		this.tabbedPane.setSelectedIndex(1);
		
		this.frame.validate();
		this.frame.repaint();
	}

	public static void main(String[] args) {
		new MainView();
	}
}
<file_sep>package front_end;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.Border;

import back_end.ExpenseAccount;
import back_end.Transaction;

public class ExpenseAccountView extends JPanel implements ActionListener, Observer {
	private ExpenseAccount expenseAccount;
	private JTextField balanceTextField;
	private JLabel balanceLabel;
	private JLabel newBalanceLabel;
	private JPanel balancePanel;
	private JPanel transactionPanel;
	private Border border;

	public ExpenseAccountView(ExpenseAccount expenseAccount) {
		this.setLayout(new BorderLayout());

		this.expenseAccount = expenseAccount;

		this.balancePanel = new JPanel();
		balancePanel.setLayout(new FlowLayout());

		this.balanceLabel = new JLabel("Balance: $" + this.expenseAccount.getBalance(), JLabel.CENTER);
		this.balancePanel.add(this.balanceLabel);
		this.newBalanceLabel = new JLabel("        Set a New Balance: ");
		this.balancePanel.add(this.newBalanceLabel);

		this.balanceTextField = new JTextField(6);
		this.balanceTextField.addActionListener(this);
		this.balancePanel.add(this.balanceTextField);

		this.add(balancePanel, BorderLayout.NORTH);

		this.transactionPanel = new JPanel();
		this.transactionPanel.setLayout(new BoxLayout(this.transactionPanel, BoxLayout.Y_AXIS));
		ArrayList<Transaction> transactions = this.expenseAccount.getTransactions();

		this.border = BorderFactory.createLineBorder(Color.LIGHT_GRAY, 4);

		for (int i = 0; i < transactions.size(); ++i) {
			JLabel label = new JLabel("<html>Total Cost: $" + transactions.get(i).getTotalCost() + "<br/>"
					+ Arrays.toString(transactions.get(i).getPurchases()) + "</html>");
			label.setBorder(this.border);

			this.transactionPanel.add(label);
		}

		this.add(transactionPanel, BorderLayout.CENTER);
	}

	public void actionPerformed(ActionEvent e) {
		double newBalance = this.expenseAccount.getBalance();

		try {
			newBalance = Double.parseDouble(balanceTextField.getText());
		} catch (NumberFormatException ex) {
			return;
		}

		DecimalFormat moneyFormat = new DecimalFormat("#.##");
		moneyFormat.setRoundingMode(RoundingMode.DOWN);

		newBalance = Double.parseDouble(moneyFormat.format(newBalance));
		this.expenseAccount.setBalance(newBalance);

		this.balanceLabel.setText("Balance: $" + this.expenseAccount.getBalance());
	}

	@Override
	public void update(Observable o, Object arg) {
		Transaction transaction = (Transaction) arg;
		
		JLabel label = new JLabel("<html>Total Cost: $" + transaction.getTotalCost() + "<br/>"
				+ Arrays.toString(transaction.getPurchases()) + "</html>");
		label.setBorder(this.border);

		this.transactionPanel.add(label);
		
		this.balanceLabel.setText("Balance: $" + this.expenseAccount.getBalance());
		
		this.validate();
		this.repaint();
	}

}
<file_sep># CampusSmartCafe
COEN 160 Final Project
<file_sep>package front_end;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.swing.JPanel;

public class BarGraphView extends JPanel{

	private Map<Color, Integer> bars = new LinkedHashMap<Color, Integer>();
	private Color barColors[] = {Color.LIGHT_GRAY,Color.RED, Color.BLUE, Color.GREEN}; ;
	
    public BarGraphView(int[] calData) {
    		for (int i=0; i<barColors.length; ++i) {
    			if(calData[i]<0)
    				calData[i]=0;
                bars.put(barColors[i],calData[i]);
            }
    }

    protected void paintComponent(Graphics gp) {
            super.paintComponent(gp);
            // Cast the graphics objects to Graphics2D
            Graphics2D g = (Graphics2D) gp;
            // determine longest bar
            int max = Integer.MIN_VALUE;
            for (Integer value : bars.values()) {
                    max = Math.max(max, value);
            }
            // paint bars
            int width = (getWidth() / bars.size()) - 2;
            int x = 1;
            for (Color color : bars.keySet()) {
                    int value = bars.get(color);
                    int height = (int) ((getHeight() - 50) * ((double) value / max));
                    g.setColor(color);
                    g.fillRect(x, getHeight() - height, width, height);
                    g.setColor(Color.black);
                    g.drawRect(x, getHeight() - height, width, height);
                    x += (width + 2);
            }
    }

    public Dimension getPreferredSize() {
            return new Dimension(bars.size() * 10 + 2, 50);
    }
}
<file_sep>package back_end;

public class UserValidator {

	private UserManager users;
	
	public UserValidator(UserManager users)
	{
		this.users=users;
	}
	
	public User login(String userName, String password)
	{
		User temp = null;
		
		if(checkPassword(userName, password))
			temp=users.getUser(userName);
		return temp;
	}
	public UserManager getUserManager()
	{
		return users;
	}
	private boolean checkPassword(String userName, String password)
	{
		User subject;
		
		try
		{
			subject= users.getUser(userName);
		}catch(NullPointerException e) {
			return false;
		}
		

		if(subject==null)
			return false;
		
		if(subject.getPassword().equals(password))
			return true;
		return false;	
	}
}
<file_sep>package back_end;

import java.awt.Point;
import java.util.ArrayList;
import java.util.Observer;

public class VendingMachine extends FoodProvider {

	public VendingMachine(String name, ArrayList<Food> menu, Point location) {
		super(name, menu, location);
	}

}
<file_sep>package back_end;

import java.io.Serializable;
import java.util.ArrayList;

public class DietaryAccount implements Serializable {

	private int maxCalBalance;
	private ArrayList<String> preferences;
	private ArrayList<Transaction> transactions;

	public DietaryAccount(int calBalance) {
		this.maxCalBalance = calBalance;
		preferences = new ArrayList<String>();
		transactions = new ArrayList<Transaction>();
	}

	public int getCalBalance() {
		int total=0;
		for(int i=0; i<transactions.size(); i++)
			total+=transactions.get(i).getCal();
		return maxCalBalance-total;
	}
	
	public int getMaxCalBalance() {
		return maxCalBalance;
	}

	public void setMaxCalBalance(int calBalance) {
		this.maxCalBalance = calBalance;
		if(this.maxCalBalance<this.getCalBalance())
			this.maxCalBalance = this.getCalBalance();
	}
	
	public ArrayList<String> getPreferences() {
		return preferences;
	}

	public void addPreference(String preference) {
		 this.preferences.add(preference);
	}

	public boolean removePreferences() {
		return preferences.removeAll(preferences);
	}

	public ArrayList<Transaction> getTransactions() {
		return transactions;
	}

	public void addTransaction(Transaction transactions) {
			this.transactions.add(transactions);
	}
	
	public void clearTransactions()
	{
		this.transactions.removeAll(transactions);
	}
	
	@Override
	public String toString() {
		return this.getCalBalance() + ";" + maxCalBalance + ";" + preferences + ";" + transactions;
	}
}
