// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/DoubleRange.java
// public static final DoubleRange NORMAL_RANGE = range(0.0, 1.0);
// 
// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/DoubleRange.java
// public static final DoubleRange REVERSE_NORMAL_RANGE = range(1.0, 0.0);
// 
// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/DoubleRange.java
// public static DoubleRange range(double limit1, double limit2) {
// 	return new DoubleRange(limit1, limit2);
// }


import static com.iamcontent.core.math.DoubleRange.NORMAL_RANGE;
import static com.iamcontent.core.math.DoubleRange.REVERSE_NORMAL_RANGE;
import static com.iamcontent.core.math.DoubleRange.range;

/**
  IAmContent Public Libraries.
  Copyright (C) 2015-2021 Greg Elderfield
  @author Greg Elderfield, support@jarchitect.co.uk
 
  This program is free software; you can redistribute it and/or modify it under the terms of the
  GNU General Public License as published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.

  This program 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 General Public License for more details.

  You should have received a copy of the GNU General Public License along with this program;
  if not, write to the Free Software Foundation, Inc., 
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package com.iamcontent.core.math;



/**
 * Converts Double objects linearly according to two corresponding {@link Range} objects.
 * @author Greg Elderfield
 */
public class InterRangeDoubleConverter implements DoubleConverter {

	public static final ClampingMode DEFAULT_MODE = ClampingMode.CLAMPED;
	public static final InterRangeDoubleConverter REVERSE_NORMAL_CONVERTER = converterFromNormalTo(REVERSE_NORMAL_RANGE);
	
	/**
	 * Indicates whether a converted value should be clamped to its target range or not.
	 */
	public static enum ClampingMode {
		CLAMPED {
			@Override
			double apply(double d, DoubleRange r) {
				return r.clamp(d);
			}
		}, 
		UNCLAMPED {
			@Override
			double apply(double d, DoubleRange r) {
				return d;
			}
		};
		abstract double apply(double d, DoubleRange r);
	};
	
	private final DoubleRange fromRange, toRange;
	private final ClampingMode clampingMode;

	public InterRangeDoubleConverter(DoubleRange fromRange, DoubleRange toRange) {
		this(fromRange, toRange, DEFAULT_MODE);
	}
	
	public InterRangeDoubleConverter(DoubleRange fromRange, DoubleRange toRange, ClampingMode clampingMode) {
		this.fromRange = fromRange;
		this.toRange = toRange;
		this.clampingMode = clampingMode;
	}

	public static InterRangeDoubleConverter converterFromNormalTo(double toLimit1, double toLimit2) {

// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/DoubleRange.java
// public static final DoubleRange NORMAL_RANGE = range(0.0, 1.0);
// 
// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/DoubleRange.java
// public static final DoubleRange REVERSE_NORMAL_RANGE = range(1.0, 0.0);
// 
// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/DoubleRange.java
// public static DoubleRange range(double limit1, double limit2) {
// 	return new DoubleRange(limit1, limit2);
// }


// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/InterRangeDoubleConverter.java
import static com.iamcontent.core.math.DoubleRange.NORMAL_RANGE;
import static com.iamcontent.core.math.DoubleRange.REVERSE_NORMAL_RANGE;
import static com.iamcontent.core.math.DoubleRange.range;

/**
  IAmContent Public Libraries.
  Copyright (C) 2015-2021 Greg Elderfield
  @author Greg Elderfield, support@jarchitect.co.uk
 
  This program is free software; you can redistribute it and/or modify it under the terms of the
  GNU General Public License as published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.

  This program 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 General Public License for more details.

  You should have received a copy of the GNU General Public License along with this program;
  if not, write to the Free Software Foundation, Inc., 
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package com.iamcontent.core.math;



/**
 * Converts Double objects linearly according to two corresponding {@link Range} objects.
 * @author Greg Elderfield
 */
public class InterRangeDoubleConverter implements DoubleConverter {

	public static final ClampingMode DEFAULT_MODE = ClampingMode.CLAMPED;
	public static final InterRangeDoubleConverter REVERSE_NORMAL_CONVERTER = converterFromNormalTo(REVERSE_NORMAL_RANGE);
	
	/**
	 * Indicates whether a converted value should be clamped to its target range or not.
	 */
	public static enum ClampingMode {
		CLAMPED {
			@Override
			double apply(double d, DoubleRange r) {
				return r.clamp(d);
			}
		}, 
		UNCLAMPED {
			@Override
			double apply(double d, DoubleRange r) {
				return d;
			}
		};
		abstract double apply(double d, DoubleRange r);
	};
	
	private final DoubleRange fromRange, toRange;
	private final ClampingMode clampingMode;

	public InterRangeDoubleConverter(DoubleRange fromRange, DoubleRange toRange) {
		this(fromRange, toRange, DEFAULT_MODE);
	}
	
	public InterRangeDoubleConverter(DoubleRange fromRange, DoubleRange toRange, ClampingMode clampingMode) {
		this.fromRange = fromRange;
		this.toRange = toRange;
		this.clampingMode = clampingMode;
	}

	public static InterRangeDoubleConverter converterFromNormalTo(double toLimit1, double toLimit2) {

		return converterFromNormalTo(range(toLimit1, toLimit2));
