package com.one;

import java.util.Random;

/**
 * Значение Vu - индикатора.
 */
public class VolumeUnit
{
	protected static final int FP_SHIFT = 16;
	protected static Random rnd = new Random();
	
	protected int minvalue, maxvalue;
	protected int current, target, updatetarget;
	protected int filldelta, reldelta;
	protected boolean dirflag;
	protected int fillfactor, relfactor;

	public VolumeUnit(int minvalue, int maxvalue, int fillsteps, int relsteps, int fillfactor, int relfactor)
	{
		this.minvalue = minvalue << FP_SHIFT;
		this.maxvalue = maxvalue << FP_SHIFT;

		this.fillfactor = fillfactor;
		this.relfactor = relfactor;
		
		filldelta = ((maxvalue - minvalue) << FP_SHIFT) / fillsteps;
		reldelta = ((maxvalue - minvalue) << FP_SHIFT) / relsteps;

		setTarget(0);
	}

	public void setTarget(int value)
	{
		target = value << FP_SHIFT;

		if(target < minvalue)
		{
			target = minvalue;
		}
		else if(target > maxvalue)
		{
			target = maxvalue;
		}

        updatetarget = target;
		dirflag = target >= current;
	}

    public void setValue(int value)
    {
		current = value << FP_SHIFT;

		if(current < minvalue)
		{
			current = minvalue;
		}
		else if(current > maxvalue)
		{
			current = maxvalue;
		}

        setTarget(value);
    }
	
	public int nextValue(boolean update)
	{
		if(update)
		{
			if(dirflag ? current >= updatetarget : current <= updatetarget)
			{
				target = minvalue + (rnd.nextInt() & 0x7FFFFFFF) % (maxvalue - minvalue + 1);
				dirflag = target >= current;

				if(dirflag)
				{
					updatetarget = current + (rnd.nextInt() & 0x7FFFFFFF) % ((target - current) / fillfactor + 1);
				}
				else
				{
					updatetarget = current - (rnd.nextInt() & 0x7FFFFFFF) % ((current - target) / relfactor + 1);
				}
			}
		}
		
		if(current < target)
		{
			current += filldelta;
			
			if(current > target)
			{
				current = target;
			}
		}
		else if(current > target)
		{
			current -= reldelta;

			if(current < target)
			{
				current = target;
			}
		}
		
		return current >>> FP_SHIFT;
	}
}
