package ie.omk.smpp.util;

import java.util.Calendar;
import java.util.TimeZone;

/**
 * Implementation of {@link ie.omk.smpp.util.SMPPDate} that represents an
 * absolute time specification.
 * 
 * @version $Id: $
 */
class AbsoluteSMPPDate extends SMPPDate {
    private static final long serialVersionUID = 1;
    
    private Calendar calendar;
    private boolean hasTimeZone = true;
    
    AbsoluteSMPPDate(Calendar calendar) {
        this.calendar = calendar;
    }
    
    AbsoluteSMPPDate(Calendar calendar, boolean withTimeZone) {
        this.calendar = calendar;
        this.hasTimeZone = withTimeZone;
    }
    
    public Calendar getCalendar() {
        return calendar;
    }

    public int getDay() {
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    public int getHour() {
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    public int getMinute() {
        return calendar.get(Calendar.MINUTE);
    }

    public int getMonth() {
        return calendar.get(Calendar.MONTH) + 1;
    }

    public int getSecond() {
        return calendar.get(Calendar.SECOND);
    }

    public int getYear() {
        return calendar.get(Calendar.YEAR);
    }

    public int getTenth() {
        return calendar.get(Calendar.MILLISECOND) / 100;
    }
    
    public boolean hasTimezone() {
        return hasTimeZone;
    }

    public boolean isAbsolute() {
        return true;
    }

    public TimeZone getTimeZone() {
        if (hasTimeZone) {
            return calendar.getTimeZone();
        } else {
            return null;
        }
    }
    
    public int getUtcOffset() {
        TimeZone tz = calendar.getTimeZone();
        return (Math.abs(tz.getRawOffset()) / 3600000) * 4;
    }
    
    public char getSign() {
        char sign;
        if (!hasTimeZone) {
            sign = (char) 0;
        } else {
            if (calendar.getTimeZone().getRawOffset() >= 0) {
                sign = '+';
            } else {
                sign = '-';
            }
        }
        return sign;
    }
    
    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof AbsoluteSMPPDate)) {
            return false;
        }
        AbsoluteSMPPDate other = (AbsoluteSMPPDate) obj;
        return calendar.equals(other.calendar)
            && hasTimeZone == other.hasTimeZone;
    }
    
    public int hashCode() {
        int hc1 = calendar.hashCode();
        return hc1 + (hasTimeZone ? 6203 : 7907);
    }
}

@@ -377,15 +377,8 @@
 Zone
- = true
 ;%0A  
@@ -430,33 +430,33 @@
         this
-.
+(
 calendar
  = calendar;
@@ -439,35 +439,31 @@
 his(calendar
- = calendar
+, true)
 ;%0A    %7D%0A    
@@ -2256,24 +2256,93 @@
 urn 
-calendar.equals(
+hasTimeZone == other.hasTimeZone%0A            && compareCalendarFields(this.calendar, 
 othe
@@ -2356,73 +2356,25 @@
 dar)
+;
 %0A    
+%7D%0A
     
+%0A
     
-&& hasTimeZone == other.hasTimeZone;%0A    %7D%0A    %0A    
 publ
@@ -2479,16 +2479,1288 @@
 3 : 7907
+);%0A    %7D%0A    %0A    public String toString() %7B%0A        return new StringBuffer(calendar.toString()).append(%22 hasTz=%22)%0A        .append(hasTimeZone).toString();%0A    %7D%0A    %0A    private boolean compareCalendarFields(Calendar calendar1, Calendar calendar2) %7B%0A        boolean equal = true;%0A        equal &= compareField(calendar1, calendar2, Calendar.YEAR);%0A        equal &= compareField(calendar1, calendar2, Calendar.MONTH);%0A        equal &= compareField(calendar1, calendar2, Calendar.DAY_OF_MONTH);%0A        equal &= compareField(calendar1, calendar2, Calendar.HOUR_OF_DAY);%0A        equal &= compareField(calendar1, calendar2, Calendar.MINUTE);%0A        equal &= compareField(calendar1, calendar2, Calendar.SECOND);%0A        int tenth1 = calendar1.get(Calendar.MILLISECOND) / 100;%0A        int tenth2 = calendar2.get(Calendar.MILLISECOND) / 100;%0A        equal &= tenth1 == tenth2;%0A        if (hasTimeZone) %7B%0A            int rawOffset1 = calendar1.getTimeZone().getRawOffset();%0A            int rawOffset2 = calendar2.getTimeZone().getRawOffset();%0A            equal &= rawOffset1 == rawOffset2;%0A        %7D%0A        return equal;%0A    %7D%0A    %0A    private boolean compareField(Calendar calendar1, Calendar calendar2, int field) %7B%0A        return calendar1.get(field) == calendar2.get(field
 );%0A    %7D

Implement a better equals. Implement hashCode. Add a simple toString implementation.