// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/InterRangeDoubleConverter.java
// public static InterRangeDoubleConverter converterFromNormalTo(double toLimit1, double toLimit2) {
// 	return converterFromNormalTo(range(toLimit1, toLimit2));
// }
// 
// Path: public-java/devices/iamcontent-pololu-servo-controllers/src/main/java/com/iamcontent/device/controller/pololu/maestro/DefaultPololuServoConfig.java
// public static AnalogIOSource<Integer> rawAnalogIOSource() {
// 	return AnalogIOSource.rawAnalogIOSource(servoController());
// }
// 
// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/geom/Geometry.java
// public enum ThreeDimension {
// 	X, Y, Z
// }
// 
// Path: public-java/io/iamcontent-io-channels/src/main/java/com/iamcontent/device/io/analog/AnalogIOSource.java
// public interface AnalogIOSource<C> extends PerChannelSource<C, AnalogIO> {
// 	
// 	/**
// 	 * Returns a AnalogIOSource that has new channel ids, as defined by the given function.
// 	 */
// 	default <NewChannelId> AnalogIOSource<NewChannelId> remapped(Function<NewChannelId, C> remapping) {
// 		return new RemappedAnalogIOSource<NewChannelId, C>(this, remapping);
// 	}
// 
// 	/**
// 	 * Returns a proxy AnalogIO that is two-way calibrated representation of this instance.
// 	 */
// 	default AnalogIOSource<C> calibrated(AnalogIOSourceCalibration<C> calibration) {
// 		return new CalibratedAnalogIOSource<C>(this, calibration);
// 	}
// 
// 	public static <C> AnalogIOSource<C> rawAnalogIOSource(final AnalogIOController<C> controller) {
// 		return new AnalogIOSource<C>() {
// 			@Override
// 			public AnalogIO forChannel(C channelId) {
// 				return new RawAnalogIO<C>(controller, channelId);
// 			}
// 		};
// 	}
// }
// 
// Path: public-java/io/iamcontent-io-channels/src/main/java/com/iamcontent/device/io/analog/AnalogIOSourceCalibration.java
// public interface AnalogIOSourceCalibration<C> extends PerChannelSource<C, AnalogIOCalibration> {
// 
// 	public static <C> DefaultingAnalogIOSourceCalibration<C> analogIOSourceCalibration(AnalogIOCalibration calibration) {
// 		return new DefaultingAnalogIOSourceCalibration<C>(calibration);
// 	}
// 
// 	public static <C> DefaultingAnalogIOSourceCalibration<C> analogIOSourceCalibration() {
// 		return analogIOSourceCalibration(AnalogIOCalibration.IDENTITY);
// 	}
// }
// 
// Path: public-java/io/iamcontent-io-channels/src/main/java/com/iamcontent/device/io/analog/impl/ImmutableAnalogIOCalibration.java
// public class ImmutableAnalogIOCalibration implements AnalogIOCalibration {
// 
// 	private final DoubleConverter value;
// 	
// 	public ImmutableAnalogIOCalibration(DoubleConverter value) {
// 		this.value = value;
// 	}
// 
// 	@Override
// 	public DoubleConverter value() {
// 		return value;
// 	}
// }
// 
// Path: public-java/robots/iamcontent-robonova-1/src/main/java/com/iamcontent/robot/robonova1/Robonova.java
// public interface Robonova {
// 	ServoSource<ServoId> servos();
// 	AnalogIOSource<ThreeDimension> accelerometer();
// }


import static com.iamcontent.core.math.InterRangeDoubleConverter.converterFromNormalTo;
import static com.iamcontent.device.controller.pololu.maestro.DefaultPololuServoConfig.rawAnalogIOSource;
import java.util.function.Function;
import com.iamcontent.core.geom.Geometry.ThreeDimension;
import com.iamcontent.device.io.analog.AnalogIOSource;
import com.iamcontent.device.io.analog.AnalogIOSourceCalibration;
import com.iamcontent.device.io.analog.impl.ImmutableAnalogIOCalibration;
import com.iamcontent.robot.robonova1.Robonova;
/**
  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.robot.robonova1.custom1;




/**
 * Provides a custom accelerometer for my own {@link Robonova}.
 * @author Greg Elderfield
 */
public class CustomRobonovaAccelerometer {

	public static AnalogIOSource<ThreeDimension> accelerometer() {
		return rawAnalogIOSource()
				.calibrated(normalization())
				.remapped(remapping())
				.calibrated(tuning());
	}
	
	private static AnalogIOSourceCalibration<Integer> normalization() {
		return AnalogIOSourceCalibration.analogIOSourceCalibration(new ImmutableAnalogIOCalibration(converterFromNormalTo(0.0, 255.0))); // FIXME: Create default normalization for Poulu IO
	}
	
