OceanusDateRangeState.java
/*******************************************************************************
* Oceanus: Java Utilities
* Copyright 2012,2025 Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.sourceforge.joceanus.oceanus.date;
import java.util.Locale;
/**
* State for JDateDayRange Selection panel.
*/
public class OceanusDateRangeState {
/**
* base date is start of period?
*/
private final boolean isBaseStartOfPeriod;
/**
* The Overall Range.
*/
private OceanusDateRange theOverallRange;
/**
* The Range.
*/
private OceanusDateRange theRange;
/**
* The start Date.
*/
private OceanusDate theStartDate;
/**
* The end Date.
*/
private OceanusDate theEndDate;
/**
* The base Date.
*/
private OceanusDate theBaseDate;
/**
* The Date Period.
*/
private OceanusDatePeriod thePeriod;
/**
* Is the period locked?
*/
private boolean isLocked;
/**
* Can we select a next period within the available range.
*/
private boolean isNextOK;
/**
* Can we select a previous period within the available range.
*/
private boolean isPrevOK;
/**
* Constructor.
* @param pBaseIsStart is the baseDate the start of the period? (true/false)
*/
public OceanusDateRangeState(final boolean pBaseIsStart) {
/* Record parameters */
isBaseStartOfPeriod = pBaseIsStart;
/* Default the period and overall range */
thePeriod = OceanusDatePeriod.ONEMONTH;
theOverallRange = new OceanusDateRange();
/* Record the initial date */
theBaseDate = new OceanusDate();
/* build the range */
buildRange();
}
/**
* Constructor.
* @param pState state to copy from
*/
public OceanusDateRangeState(final OceanusDateRangeState pState) {
/* Copy values */
isBaseStartOfPeriod = pState.isBaseStartOfPeriod();
thePeriod = pState.getPeriod();
theOverallRange = pState.getOverallRange();
theStartDate = pState.getStartDate();
theEndDate = pState.getEndDate();
theBaseDate = pState.getBaseDate();
theRange = pState.getRange();
isLocked = pState.isLocked();
isNextOK = pState.isNextOK();
isPrevOK = pState.isPrevOK();
}
/**
* Is the baseDate the start of the range.
* @return the range
*/
public boolean isBaseStartOfPeriod() {
return isBaseStartOfPeriod;
}
/**
* Get the range.
* @return the range
*/
public OceanusDateRange getRange() {
return theRange;
}
/**
* Get the overall range.
* @return the start date
*/
public OceanusDateRange getOverallRange() {
return theOverallRange;
}
/**
* Get the start date.
* @return the start date
*/
public OceanusDate getStartDate() {
return theStartDate;
}
/**
* Get the end date.
* @return the end date
*/
public OceanusDate getEndDate() {
return theEndDate;
}
/**
* Get the base date.
* @return the base date
*/
public OceanusDate getBaseDate() {
return theBaseDate;
}
/**
* Get the DatePeriod.
* @return the date period
*/
public OceanusDatePeriod getPeriod() {
return thePeriod;
}
/**
* Can we select a next period within the available range.
* @return true/false
*/
public boolean isNextOK() {
return isNextOK;
}
/**
* Can we select a previous period within the available range.
* @return true/false
*/
public boolean isPrevOK() {
return isPrevOK;
}
/**
* Is the period locked?
* @return true/false
*/
public boolean isLocked() {
return isLocked;
}
/**
* Is this an UpTo range?
* @return true/false
*/
public boolean isUpTo() {
return thePeriod == OceanusDatePeriod.DATESUPTO;
}
/**
* Is this a custom range?
* @return true/false
*/
public boolean isCustom() {
return thePeriod == OceanusDatePeriod.CUSTOM;
}
/**
* Is this a full range?
* @return true/false
*/
public boolean isFull() {
return thePeriod == OceanusDatePeriod.ALLDATES;
}
/**
* Is this an adjustable range?
* @return true/false
*/
public boolean isAdjustable() {
return thePeriod.adjustPeriod();
}
/**
* Is this a containing range?
* @return true/false
*/
public boolean isContaining() {
return thePeriod.isContaining();
}
/**
* Lock the period.
* @param pLocked true/false
*/
public void lockPeriod(final boolean pLocked) {
isLocked = pLocked;
}
/**
* Set new Period.
* @param pPeriod the new period
*/
public void setPeriod(final OceanusDatePeriod pPeriod) {
/* Adjust the period and build the new range */
thePeriod = pPeriod;
buildRange();
}
/**
* Set new Start Date.
* @param pStartDate the new start date
*/
public void setStartDate(final OceanusDate pStartDate) {
/* Adjust the start date and build the new range */
theStartDate = pStartDate;
buildRange();
}
/**
* Set new End Date.
* @param pEndDate the new end date
*/
public void setEndDate(final OceanusDate pEndDate) {
/* Adjust the end date and build the new range */
theEndDate = pEndDate;
buildRange();
}
/**
* Set new base Date.
* @param pBaseDate the new base date
*/
public void setBaseDate(final OceanusDate pBaseDate) {
/* Adjust the base date and build the new range */
theBaseDate = pBaseDate;
buildRange();
}
/**
* Set next Date.
*/
public void setNextDate() {
/* Adjust the date and build the new range */
nextPeriod();
buildRange();
}
/**
* Set previous Date.
*/
public void setPreviousDate() {
/* Adjust the date and build the new range */
previousPeriod();
buildRange();
}
/**
* adjust the overall range.
* @param pRange the overallRange
*/
public void adjustOverallRange(final OceanusDateRange pRange) {
/* record the range */
theOverallRange = new OceanusDateRange(pRange);
/* Access range parameters */
final OceanusDate myFirst = theOverallRange.getStart();
final OceanusDate myLast = theOverallRange.getEnd();
/* Make sure that no dates are before the first date */
if (myFirst != null) {
if (theBaseDate.compareTo(myFirst) < 0) {
theBaseDate = myFirst;
}
if ((theStartDate == null)
|| (theStartDate.compareTo(myFirst) < 0)) {
theStartDate = myFirst;
}
if ((theEndDate != null)
&& (theEndDate.compareTo(myFirst) < 0)) {
theEndDate = myFirst;
}
}
/* Make sure that no dates are past the final date */
if (myLast != null) {
if (theBaseDate.compareTo(myLast) > 0) {
theBaseDate = myLast;
}
if ((theStartDate != null)
&& (theStartDate.compareTo(myLast) > 0)) {
theStartDate = myLast;
}
if ((theEndDate == null)
|| (theEndDate.compareTo(myLast) > 0)) {
theEndDate = myLast;
}
}
/* Build the range */
buildRange();
}
/**
* Set the locale.
* @param pLocale the locale
*/
public void setLocale(final Locale pLocale) {
theStartDate.setLocale(pLocale);
theEndDate.setLocale(pLocale);
theBaseDate.setLocale(pLocale);
theOverallRange.setLocale(pLocale);
theRange.setLocale(pLocale);
}
/**
* Build the range represented by the selection.
*/
private void buildRange() {
/* Determine action for period */
switch (thePeriod) {
case ALLDATES:
buildFullRange();
break;
case CUSTOM:
buildCustomRange();
break;
case DATESUPTO:
buildUpToRange();
break;
case CALENDARMONTH:
case CALENDARQUARTER:
case CALENDARYEAR:
case FISCALYEAR:
buildContainingRange();
break;
default:
buildStandardRange();
break;
}
}
/**
* Build the standard range.
*/
private void buildStandardRange() {
if (isBaseStartOfPeriod) {
buildStartingRange();
} else {
buildEndingRange();
}
}
/**
* Build the full range.
*/
private void buildFullRange() {
/* Previous and next are not allowed */
isPrevOK = false;
isNextOK = false;
/* Create the range */
theRange = new OceanusDateRange(theOverallRange);
}
/**
* Build the custom range.
*/
private void buildCustomRange() {
/* Previous and next are disallowed */
isPrevOK = false;
isNextOK = false;
/* Reset anomalies */
if (theEndDate.compareTo(theStartDate) < 0) {
theEndDate = theStartDate;
}
if (theBaseDate.compareTo(theStartDate) < 0) {
theBaseDate = theStartDate;
}
if (theBaseDate.compareTo(theEndDate) < 0) {
theBaseDate = theEndDate;
}
/* Create the range */
theRange = new OceanusDateRange(theStartDate, theEndDate);
}
/**
* Build the upTo range.
*/
private void buildUpToRange() {
/* Previous and next are disallowed */
isPrevOK = false;
isNextOK = false;
/* Record start and end dates */
theStartDate = theOverallRange.getStart();
theEndDate = theBaseDate;
/* Create the range */
theRange = new OceanusDateRange(theStartDate, theEndDate);
}
/**
* Build the containing range.
*/
private void buildContainingRange() {
/* Initialise the start date */
theStartDate = new OceanusDate(theBaseDate);
/* Adjust the date to the start of the relevant period */
theStartDate.startPeriod(thePeriod);
/* Initialise the end date */
theEndDate = new OceanusDate(theStartDate);
/* Adjust the date to cover the relevant period */
theEndDate.adjustForwardByPeriod(thePeriod);
theEndDate.adjustDay(-1);
/* Reset anomalies */
resetBaseAnomalies();
/* Create the range */
theRange = new OceanusDateRange(theStartDate, theEndDate);
}
/**
* Reset anomalies.
*/
private void resetBaseAnomalies() {
/* Reset anomalies */
final OceanusDate myFirstDate = theOverallRange.getStart();
if (myFirstDate != null
&& theStartDate.compareTo(myFirstDate) < 0) {
theStartDate = myFirstDate;
}
final OceanusDate myLastDate = theOverallRange.getEnd();
if (myLastDate != null
&& theEndDate.compareTo(myLastDate) > 0) {
theEndDate = myLastDate;
}
/* Previous is only allowed if we have not hit the first date */
isPrevOK = (myFirstDate == null)
|| (myFirstDate.compareTo(theStartDate) != 0);
/* Next is only allowed if we have not hit the last date */
isNextOK = (myLastDate == null)
|| (myLastDate.compareTo(theEndDate) != 0);
}
/**
* Build the starting range.
*/
private void buildStartingRange() {
/* Initialise the start date */
theStartDate = theBaseDate;
/* Initialise the end date */
theEndDate = new OceanusDate(theBaseDate);
/* Adjust the date to cover the relevant period */
theEndDate.adjustForwardByPeriod(thePeriod);
theEndDate.adjustDay(-1);
/* Reset anomalies */
resetBaseAnomalies();
/* Create the range */
theRange = new OceanusDateRange(theStartDate, theEndDate);
}
/**
* Build the ending range.
*/
private void buildEndingRange() {
/* Initialise the end date */
theEndDate = theBaseDate;
/* Initialise the start date */
theStartDate = new OceanusDate(theBaseDate);
/* Adjust the date to cover the relevant period */
theStartDate.adjustBackwardByPeriod(thePeriod);
theStartDate.adjustDay(1);
/* Reset anomalies */
resetBaseAnomalies();
/* Create the range */
theRange = new OceanusDateRange(theStartDate, theEndDate);
}
/**
* Adjust forwards to the next period.
*/
private void nextPeriod() {
/* Initialise the date */
OceanusDate myDate = new OceanusDate(theBaseDate);
/* Adjust the date appropriately */
myDate.adjustForwardByPeriod(thePeriod);
/* Make sure that we do not go beyond the date range */
final OceanusDate myLastDate = theOverallRange.getEnd();
if (myLastDate != null
&& myDate.compareTo(myLastDate) > 0) {
myDate = myLastDate;
}
/* Store the date */
theBaseDate = myDate;
}
/**
* Adjust backwards to the previous period.
*/
private void previousPeriod() {
/* Initialise the date */
OceanusDate myDate = new OceanusDate(theBaseDate);
/* Adjust the date appropriately */
myDate.adjustBackwardByPeriod(thePeriod);
/* Make sure that we do not go beyond the date range */
final OceanusDate myFirstDate = theOverallRange.getStart();
if (myFirstDate != null
&& myDate.compareTo(myFirstDate) < 0) {
myDate = myFirstDate;
}
/* Store the date */
theBaseDate = myDate;
}
}