import javax.swing.*;
import java.awt.*;
import java.util.*;


/** 
 * This class represents the appointments.  They are kept in sorted order.
 * The class contains methods to manipulate the calendar.
 *
 * @author Dave Knauer and Drew Boese, SE 376.
 */
public class Appointments {
	
	private Vector appointments;  // To hold all of the appointments
	private JPanel mainPanel;
	private JList displayList;
	
	/**
	 * Creates a new Appoinments object.  This object acts as the actual set of 
	 * appointments.
	 *
	 */
	public Appointments(JPanel _mainPanel, Vector _appointments, 
						JList _displayList) {
		this.appointments = _appointments; 
		this.mainPanel = _mainPanel;
		this.displayList = _displayList;
	}

	/**
	 * Creates a new appoinment, and adds it to the calendar.
	 *
	 */ 
	public void insert() {
		int dResult = 0;
		boolean valid = false;
		String errorMessage = "";
		while (!valid) {
			JOptionPane jOption = new JOptionPane();
			String[] option = new String[2];
			option[0] = "Ok";
			option[1] = "Cancel";
			InsertDialog iDialog = new InsertDialog();
			iDialog.errorL.setText(errorMessage);
			dResult = jOption.showOptionDialog(this.mainPanel, 
								iDialog, 
								"Insert Appointment",
								JOptionPane.DEFAULT_OPTION,
								JOptionPane.PLAIN_MESSAGE,
								null,
								option,
								iDialog);
			if (dResult == 0) {
				Integer dayI = (Integer) iDialog.day.getSelectedItem();
				Integer monthI = (Integer) iDialog.month.getSelectedItem();
				Integer yearI = (Integer) iDialog.year.getSelectedItem();
				String day = dayI.toString();
				String month = monthI.toString();
				String year = yearI.toString();
				if (day.length() < 2) day = "0" + day;
				if (month.length() < 2) month = "0" + month;
				String date = month + "/" + day + "/" + year;
				Integer sHour1 = (Integer) iDialog.hour1.getSelectedItem();
				String startMin = iDialog.min1.getSelectedItem().toString();
				String startAMPM = iDialog.ampm1.getSelectedItem().toString();
				String startHour;
				if (startAMPM.equals("PM"))
					if (sHour1.intValue() == 12)
						startHour = "12";
					else
						startHour = "" + (sHour1.intValue() + 12);
				else if (sHour1.intValue() == 12)
					startHour = "00";
				else
					startHour = "" + sHour1.intValue();
				String startTime = startHour + ":" + startMin;
				Integer sHour2 = (Integer) iDialog.hour2.getSelectedItem();
				String stopMin = iDialog.min2.getSelectedItem().toString();
				String stopAMPM = iDialog.ampm2.getSelectedItem().toString();
				String stopHour;
				if (stopAMPM.equals("PM"))
					if (sHour2.intValue() == 12)
						stopHour = "12";
					else
						stopHour = "" + (sHour2.intValue() + 12);
				else if (sHour2.intValue() == 12)
					stopHour = "00";
				else
					stopHour = "" + sHour2.intValue();
				String stopTime = stopHour + ":" + stopMin;
				if (!CalendarUtils.precedesCurDate(date))
					if (CalendarUtils.validTime(startTime))
						if (!(CalendarUtils.equalsCurDate(date) &&
							CalendarUtils.precedesCurTime(startTime)))
							if (CalendarUtils.validTime(stopTime))
								if (CalendarUtils.precedingTime(startTime, stopTime)) 
									if (!iDialog.name.getText().equals("")) {
										ScheduleEvent newEvent = new ScheduleEvent(
												iDialog.name.getText(),
												date, 
												startTime,
												stopTime, yearI, monthI, dayI);
										this.appointments.add(this.findIndexFor(newEvent), newEvent);
										valid = true;
									} else errorMessage = "ERROR: Blank Name";
								else errorMessage = "ERROR: Bad Times";
							else  errorMessage = "ERROR: Bad Stop Time";
						else errorMessage = "ERROR: Bad Times";
					else errorMessage = "ERROR: Bad Start Time";
				else errorMessage = "ERROR: Bad Date";
			}
			else valid = true;	
		}
	}
	