	private static Function<ThreeDimension, Integer> remapping() {
		return new Function<ThreeDimension, Integer>() {
			@Override
			public Integer apply(ThreeDimension dimension) {
				switch (dimension) {
				case X:
					return 0;
				case Y:
					return 1;
				case Z:
					return 2;
				default:
// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/math/InterRangeDoubleConverter.java
// public static InterRangeDoubleConverter converterFromNormalTo(double toLimit1, double toLimit2) {
// 	return converterFromNormalTo(range(toLimit1, toLimit2));
// }
// 
// Path: public-java/devices/iamcontent-pololu-servo-controllers/src/main/java/com/iamcontent/device/controller/pololu/maestro/DefaultPololuServoConfig.java
// public static AnalogIOSource<Integer> rawAnalogIOSource() {
// 	return AnalogIOSource.rawAnalogIOSource(servoController());
// }
// 
// Path: public-java/iamcontent-core/src/main/java/com/iamcontent/core/geom/Geometry.java
// public enum ThreeDimension {
// 	X, Y, Z
// }
// 
// Path: public-java/io/iamcontent-io-channels/src/main/java/com/iamcontent/device/io/analog/AnalogIOSource.java
// public interface AnalogIOSource<C> extends PerChannelSource<C, AnalogIO> {
// 	
// 	/**
// 	 * Returns a AnalogIOSource that has new channel ids, as defined by the given function.
// 	 */
// 	default <NewChannelId> AnalogIOSource<NewChannelId> remapped(Function<NewChannelId, C> remapping) {
// 		return new RemappedAnalogIOSource<NewChannelId, C>(this, remapping);
// 	}
// 
// 	/**
// 	 * Returns a proxy AnalogIO that is two-way calibrated representation of this instance.
// 	 */
// 	default AnalogIOSource<C> calibrated(AnalogIOSourceCalibration<C> calibration) {
// 		return new CalibratedAnalogIOSource<C>(this, calibration);
// 	}
// 
// 	public static <C> AnalogIOSource<C> rawAnalogIOSource(final AnalogIOController<C> controller) {
// 		return new AnalogIOSource<C>() {
// 			@Override
// 			public AnalogIO forChannel(C channelId) {
// 				return new RawAnalogIO<C>(controller, channelId);
// 			}
// 		};
// 	}
// }
// 
// Path: public-java/io/iamcontent-io-channels/src/main/java/com/iamcontent/device/io/analog/AnalogIOSourceCalibration.java
// public interface AnalogIOSourceCalibration<C> extends PerChannelSource<C, AnalogIOCalibration> {
// 
// 	public static <C> DefaultingAnalogIOSourceCalibration<C> analogIOSourceCalibration(AnalogIOCalibration calibration) {
// 		return new DefaultingAnalogIOSourceCalibration<C>(calibration);
// 	}
// 
// 	public static <C> DefaultingAnalogIOSourceCalibration<C> analogIOSourceCalibration() {
// 		return analogIOSourceCalibration(AnalogIOCalibration.IDENTITY);
// 	}
// }
// 
// Path: public-java/io/iamcontent-io-channels/src/main/java/com/iamcontent/device/io/analog/impl/ImmutableAnalogIOCalibration.java
// public class ImmutableAnalogIOCalibration implements AnalogIOCalibration {
// 
// 	private final DoubleConverter value;
// 	
// 	public ImmutableAnalogIOCalibration(DoubleConverter value) {
// 		this.value = value;
// 	}
// 
// 	@Override
// 	public DoubleConverter value() {
// 		return value;
// 	}
// }
// 
// Path: public-java/robots/iamcontent-robonova-1/src/main/java/com/iamcontent/robot/robonova1/Robonova.java
// public interface Robonova {
// 	ServoSource<ServoId> servos();
// 	AnalogIOSource<ThreeDimension> accelerometer();
// }


// Path: public-java/robots/iamcontent-robonova-1/src/main/java/com/iamcontent/robot/robonova1/custom1/CustomRobonovaAccelerometer.java
import static com.iamcontent.core.math.InterRangeDoubleConverter.converterFromNormalTo;
import static com.iamcontent.device.controller.pololu.maestro.DefaultPololuServoConfig.rawAnalogIOSource;
import java.util.function.Function;
import com.iamcontent.core.geom.Geometry.ThreeDimension;
import com.iamcontent.device.io.analog.AnalogIOSource;
import com.iamcontent.device.io.analog.AnalogIOSourceCalibration;
import com.iamcontent.device.io.analog.impl.ImmutableAnalogIOCalibration;
import com.iamcontent.robot.robonova1.Robonova;

/**
  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.robot.robonova1.custom1;




/**
 * Provides a custom accelerometer for my own {@link Robonova}.
 * @author Greg Elderfield
 */
public class CustomRobonovaAccelerometer {

	public static AnalogIOSource<ThreeDimension> accelerometer() {
		return rawAnalogIOSource()
				.calibrated(normalization())
				.remapped(remapping())
				.calibrated(tuning());
	}
	
	private static AnalogIOSourceCalibration<Integer> normalization() {
		return AnalogIOSourceCalibration.analogIOSourceCalibration(new ImmutableAnalogIOCalibration(converterFromNormalTo(0.0, 255.0))); // FIXME: Create default normalization for Poulu IO
	}
	
	private static Function<ThreeDimension, Integer> remapping() {
		return new Function<ThreeDimension, Integer>() {
			@Override
			public Integer apply(ThreeDimension dimension) {
				switch (dimension) {
				case X:
					return 0;
				case Y:
					return 1;
				case Z:
					return 2;
				default:
					throw new IllegalStateException("Dimension not recognized: " + dimension);