Package ch.sahits.game.openpatrician.model

Source Code of ch.sahits.game.openpatrician.model.Date

package ch.sahits.game.openpatrician.model;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.ResourceBundle;
import java.util.concurrent.CopyOnWriteArrayList;

import ch.sahits.game.event.TimeChangeEvent;
import ch.sahits.game.openpatrician.util.l10n.Locale;

/**
* Representation of the date within the game.
* This class is thread safe.
* The Date is implemented as a singleton. However there
* is no getInstance method to retrieve the once created instance,
* so it must be referenced elsewhere.
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Sep 16, 2011
*
*/
public class Date implements IClockUpdateListenable{
  /** Tick update in minutes */
  private int update;
  /** Current date */
  private final Calendar cal;
  /** Start year */
  private final int startYear;
  /** This instance */
  private static Date instance;
  /** Lock for guaranteeing thread safty */
  private static Object lock = new Object();
  private CopyOnWriteArrayList<IClockUpdateListener> listeners = new CopyOnWriteArrayList<IClockUpdateListener>();
  private ResourceBundle messages = ResourceBundle.getBundle("OpenPatricianMessages", Locale.getInstance().getCurrentLocal());
  /**
   * Initialize the date with start year.
   * The initial date is 13th July of the start year.
   * The default tick update is 5 minutes.
   */
  private Date(int year){
    startYear=year;
    cal = GregorianCalendar.getInstance();
    cal.setTimeInMillis(0);
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.DAY_OF_MONTH, 13);
    cal.set(Calendar.MONTH, Calendar.JULY);
    update = 5;
  }
  /**
   * Constructor for testing purposes only
   * @param cal
   */
  Date(Calendar cal){
    this.cal = cal;
    startYear = cal.get(Calendar.YEAR);
    update = 5;
  }
  /**
   * Retrieve the singleton instance of the date.
   * If the instance is not yet created, it will be
   * created
   * @param year
   * @return
   */
  public static Date getInstance(int year){
    synchronized (lock) {
      if (instance==null){
        instance=new Date(year);
      }
      return instance;
    }
  }
//  /**
//   * Retrieve the singleton instance of this object.
//   * If no such instance is initiated an {@link IllegalStateException}
//   * will be thrown.
//   * @return
//   */
//  public static Date getInstance(){
//    if (instance!=null){
//      return instance;
//    }
//    throw new IllegalStateException("Not yet initialized");
//  }
  /**
   * Update the time by one tick.
   */
  public void tick(){
    synchronized (lock) {
      int dayBefore = cal.get(Calendar.DATE);
      cal.add(Calendar.MINUTE, update);
      if (dayBefore!=cal.get(Calendar.DATE)){
        new TimeChangeEvent().notify(null);
      }
    }
    notifyTick();
  }
  /**
   * Set the tick update in number of minutes
   * @param minutes tick update
   */
  public void setTickUpdate(int minutes){
    update=minutes;
    notifyTickUpdate();
  }
  /**
   * Retrieve the start year
   * @return the startYear
   */
  public int getStartYear() {
    return startYear;
  }
//  /**
//   * @param field
//   * @return
//   * @see java.util.Calendar#get(int)
//   */
//  public int get(int field) {
//    return cal.get(field);
//  }
  /**
   * Retrieve the date of the start of the week in the form {Day of month}. {Month}.
   * The week starts with Monday
   * @return
   */
  public String getStartOfWeek(){
    Calendar lastMon = getStartOfWeekInternal();
    return toShortDate(lastMon);
  }
  /**
   * Retrieve the date of the start of the last week
   * @return
   */
  Calendar getStartOfWeekInternal() {
    Calendar c = (Calendar) cal.clone();
    // last week
    c.add(Calendar.WEEK_OF_YEAR, -1);
    // first day
    c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
 
    int cdow = cal.get(Calendar.DAY_OF_WEEK);
    Calendar lastMon = (Calendar) cal.clone();
    lastMon.roll(Calendar.DATE, -7 - (cdow - Calendar.MONDAY));
    return lastMon;
  }
  /**
   * Convert the date into the form {Day in month}. {Month}
   * @param c
   * @return
   */
  private String toShortDate(Calendar c) {
    final int day;
    final int month;
    synchronized (lock) {
      day = c.get(Calendar.DAY_OF_MONTH);
      month = c.get(Calendar.MONTH);
    }
    StringBuilder sb = new StringBuilder();
    sb.append(day).append(". ");
    sb.append(messages.getObject("month_short_"+month));
    return sb.toString();
  }
  /**
   * Retrieve the date of the end of the week in the form {Day of month}. {Month}.
   * The week ends with Sunday
   * @return
   */
  public String getEndOfWeek(){
      Calendar lastSun = getEndOfWeekInternal();
      return toShortDate(lastSun);
  }
  /**
   * Retrieve the date of the of the Sunday of last week
   * @return
   */
  Calendar getEndOfWeekInternal() {
    int cdow = cal.get(Calendar.DAY_OF_WEEK);
       Calendar lastMon = (Calendar) cal.clone();
    lastMon.roll(Calendar.DATE, -7 - (cdow - Calendar.MONDAY));
    Calendar lastSun = (Calendar) lastMon.clone();
    lastSun.roll(Calendar.DATE, 6);
    return lastSun;
  }

  /**
   * Create a string representation for the user interface of the
   * form {Day of month}. {Month} {Year}.
   * @return
   */
  public String toDisplayString(){
    final int day;
    final int month;
    final int year;
    synchronized (lock) {
      day = cal.get(Calendar.DAY_OF_MONTH);
      month = cal.get(Calendar.MONTH);
      year = cal.get(Calendar.YEAR);
    }
    return todisplayString(day, month, year);
  }
  public String todisplayString(final int day, final int month, final int year) {
    StringBuilder sb = new StringBuilder();
    sb.append(day).append(". ");
    sb.append(messages.getObject("month_short_"+month)).append(" ");
    sb.append(year);
    return sb.toString();
  }
  @Override
  public void add(IClockUpdateListener listener) {
    listeners.add(listener);
  }
  @Override
  public void remove(IClockUpdateListener listener) {
    listeners.remove(listener);
  }
  @Override
  public void notifyTick() {
    for (IClockUpdateListener listener : listeners) {
      listener.ticked();
    }
  }
  @Override
  public void notifyTickUpdate() {
    for (IClockUpdateListener listener : listeners) {
      listener.updateTick(update);
    }
  }
  /**
   * Retrieve a copy of the current date
   * @return
   */
  public Calendar getCurrentDate(){
    return (Calendar) cal.clone();
  }
  /**
   * Retrieve the update interval
   * @return
   */
  public final int getUpdateInterval(){
    return update;
  }
  /**
   * Retrieve an index for the current weekday. Mondy is 0.
   * @return
   */
  public final int getWeekdayIndex(){
    int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
    return (dayOfWeek-Calendar.MONDAY)%7;
  }
}
TOP

Related Classes of ch.sahits.game.openpatrician.model.Date

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.