	/**
	 * Allows the user to change attributes of a particular appointment
	 *
	 */
	public void change() {
		int curSel;
		String errorMessage = "";
		if (this.displayList.getSelectedIndex() == -1)
			curSel = 0;
		else
			curSel = this.displayList.getSelectedIndex();
		ScheduleEvent curE = (ScheduleEvent) this.appointments.get(curSel);
		int dResult = 0;
		boolean valid = false;
		while (!valid) {
			JOptionPane jOption = new JOptionPane();
			String[] option = new String[2];
			option[0] = "Ok";
			option[1] = "Cancel";
			InsertDialog iDialog = new InsertDialog();
			iDialog.name.setText(curE.getName());
			iDialog.year.setSelectedItem(curE.year);
			iDialog.month.setSelectedItem(curE.month);
			iDialog.day.setSelectedItem(curE.day);
			String curStartTime = curE.getStartTime();
			StringTokenizer st = new StringTokenizer(curStartTime,":");
			String curHours = st.nextToken();
			String curMins = st.nextToken();
			iDialog.min1.setSelectedItem(curMins);
			Integer curH = new Integer(curHours);
			if (curH.intValue() > 12) {
				curH = new Integer(curH.intValue() - 12);
				iDialog.ampm1.setSelectedIndex(1);
				iDialog.hour1.setSelectedItem(curH);
			} else if (curH.intValue() == 0) {
				curH = new Integer(12);
				iDialog.ampm1.setSelectedIndex(0);
				iDialog.hour1.setSelectedItem(curH);
			} else {
				iDialog.ampm1.setSelectedIndex(0);
				iDialog.hour1.setSelectedItem(curH);
			}
			String curStopTime = curE.getStopTime();
			st = new StringTokenizer(curStopTime,":");
			curHours = st.nextToken();
			curMins = st.nextToken();
			iDialog.min2.setSelectedItem(curMins);
			curH = new Integer(curHours);
			if (curH.intValue() > 12) {
				curH = new Integer(curH.intValue() - 12);
				iDialog.ampm2.setSelectedIndex(1);
				iDialog.hour2.setSelectedItem(curH);
			} else if (curH.intValue() == 0) {
				curH = new Integer(12);
				iDialog.ampm2.setSelectedIndex(0);
				iDialog.hour2.setSelectedItem(curH);
			} else {
				iDialog.ampm2.setSelectedIndex(0);
				iDialog.hour2.setSelectedItem(curH);
			}
			iDialog.errorL.setText(errorMessage);
			dResult = jOption.showOptionDialog(this.mainPanel, 
								iDialog, 
								"Change Appointment",
								JOptionPane.DEFAULT_OPTION,
								JOptionPane.PLAIN_MESSAGE,
								null,
								option,
								iDialog);
			if (dResult == 0) {
				Integer dayI = (Integer) iDialog.day.getSelectedItem();
				Integer monthI = (Integer) iDialog.month.getSelectedItem();
				Integer yearI = (Integer) iDialog.year.getSelectedItem();
				String day = dayI.toString();
				String month = monthI.toString();
				String year = yearI.toString();
				if (day.length() < 2) day = "0" + day;
				if (month.length() < 2) month = "0" + month;
				String date = month + "/" + day + "/" + year;
				Integer sHour1 = (Integer) iDialog.hour1.getSelectedItem();
				String startMin = iDialog.min1.getSelectedItem().toString();
				String startAMPM = iDialog.ampm1.getSelectedItem().toString();
				String startHour;
				if (startAMPM.equals("PM"))
					if (sHour1.intValue() == 12)
						startHour = "12";
					else
						startHour = "" + (sHour1.intValue() + 12);
				else if (sHour1.intValue() == 12)
					startHour = "00";
				else
					startHour = "" + sHour1.intValue();
				String startTime = startHour + ":" + startMin;
				Integer sHour2 = (Integer) iDialog.hour2.getSelectedItem();
				String stopMin = iDialog.min2.getSelectedItem().toString();
				String stopAMPM = iDialog.ampm2.getSelectedItem().toString();
				String stopHour;
				if (stopAMPM.equals("PM"))
					if (sHour2.intValue() == 12)
						stopHour = "12";
					else
						stopHour = "" + (sHour2.intValue() + 12);
				else if (sHour2.intValue() == 12)
					stopHour = "00";
				else
					stopHour = "" + sHour2.intValue();
				String stopTime = stopHour + ":" + stopMin;
				if (!CalendarUtils.precedesCurDate(date))
					if (CalendarUtils.validTime(startTime))
						if (!(CalendarUtils.equalsCurDate(date) &&
							CalendarUtils.precedesCurTime(startTime)))
							if (CalendarUtils.validTime(stopTime))
								if (CalendarUtils.precedingTime(startTime, stopTime)) 
									if (!iDialog.name.getText().equals("")) {
										ScheduleEvent newEvent = new ScheduleEvent(
												iDialog.name.getText(),
												date, 
												startTime,
												stopTime, yearI, monthI, dayI);
										this.appointments.add(this.findIndexFor(newEvent), newEvent);
										this.appointments.remove(curSel);
										valid = true;
									} else errorMessage = "ERROR: Blank Name";
								else errorMessage = "ERROR: Bad Times";
							else  errorMessage = "ERROR: Bad Stop Time";
						else errorMessage = "ERROR: Bad Times";
					else errorMessage = "ERROR: Bad Start Time";
				else errorMessage = "ERROR: Bad Date";
			}
			else valid = true;	
		}
	}
	
