package org.skyve.domain.types.converters.decimal;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

import org.skyve.domain.types.Decimal5;
import org.skyve.domain.types.converters.Converter;
import org.skyve.domain.types.converters.Format;
import org.skyve.domain.types.converters.Validator;
import org.skyve.metadata.model.Attribute.AttributeType;

public class Decimal5TimeDuration implements Converter<Decimal5> {
	private static final MathContext MATH_CONTEXT = new MathContext(4, RoundingMode.HALF_UP);

	@Override
	public Decimal5 fromDisplayValue(String displayValue) throws Exception {
		int colonIndex = displayValue.indexOf(':');
		if (colonIndex < 0) {
			throw new IllegalArgumentException("Time Duration is not formatted correctly.");
		}

		Decimal5 hours = new Decimal5(displayValue.substring(0, colonIndex));
		Decimal5 minutes = new Decimal5(displayValue.substring(colonIndex + 1));
		minutes = minutes.divide(Decimal5.SIXTY);

		Decimal5 returnValue;
		if (hours.compareTo(Decimal5.ZERO) >= 0) {
			returnValue = hours.add(minutes);
		}
		else {
			returnValue = hours.subtract(minutes);
		}

		return returnValue;
	}

	@Override
	public String toDisplayValue(Decimal5 value) throws Exception {
		BigDecimal decimalValue = value.bigDecimalValue();
		int hours = decimalValue.round(new MathContext(0, RoundingMode.DOWN)).intValue();

		decimalValue = decimalValue.subtract(new BigDecimal(hours));
		decimalValue = decimalValue.multiply(Decimal5.SIXTY.bigDecimalValue(), MATH_CONTEXT);
		decimalValue = decimalValue.round(new MathContext(0, RoundingMode.HALF_UP));
		int minutesValue = (new Integer(decimalValue.intValue())).intValue();

		// handle negative time
		String sign = "";
		if (hours < 0 || minutesValue < 0) {
			sign = "-";
		}

		String minutes = new Integer(Math.abs(minutesValue)).toString();
		if (minutes.length() == 1) {
			minutes = '0' + minutes;
		}

		return sign + Math.abs(hours) + ":" + minutes;
	}

	@Override
	public AttributeType getAttributeType() {
		return AttributeType.decimal5;
	}

	@Override
	public Format<Decimal5> getFormat() {
		return null;
	}

	@Override
	public Validator<Decimal5> getValidator() {
		return null;
	}
}

@@ -1691,16 +1691,185 @@
 lue();%0A%0A
+%09%09// handle round up to 60 minutes%0A%09%09if (minutesValue == 60) %7B%0A%09%09%09minutesValue = 0;%0A%09%09%09hours++;%0A%09%09%7D%0A%09%09if (minutesValue == -60) %7B%0A%09%09%09minutesValue = 0;%0A%09%09%09hours--;%0A%09%09%7D%0A%09%09%0A
 %09%09// han
@@ -1907,24 +1907,25 @@
  = %22%22;%0A%09%09if 
+(
 (hours %3C 0 %7C
@@ -1926,12 +1926,14 @@
  %3C 0
+)
  %7C%7C 
+(
 minu
@@ -1941,24 +1941,25 @@
 esValue %3C 0)
+)
  %7B%0A%09%09%09sign =

Fix rounding problem with displaying decimal 5 as hours and minutes duration.