/*
* (C) Copyright 2006-2008, by Projity Inc. and Contributors.
* http://www.projity.com
*
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
*
*/
package com.projity.contrib.calendar;
import java.util.Calendar;
import java.util.Collection;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.lang.time.DateUtils;
import org.jdesktop.swing.calendar.DateSpan;
/**
*
*/
public class ContribIntervals extends TreeSet{
/**
*
*/
public ContribIntervals() {
super(new Comparator(){
public int compare(Object o1, Object o2) {
DateSpan d1=(DateSpan)o1; //Only want to compare DateSpan no need to use instanceof
DateSpan d2=(DateSpan)o2;
if (d1.getStart()<d2.getStart()||(d1.getStart()==d2.getStart()&&d1.getEnd()<d2.getEnd())) return -1;
else if (d1.getStart()>d2.getStart()||(d1.getStart()==d2.getStart()&&d1.getEnd()>d2.getEnd())) return 1;
else return 0;
}
});
}
public ContribIntervals(Comparator c) {
super(c);
}
protected DateSpan createInterval(long start,long end) {
return new DateSpan(start,end);
}
protected DateSpan mergeIntervals(DateSpan i1,DateSpan i2) {
return new DateSpan(Math.min(i1.getStart(),i2.getStart()),Math.max(i1.getEnd(),i2.getEnd()));
}
public boolean add(Object o) {
DateSpan toAdd=(DateSpan)o;
SortedSet set=headSet(o);
if (set.size()>0){
DateSpan interval=(DateSpan)set.last();
if (interval.getEnd()>=toAdd.getStart())
toAdd=mergeIntervals(toAdd,interval);
}
set=tailSet(o);
if (set.size()>0){
DateSpan interval=(DateSpan)set.first();
if (toAdd.getEnd()>=interval.getStart())
toAdd=mergeIntervals(toAdd,interval);
}
return super.add(toAdd);
}
public boolean addAll(Collection c) {
if (c==null) return false;
boolean added=false;
for (Iterator i=c.iterator();i.hasNext();){
if (super.add(i.next())) added=true;
}
return added;
}
public long getEnd() {
return (size()==0)?-1:((DateSpan)last()).getEnd();
}
public long getStart() {
return (size()==0)?-1:((DateSpan)first()).getStart();
}
public boolean containsDate(long date){
for (Iterator i=iterator();i.hasNext();){ //a more optimized version can be found
DateSpan interval=(DateSpan)i.next();
if (interval.getStart()<=date&&date<=interval.getEnd()) return true;
}
return false;
}
void eliminateWeekdayDuplicates(boolean weekDays[]) {
Calendar cal = calendarInstance();
for (Iterator i=iterator();i.hasNext();){ //a more optimized version can be found
DateSpan interval=(DateSpan)i.next();
cal.setTimeInMillis(interval.getStart());
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) -1;
// remove any days which correspond to a selected week day
for (int d = 0; d < 7; d++) {
if (weekDays[d] && d == dayOfWeek) {
i.remove();
}
}
}
}
/*public void xorAdd(HasStartAndEnd o,Closure removeFunctor,Closure addFunctor){
HasStartAndEnd toAdd=o;
SortedSet set=headSet(o);
if (set.size()>0){
HasStartAndEnd previous=(HasStartAndEnd)set.last();
if (previous.getEnd()>=toAdd.getStart()){
remove(previous);
if (previous.getEnd()==toAdd.getStart()){
toAdd=createInterval(previous.getStart(),toAdd.getEnd());
}else{
if (previous.getStart()<toAdd.getStart())
super.add(createInterval(previous.getStart(),toAdd.getStart()));
removeFunctor.execute(createInterval(toAdd.getStart(),previous.getEnd()));
toAdd=createInterval(previous.getEnd(),toAdd.getEnd());
}
}
}
set=tailSet(o);
if (set.size()>0){
HasStartAndEnd next=(HasStartAndEnd)set.first();
if (next.getStart()<=toAdd.getEnd()){
remove(next);
if (next.getStart()==toAdd.getEnd()){
createInterval(toAdd.getStart(),next.getEnd());
}else{
if (next.getEnd()>toAdd.getEnd())
super.add(createInterval(toAdd.getEnd(),next.getEnd()));
removeFunctor.execute(createInterval(next.getStart(),toAdd.getEnd()));
toAdd=createInterval(toAdd.getStart(),next.getStart());
}
}
}
if (toAdd.getStart()<=toAdd.getEnd()){
super.add(toAdd);
addFunctor.execute(toAdd);
}
}*/
public static GregorianCalendar calendarInstance() {
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeZone(DateUtils.UTC_TIME_ZONE);
return cal;
}
}