/*
 *******************************************************************************
 * Copyright (C) 1996-2004, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 */

package com.ibm.icu.dev.tool.timescale;

import java.util.Locale;

import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.SimpleTimeZone;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.UniversalTimeScale;

/**
 * This class calculates the minimum and maximum values which can be
 * used as arguments to <code>toLong</code> and <code>from</code>.
 * 
 * NOTE: If you change the way in which these values are calculated, it
 * may be necessary to disable to <code>toRangeCheck()</code> and
 * <code>fromRangeCheck()</code> methods in the <code>UniversalTimeScale</code>
 * for all of the calculations to run without throwing an error.
 * 
 * @see com.ibm.icu.util.UniversalTimeScale
 * 
 * @draft ICU 3.2
 */
public class CalculateLimits {

    /**
     * The default constructor.
     * 
     * @draft ICU 3.2
     */
    public CalculateLimits()
    {
    }

    /**
     * This method first calculates the <code>from</code> limits by
     * passing <code>Long.MIN_VALUE</code> and <code>Long.MAX_VALUE</code> to
     * the (internal) <code>toBigDecimalTrunc()</code> method. Any values outside
     * of the range of a <code>long</code> are pinned.
     * 
     * The mimimum and maximum values for <code>toLong</code> are calulated by passing
     * the min and max values calculated above to <code>BigDecimalFrom()</code>. Because
     * this method will round, the returned values are adjusted to take this into account.
     * 
     * @see com.ibm.icu.util.UniversalTimeScale
     * 
     * @param args - the command line arugments
     * 
     * @draft ICU 3.2
     */
    public static void main(String[] args)
    {
        TimeZone utc = new SimpleTimeZone(0, "UTC");
        Calendar cal = Calendar.getInstance(utc, Locale.ENGLISH);
        MessageFormat fmt = new MessageFormat("{0}L, {1}L, {2}L, {3}L");        
        BigDecimal universalMin = new BigDecimal(Long.MIN_VALUE);
        BigDecimal universalMax = new BigDecimal(Long.MAX_VALUE);
        Object limitArgs[] = {null, null, null, null};
        
        System.out.println("\nTo, From limits:");
        
        // from limits
        for(int scale = 0; scale < UniversalTimeScale.MAX_SCALE; scale += 1) {
            BigDecimal min = UniversalTimeScale.toBigDecimalTrunc(universalMin, scale).max(universalMin);
            BigDecimal max = UniversalTimeScale.toBigDecimalTrunc(universalMax, scale).min(universalMax);
            long minLong   = min.longValue();
            long maxLong   = max.longValue();
            
            limitArgs[2] = min.toString();
            limitArgs[3] = max.toString();

            // to limits
            BigDecimal minTrunc   = UniversalTimeScale.bigDecimalFrom(min, scale);
            BigDecimal maxTrunc   = UniversalTimeScale.bigDecimalFrom(max, scale);
            BigDecimal minResidue = minTrunc.subtract(universalMin);
            BigDecimal maxResidue = universalMax.subtract(maxTrunc);
            long units            = UniversalTimeScale.getTimeScaleValue(scale, UniversalTimeScale.UNITS_VALUE);
            BigDecimal half       = new BigDecimal(units == 1? 0: units / 2 - 1);
            
            min = minTrunc.subtract(minResidue.min(half));
            max = maxTrunc.add(maxResidue.min(half));
            limitArgs[0] = min.toString();
            limitArgs[1] = max.toString();
            
            System.out.println(fmt.format(limitArgs));
            
            // round-trip test the from limits
            if(UniversalTimeScale.toLong(UniversalTimeScale.from(minLong, scale), scale) != minLong) {
                System.out.println("OOPS: min didn't round trip!");
            }
            
            if(UniversalTimeScale.toLong(UniversalTimeScale.from(maxLong, scale), scale) != maxLong) {
                System.out.println("OOPS: max didn't round trip!");
            }
            
            // make sure that the to limits convert to the from limits
            if(UniversalTimeScale.toLong(min.longValue(), scale) != minLong) {
                System.out.println("OOPS: toLong(toMin) != fromMin");
            }
            
            if(UniversalTimeScale.toLong(max.longValue(), scale) != maxLong) {
                System.out.println("OOPS: toLong(toMax) != fromMax");
            }
        }
    }
}