	/**
	 * Gets a date from the user and limits the display list for only
	 * that date.
	 */
	public void limitView() {
		int dResult = 0;
		JOptionPane jOption = new JOptionPane();
		String[] option = new String[2];
		option[0] = "Ok";
		option[1] = "Cancel";
		LimitDialog lDialog = new LimitDialog();
		dResult = jOption.showOptionDialog(this.mainPanel, 
								lDialog, 
								"Date to View",
								JOptionPane.DEFAULT_OPTION,
								JOptionPane.PLAIN_MESSAGE,
								null,
								option,
								lDialog);
		if (dResult == 0) {
			Integer dayI = (Integer) lDialog.day.getSelectedItem();
			Integer monthI = (Integer) lDialog.month.getSelectedItem();
			Integer yearI = (Integer) lDialog.year.getSelectedItem();
			String day = dayI.toString();
			String month = monthI.toString();
			String year = yearI.toString();
			if (day.length() < 2) day = "0" + day;
			if (month.length() < 2) month = "0" + month;
			String date = month + "/" + day + "/" + year;
			Vector tempV = new Vector();
			int numApps = this.appointments.size();
			for (int i = 0; i < numApps; i++) {
				ScheduleEvent tempE = (ScheduleEvent) this.appointments.get(i);
				if (tempE.getDate().equals(date))
					tempV.add(tempE);
			}
			this.displayList.setListData(tempV);
		}
			
	}
	
	/**
	 * Finds the index at which this event would be inserted.
	 * 
	 * @param The event to place in the sorted ArrayList of ScheduleEvents
	 * @return The index at which this event would be inserted
	 */
	private int findIndexFor(ScheduleEvent event) {
		int index; // The current index being examined.
		ScheduleEvent compare; // To store the current comparison item
		
		while(index < appointments.size()) {
			compare = (ScheduleEvent)appointments.get(index);

			if(!CalendarUtils.precedingEvent(compare, event)) 
				return index;
			if(CalendarUtils.concurrentEvents(compare, event)) 
				return index;
			index++;
		}

		return index;		
	}
	
}
