package bricks;

import com.tinkerforge.BrickletLCD20x4;

/**
 * Extends the original LCD20x4 Bricklet with some useful functions.
 * 
 * @author Gagahhag
 * @version 0.1
 * 
 */
public class BrickletLCD20x4Advanced extends BrickletLCD20x4 {

	private static final short CHARS_PER_LINE = 20;

	public BrickletLCD20x4Advanced(String uid) {
		super(uid);
	}

	/**
	 * Clears a specific line (0 to 3) from a specific position (0 to 19)
	 * 
	 * @param line
	 *            Line to clear
	 * @param start
	 *            Start position to clear
	 */
	public void clear(short line, short start) {
		clear(line, start, CHARS_PER_LINE);
	}

	/**
	 * Clears a specific line (0 to 3) from and to a specific position (0 to 19)
	 * 
	 * @param line
	 *            Line to clear
	 * @param start
	 *            Start position to clear
	 * @param end
	 *            End position to clear
	 */
	public void clear(short line, short start, short end) {
		for (short i = start; i < end; i++) {
			writeLine(line, i, " ");
		}
	}

	/**
	 * Creates a text ticker from right to left
	 * 
	 * @param line
	 *            LCD line (0-3) the ticker is created on
	 * @param start
	 *            Start position (0-10)
	 * @param length
	 *            Number of chars using for the ticker
	 * @param timeout
	 *            Time in milliseconds between each step
	 * @param text
	 *            Text used for the ticker
	 */
	public void ticker(short line, short start, short length, int timeout,
			String text) {

		ticker(line, start, length, timeout, text, ' ');
	}

	/**
	 * Creates a text ticker from right to left using a given fill char
	 * 
	 * @param line
	 *            LCD line (0-3) the ticker is created on
	 * @param start
	 *            Start position (0-10)
	 * @param length
	 *            Number of chars using for the ticker
	 * @param timeout
	 *            Time in milliseconds between each step
	 * @param text
	 *            Text used for the ticker
	 * @param fill
	 *            Character to fill rest of line
	 */
	public void ticker(short line, short start, short length, int timeout,
			String text, char fill) {
		ticker(line, start, length, timeout, text, fill, 1);
	}

	/**
	 * Creates a text ticker from right to left using a given fill char and
	 * repeats a given amount
	 * 
	 * @param line
	 *            LCD line (0-3) the ticker is created on
	 * @param start
	 *            Start position (0-10)
	 * @param length
	 *            Number of chars using for the ticker
	 * @param timeout
	 *            Time in milliseconds between each step
	 * @param text
	 *            Text used for the ticker
	 * @param fill
	 *            Character to fill rest of line
	 * @param repeatCount
	 *            Repeat scrolling amount
	 */
	public void ticker(short line, short start, short length, int timeout,
			String text, char fill, int repeatCount) {
		new TickerThread(line, start, length, timeout, text, fill, repeatCount);
	}

	/**
	 * Ticker thread that does the actual scrolling
	 * 
	 * @author boss
	 * 
	 */
	private class TickerThread extends Thread {
		private short line;
		private short start;
		private short length;
		private int timeout;
		private String text;
		private String fill;
		private int repeatCount;

		private TickerThread(final short line, final short start,
				final short length, final int timeout, final String text,
				final char fill, final int repeatCount) {
			this.line = line;
			this.start = start;
			this.length = length;
			this.timeout = timeout;
			this.text = text;
			this.fill = String.valueOf(fill);
			this.repeatCount = repeatCount;
			
			// Start immediately
			this.start();
		}

		/**
		 * Calculates the ticker based on text length and current position of
		 * the text within the ticker.
		 * 
		 * @param text
		 *            Text used for the ticker
		 * @param length
		 *            Length of the ticker
		 * @param pos
		 *            Actual position of text
		 * @param fill
		 *            Fill character
		 * @return Returns the ticker text to display
		 */
		private String buildString(String text, int length, int pos, String fill) {
			StringBuilder sb = new StringBuilder(length);
			int currLength = 0;

			for (int i = 0; i < pos - text.length(); i++) {
				sb.append(fill);
			}

			sb.append(text.substring((pos <= text.length()) ? text.length()
					- pos : 0));

			currLength = sb.length();
			for (int i = 0; i < length - currLength; i++) {
				sb.append(fill);
			}

			return sb.toString().substring(0, length);
		}

		@Override
		public void run() {
			for (int repeat = 0; repeat < repeatCount; repeat++) {
				for (short i = (short) (length + text.length()); i >= 0; i--) {
					try {

						writeLine(line, start,
								buildString(text, length, i, fill));

						Thread.sleep(timeout);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				writeLine(line, start, text.substring(0,
						(text.length() > length) ? length : text.length()));
			}
		}
	}
}
