/*
 * Copyright 2009 Google Inc.
 * 
 * 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.
 */

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You 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.
 * 
 * INCLUDES MODIFICATIONS BY GOOGLE.
 */
/**
 * author Elena Semukhina
 */
package com.google.gwt.emultest.java.math;

import com.google.gwt.emultest.java.util.EmulTestBase;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

/**
 * Class: java.math.BigDecimal Methods: movePointLeft, movePointRight, scale,
 * setScale, unscaledValue *.
 */
public class BigDecimalScaleOperationsTest extends EmulTestBase {

  public void testScaleByPowerOfTen() {
    BigDecimal val = BigDecimal.ONE.scaleByPowerOfTen(1);
    assertEquals(10, val.intValue());
  }

  /**
   * Check the default scale.
   */
  public void testScaleDefault() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int cScale = 0;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a));
    assertTrue("incorrect scale", aNumber.scale() == cScale);
  }

  /**
   * Check a negative scale.
   */
  public void testScaleNeg() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = -10;
    int cScale = -10;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    assertTrue("incorrect scale", aNumber.scale() == cScale);
  }

  /**
   * Check a positive scale.
   */
  public void testScalePos() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 10;
    int cScale = 10;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    assertTrue("incorrect scale", aNumber.scale() == cScale);
  }

  /**
   * Check the zero scale.
   */
  public void testScaleZero() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 0;
    int cScale = 0;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    assertTrue("incorrect scale", aNumber.scale() == cScale);
  }

  /**
   * Check the unscaled value.
   */
  public void testUnscaledValue() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 100;
    BigInteger bNumber = new BigInteger(a);
    BigDecimal aNumber = new BigDecimal(bNumber, aScale);
    assertTrue("incorrect unscaled value", aNumber.unscaledValue().equals(
        bNumber));
  }

  /**
   * Set a greater new scale.
   */
  public void testSetScaleGreater() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 18;
    int newScale = 28;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertEquals("incorrect value", 0, bNumber.compareTo(aNumber));
  }

  /**
   * Set a less new scale; this.scale == 8; newScale == 5.
   */
  public void testSetScaleLess() {
    String a = "2.345726458768760000E+10";
    int newScale = 5;
    BigDecimal aNumber = new BigDecimal(a);
    BigDecimal bNumber = aNumber.setScale(newScale);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertEquals("incorrect value", 0, bNumber.compareTo(aNumber));
  }

  /**
   * Verify an exception when setting a new scale.
   */
  public void testSetScaleException() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    try {
      aNumber.setScale(newScale);
      fail("ArithmeticException has not been caught");
    } catch (ArithmeticException e) {
      assertEquals("Improper exception message", "Rounding necessary",
          e.getMessage());
    }
  }

  /**
   * Set the same new scale.
   */
  public void testSetScaleSame() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 18;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.equals(aNumber));
  }

  /**
   * Set a new scale.
   */
  public void testSetScaleRoundUp() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478139";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_UP);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * Set a new scale.
   */
  public void testSetScaleRoundDown() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478138";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_DOWN);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * Set a new scale.
   */
  public void testSetScaleRoundCeiling() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478139";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_CEILING);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * Set a new scale.
   */
  public void testSetScaleRoundFloor() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478138";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_FLOOR);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * Set a new scale.
   */
  public void testSetScaleRoundHalfUp() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478138";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_UP);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * Set a new scale.
   */
  public void testSetScaleRoundHalfDown() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478138";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_DOWN);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * Set a new scale.
   */
  public void testSetScaleRoundHalfEven() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478138";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_EVEN);
    assertTrue("incorrect scale", bNumber.scale() == newScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * SetScale(int, RoundingMode).
   */
  public void testSetScaleIntRoundingMode() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 28;
    int newScale = 18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal result = aNumber.setScale(newScale, RoundingMode.HALF_EVEN);
    String res = "123121247898748298842980.877981045763478138";
    int resScale = 18;
    assertEquals("incorrect value", res, result.toString());
    assertEquals("incorrect scale", resScale, result.scale());
  }

  /**
   * Move the decimal point to the left; the shift value is positive.
   */
  public void testMovePointLeftPos() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 28;
    int shift = 18;
    int resScale = 46;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.movePointLeft(shift);
    assertTrue("incorrect scale", bNumber.scale() == resScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
  }

  /**
   * Move the decimal point to the left; the shift value is positive.
   */
  public void testMovePointLeftNeg() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 28;
    int shift = -18;
    int resScale = 10;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.movePointLeft(shift);
    assertTrue("incorrect scale", bNumber.scale() == resScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
  }

  /**
   * Move the decimal point to the right; the shift value is positive.
   */
  public void testMovePointRightPosGreater() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 28;
    int shift = 18;
    int resScale = 10;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.movePointRight(shift);
    assertTrue("incorrect scale", bNumber.scale() == resScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
  }

  /**
   * Move the decimal point to the right; the shift value is positive.
   */
  public void testMovePointRightPosLess() {
    String a = "1231212478987482988429808779810457634781384756794987";
    String b = "123121247898748298842980877981045763478138475679498700";
    int aScale = 28;
    int shift = 30;
    int resScale = 0;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.movePointRight(shift);
    assertTrue("incorrect scale", bNumber.scale() == resScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
  }

  /**
   * Move the decimal point to the right; the shift value is positive.
   */
  public void testMovePointRightNeg() {
    String a = "1231212478987482988429808779810457634781384756794987";
    int aScale = 28;
    int shift = -18;
    int resScale = 46;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    BigDecimal bNumber = aNumber.movePointRight(shift);
    assertTrue("incorrect scale", bNumber.scale() == resScale);
    assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
  }

  /**
   * Move the decimal point to the right when the scale overflows.
   */
  public void testMovePointRightException() {
    String a = "12312124789874829887348723648726347429808779810457634781384756794987";
    int aScale = Integer.MAX_VALUE; // 2147483647
    int shift = -18;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    try {
      aNumber.movePointRight(shift);
      fail("ArithmeticException has not been caught");
    } catch (ArithmeticException e) {
      assertEquals("Improper exception message", "Underflow", e.getMessage());
    }
  }

  /**
   * precision().
   */
  public void testPrecision() {
    String a = "12312124789874829887348723648726347429808779810457634781384756794987";
    int aScale = 14;
    BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
    int prec = aNumber.precision();
    assertEquals(68, prec);
  }
}
