/*
* Get Organized - Organize your schedule, course assignments, and grades
* Copyright © 2012 Alex Laird
* getorganized@alexlaird.com
* alexlaird.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package adl.go.types;
import adl.go.gui.Domain;
import adl.go.resource.LocalUtility;
import adl.go.resource.Utility;
import java.text.ParseException;
import java.util.Date;
import java.util.NoSuchElementException;
import java.util.Scanner;
/**
* An event has no owner and simply requires a start date, end date, and event
* details.
*
* @author Alex Laird
*/
public class Event extends ExtendedJPanelForEvent implements ListItem
{
/**
* The reference to the utility for coloring.
*/
private Utility utility;
/**
* The object for the year to which this event belongs.
*/
private EventYear eventYear;
/**
* The unique name of the category.
*/
private String categoryName;
/**
* The category of the event.
*/
private Category category;
/**
* The date of the event.
*/
private String date = Domain.DATE_FORMAT.format (new Date ());
/**
* The start hour of the event.
*/
private String startHr = "12";
/**
* The start minute of the event.
*/
private String startMin = "00";
/**
* The start meridian of the event.
*/
private String startM = "PM";
/**
* The end hour of the event.
*/
private String endHr = "12";
/**
* The end minute of the event.
*/
private String endMin = "00";
/**
* The end meridian of the event.
*/
private String endM = "PM";
/**
* The location of the event.
*/
private String location = "";
/**
* The description for the event.
*/
private String description = "";
/**
* The string for the repetition of the event.
*/
private Repeating repeating = new Repeating ();
/**
* The row object for use in the assignmentsAndEvents table.
*/
private Object[] rowObject = new Object[]
{
null, null, null, null, null, null, null
};
/**
* True if the event is all day, false otherwise.
*/
private boolean isAllDay = false;
/**
* True if an immediate save is needed after application startup.
*/
private boolean immediateSaveNeeded = false;
/**
* Constructs an event with a given name, unique ID, and reference to its
* containing course.
*
* @param name The name of the event.
* @param id A unique ID not used by any other type in the application.
* @param utility A reference to the utility is needed for coloring.
*/
public Event(String name, long id, LocalUtility utility, EventYear eventYear)
{
super (name, id, utility);
this.utility = utility;
this.eventYear = eventYear;
category = utility.preferences.categories.get (0);
refreshRowObject ();
}
/**
* Parses a single input string into every attribute's initial state for
* this object--this is specifically used by the loading methods from the
* data file.
*
* @param parse The string of all data to be used for initialization.
* @param utility A reference to the utility is needed for coloring.
*/
public Event(String parse, LocalUtility utility)
{
super ("", -1, utility);
this.utility = utility;
Scanner scan = new Scanner (parse).useDelimiter ("(?<!\\\\)" + SEPARATOR + "|" + "(?<!\\\\)" + END_OF_LINE);
// throw away the false saying this is an event
String throwAway = null;
try
{
throwAway = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
if (throwAway != null && (throwAway.equals ("true") || throwAway.equals ("false")))
{
setItemName (scan.next ().replaceAll ("\\\\" + SEPARATOR, SEPARATOR).replaceAll ("\\\\" + END_OF_LINE, END_OF_LINE));
}
else
{
setItemName (throwAway);
}
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
setUniqueID (scan.nextLong ());
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
date = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
startHr = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
endHr = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
isAllDay = scan.nextBoolean ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
location = scan.next ().replaceAll ("\\\\" + SEPARATOR, SEPARATOR).replaceAll ("\\\\" + END_OF_LINE, END_OF_LINE);
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
description = scan.next ().replaceAll ("\\\\" + SEPARATOR, SEPARATOR).replaceAll ("\\\\" + END_OF_LINE, END_OF_LINE).replaceAll ("\\\\<br />", LINE_RETURN);
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
categoryName = scan.next ().replaceAll ("\\\\" + SEPARATOR, SEPARATOR).replaceAll ("\\\\" + END_OF_LINE, END_OF_LINE);
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
repeating.id = scan.nextLong ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
setRepeating (scan.next ());
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
if (startHr.contains (":"))
{
startMin = startHr.split (":")[1].split (" ")[0];
startM = startHr.split (":")[1].split (" ")[1];
startHr = startHr.split (":")[0];
immediateSaveNeeded = true;
}
else
{
try
{
startMin = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
startM = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
}
if (endHr.contains (":"))
{
endMin = endHr.split (":")[1].split (" ")[0];
endM = endHr.split (":")[1].split (" ")[1];
endHr = endHr.split (":")[0];
immediateSaveNeeded = true;
}
else
{
try
{
endMin = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
try
{
endM = scan.next ();
}
catch (NoSuchElementException ex)
{
immediateSaveNeeded = true;
}
}
scan.close ();
}
/**
* Retrieve the object reference to this event's event year.
*
* @return The event year of this event.
*/
public EventYear getEventYear()
{
return eventYear;
}
/**
* Set the event year object for this event.
*
* @param eventYear The event year to be set.
*/
public void setEventYear(EventYear eventYear)
{
this.eventYear = eventYear;
}
/**
* Check if the event needs an immediate save after startup.
*
* @return True if an immediate save is needed, false otherwise.
*/
public boolean needsImmediateSaveNeeded()
{
return immediateSaveNeeded;
}
/**
* Reset the needsImmedateSave flag.
*/
public void resetNeedsImmediateSaveNeeded()
{
immediateSaveNeeded = false;
}
/**
* Refreshes the text of the component that is shown in Calendar View.
*/
@Override
public void refreshText()
{
switch (utility.preferences.colorByIndex)
{
// color by due date
case 0:
{
String[] eventDate = getDueDate ().split ("/");
String[] currentDate = Domain.DATE_FORMAT.format (new Date ()).split ("/");
try
{
if (((new Date ()).before (Domain.DATE_FORMAT.parse (getDueDate ()))
|| (Domain.DATE_FORMAT.format (new Date ()).equals (getDueDate ())))
&& (Integer.parseInt (eventDate[2]) - Integer.parseInt (currentDate[2]) == 0
&& Integer.parseInt (eventDate[0]) - Integer.parseInt (currentDate[0]) == 0))
{
if (Integer.parseInt (eventDate[1]) - Integer.parseInt (currentDate[1]) == 3)
{
getLabel ().setForeground (utility.preferences.dueDateColors[5]);
}
else if (Integer.parseInt (eventDate[1]) - Integer.parseInt (currentDate[1]) == 2)
{
getLabel ().setForeground (utility.preferences.dueDateColors[4]);
}
else
{
if (Integer.parseInt (eventDate[1]) - Integer.parseInt (currentDate[1]) == 1)
{
getLabel ().setForeground (utility.preferences.dueDateColors[3]);
}
else
{
if (Integer.parseInt (eventDate[1]) - Integer.parseInt (currentDate[1]) == 0)
{
getLabel ().setForeground (utility.preferences.dueDateColors[2]);
}
else
{
getLabel ().setForeground (utility.preferences.dueDateColors[0]);
}
}
}
}
else
{
getLabel ().setForeground (utility.preferences.dueDateColors[0]);
}
}
catch (ParseException ex)
{
Domain.LOGGER.add (ex);
}
break;
}
// color by category
case 1:
{
getLabel ().setForeground (getCategory ().getColor ());
break;
}
// color by priority
case 2:
{
getLabel ().setForeground (getCategory ().getColor ());
break;
}
}
setItemName (getItemName ());
}
/**
* Retrieves the category this event is attached to.
*
* @return The category this assignment is attached to.
*/
public Category getCategory()
{
return category;
}
/**
* Retrieves the name of the category this event is attached to.
*
* @return The name of the category this assignment is attached to.
*/
public String getCategoryName()
{
if (categoryName == null)
{
categoryName = "Default";
}
return categoryName;
}
/**
* Sets the category for this event.
*
* @param category The category to be set.
*/
public void setCategory(Category category)
{
this.category = category;
}
/**
* Refreshes the row object with the values stored in this event object to
* ensure they are all correct.
*/
public final void refreshRowObject()
{
String openTags = "<html><b>";
String closeTags = "</b></html>";
switch (utility.preferences.colorByIndex)
{
// color by due date
case 0:
{
String[] assignmentDate = getDueDate ().split ("/");
String[] currentDate = Domain.DATE_FORMAT.format (new Date ()).split ("/");
try
{
if (((new Date ()).before (Domain.DATE_FORMAT.parse (getDueDate ()))
|| (Domain.DATE_FORMAT.format (new Date ()).equals (getDueDate ())))
&& (Integer.parseInt (assignmentDate[2]) - Integer.parseInt (currentDate[2]) == 0
&& Integer.parseInt (assignmentDate[0]) - Integer.parseInt (currentDate[0]) == 0))
{
if (Integer.parseInt (assignmentDate[1]) - Integer.parseInt (currentDate[1]) == 3)
{
openTags += "<font color=\"#" + Integer.toHexString (utility.preferences.dueDateColors[5].getRGB () & 0x00FFFFFF) + "\">";
closeTags = "</font>" + closeTags;
}
else if (Integer.parseInt (assignmentDate[1]) - Integer.parseInt (currentDate[1]) == 2)
{
openTags += "<font color=\"#" + Integer.toHexString (utility.preferences.dueDateColors[4].getRGB () & 0x00FFFFFF) + "\">";
closeTags = "</font>" + closeTags;
}
else
{
if (Integer.parseInt (assignmentDate[1]) - Integer.parseInt (currentDate[1]) == 1)
{
openTags += "<font color=\"#" + Integer.toHexString (utility.preferences.dueDateColors[3].getRGB () & 0x00FFFFFF) + "\">";
closeTags = "</font>" + closeTags;
}
else
{
if (Integer.parseInt (assignmentDate[1]) - Integer.parseInt (currentDate[1]) == 0)
{
openTags += "<font color=\"#" + Integer.toHexString (utility.preferences.dueDateColors[2].getRGB () & 0x00FFFFFF) + "\">";
closeTags = "</font>" + closeTags;
}
else
{
openTags += "<font color=\"#" + Integer.toHexString (utility.preferences.dueDateColors[0].getRGB () & 0x00FFFFFF) + "\">";
closeTags = "</font>" + closeTags;
}
}
}
}
else
{
openTags += "<font color=\"#" + Integer.toHexString (utility.preferences.dueDateColors[0].getRGB () & 0x00FFFFFF) + "\">";
closeTags = "</font>" + closeTags;
}
}
catch (ParseException ex)
{
Domain.LOGGER.add (ex);
}
break;
}
// color by category
case 1:
{
String rgb = Integer.toHexString (getCategory ().getColor ().getRGB ());
openTags += "<font color=\"#" + rgb.substring (2, rgb.length ()) + "\">";
closeTags = "</font>" + closeTags;
break;
}
// color by priority
case 2:
{
String rgb = Integer.toHexString (getCategory ().getColor ().getRGB ());
openTags += "<font color=\"#" + rgb.substring (2, rgb.length ()) + "\">";
closeTags = "</font>" + closeTags;
break;
}
}
if (!isAllDay ())
{
rowObject[1] = openTags + "(" + startHr + ":" + startMin + " " + startM + ") " + getItemName () + closeTags;
}
else
{
rowObject[1] = openTags + getItemName () + closeTags;
}
rowObject[2] = "Event";
rowObject[3] = getCategoryName ();
rowObject[4] = getDueDate ();
rowObject[5] = "---";
rowObject[6] = getUniqueID ();
}
/**
* Set the name of the event with the given name.
*
* @param name The name to set the event with.
*/
@Override
public final void setItemName(String name)
{
super.setItemName (name);
if (!isAllDay ())
{
getLabel ().setText ("<html>(" + startHr + ":" + startMin + " " + startM + ") " + name + "</html>");
}
else
{
getLabel ().setText ("<html>" + name + "</html>");
}
}
/**
* Retrieves the row object for use in the assignmentsAndEvents table.
*
* @return The row object.
*/
@Override
public Object[] getRowObject()
{
refreshRowObject ();
return rowObject;
}
/**
* Retrieve the date.
*
* @return The date.
*/
@Override
public String getDueDate()
{
return date;
}
/**
* Retrieves if the event is all day or not.
*
* @return True if the event is all day, false otherwise.
*/
public boolean isAllDay()
{
return isAllDay;
}
/**
* Sets the all day state of the event
*
* @param isAllDay True if the event should be all day, false otherwise.
*/
public void setIsAllDay(boolean isAllDay)
{
this.isAllDay = isAllDay;
}
/**
* Set the repeating object for the event with the given string.
*
* @param repeatingString The repeating string for the event.
*/
public final void setRepeating(String repeatingString)
{
if (!repeatingString.equals (""))
{
String[] split = repeatingString.split ("-");
repeating.repeatsIndex = Integer.parseInt (split[0]);
repeating.repeatsEveryIndex = Integer.parseInt (split[1]);
repeating.sunday = Boolean.valueOf (split[2]);
repeating.monday = Boolean.valueOf (split[3]);
repeating.tuesday = Boolean.valueOf (split[4]);
repeating.wednesday = Boolean.valueOf (split[5]);
repeating.thursday = Boolean.valueOf (split[6]);
repeating.friday = Boolean.valueOf (split[7]);
repeating.saturday = Boolean.valueOf (split[8]);
repeating.startDate = split[9];
repeating.endDate = split[10];
}
}
/**
* Retrieve the repeating object for the event.
*
* @return The repeating object for the event.
*/
public Repeating getRepeating()
{
return repeating;
}
/**
* Set the date.
*
* @param date The date to be set.
*/
public void setDate(String date, LocalUtility utility)
{
this.date = date;
setEventYear (utility.getEventYear (date.split ("/")[2]));
}
/**
* Sets the start time of the event.
*
* @param index 0 will return the hr, 1 will return the minute, 2 will
* return the meridian.
* @param time The start time to be set.
*/
public final void setStartTime(int index, String time)
{
switch (index)
{
case 0:
{
startHr = time;
break;
}
case 1:
{
startMin = time;
break;
}
case 2:
{
startM = time;
break;
}
}
refreshText ();
}
/**
* Retrieves the start time of the event.
*
* @param index 0 will return the hr, 1 will return the minute, 2 will
* return the meridian.
* @return The start time of the event.
*/
public String getStartTime(int index)
{
String time = "";
switch (index)
{
case 0:
{
time = startHr;
break;
}
case 1:
{
time = startMin;
break;
}
case 2:
{
time = startM;
break;
}
}
return time;
}
/**
* Sets the end time of the event.
*
* @param index 0 will return the hr, 1 will return the minute, 2 will
* return the meridian.
* @param time The end time to be set.
*/
public final void setEndTime(int index, String time)
{
switch (index)
{
case 0:
{
endHr = time;
break;
}
case 1:
{
endMin = time;
break;
}
case 2:
{
endM = time;
break;
}
}
}
/**
* Retrieves the end time of the event.
*
* @param index 0 will return the hr, 1 will return the minute, 2 will
* return the meridian.
* @return The end time of the event.
*/
public String getEndTime(int index)
{
String time = "";
switch (index)
{
case 0:
{
time = endHr;
break;
}
case 1:
{
time = endMin;
break;
}
case 2:
{
time = endM;
break;
}
}
return time;
}
/**
* Retrieves the event location.
*
* @return The location of the event.
*/
public String getEventLocation()
{
return location;
}
/**
* Sets the event location.
*
* @param location The location of the event to be set.
*/
public void setEventLocation(String location)
{
this.location = location;
}
/**
* Retrieves the description.
*
* @return The description of the event.
*/
public String getDescription()
{
return description;
}
/**
* Sets the description for this event.
*
* @param description The description to be set.
*/
public void setDescription(String description)
{
this.description = description;
}
/**
* Always returns false, because an event is not an assignment.
*
* @return False because this is an event, not an assignment.
*/
@Override
public boolean isAssignment()
{
return false;
}
/**
* Returns a string of all components in this object that is formatted that
* the file reader/writer will cooperate with it.
*
* @return The formatted output string.
*/
@Override
public String out()
{
return isAssignment () + SEPARATOR
+ getItemName ().replaceAll (SEPARATOR, "\\\\" + SEPARATOR).replaceAll (END_OF_LINE, "\\\\" + END_OF_LINE) + SEPARATOR
+ getUniqueID () + SEPARATOR
+ date + SEPARATOR
+ startHr + SEPARATOR
+ endHr + SEPARATOR
+ isAllDay + SEPARATOR
+ location.replaceAll (SEPARATOR, "\\\\" + SEPARATOR).replaceAll (END_OF_LINE, "\\\\" + END_OF_LINE) + SEPARATOR
+ description.replaceAll (SEPARATOR, "\\\\" + SEPARATOR).replaceAll (END_OF_LINE, "\\\\" + END_OF_LINE).replaceAll (LINE_RETURN, "\\\\<br />") + SEPARATOR
+ getCategory ().getName ().replaceAll (SEPARATOR, "\\\\" + SEPARATOR).replaceAll (END_OF_LINE, "\\\\" + END_OF_LINE) + SEPARATOR
+ repeating.id + SEPARATOR
+ repeating + SEPARATOR
+ startMin + SEPARATOR
+ startM + SEPARATOR
+ endMin + SEPARATOR
+ endM;
}
}