/*******************************************************************************
 * Copyright (c) 2007 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 * 
 * Contributors: 
 * Michael Scharf (Wind River) - initial API and implementation
 *******************************************************************************/
package org.eclipse.tm.internal.terminal.model;

import org.eclipse.tm.terminal.model.ITerminalTextData;
import org.eclipse.tm.terminal.model.ITerminalTextDataSnapshot;
import org.eclipse.tm.terminal.model.LineSegment;
import org.eclipse.tm.terminal.model.Style;

/**
 * This class is optimized for scrolling the entire {@link #getHeight()}.
 * The scrolling is done by moving an offset into the data and using
 * the modulo operator.
 *
 */
public class TerminalTextDataFastScroll implements ITerminalTextData {
	
	final ITerminalTextData fData;
	private int fHeight;
	private int fMaxHeight;
	/**
	 * The offset into the array. 
	 */
	int fOffset;
	public TerminalTextDataFastScroll(ITerminalTextData data,int maxHeight) {
		fMaxHeight=maxHeight;
		fData=data;
		fData.setDimensions(maxHeight, fData.getWidth());
		if(maxHeight>2)
			assert shiftOffset(-2) || throwRuntimeException();
	}
	public TerminalTextDataFastScroll(int maxHeight) {
		this(new TerminalTextDataStore(),maxHeight);
	}
	public TerminalTextDataFastScroll() {
		this(new TerminalTextDataStore(),1);
	}
	/**
	 * This is used in asserts to throw an {@link RuntimeException}.
	 * This is useful for tests.
	 * @return never -- throws an exception
	 */
	private boolean throwRuntimeException() {
		throw new RuntimeException();
	}
	/**
	 * 
	 * @param line
	 * @return the actual line number in {@link #fData}
	 */
	int getPositionOfLine(int line) {
		return (line+fOffset)%fMaxHeight;
	}
	/**
	 * Moves offset by delta. This does <b>not</b> move the data!
	 * @param delta
	 */
	void moveOffset(int delta) {
		assert Math.abs(delta)<fMaxHeight || throwRuntimeException();
		fOffset=(fMaxHeight+fOffset+delta)%fMaxHeight;
		
	}
	/**
	 * Test method to shift the offset for testing (if assert ==true)
	 * @param shift TODO
	 * @return true
	 */
	private boolean shiftOffset(int shift) {
		moveOffset(shift);
		return true;
	}
	public void addLine() {
		if(getHeight()<fMaxHeight) {
			setDimensions(getHeight()+1, getWidth());
		} else {
			scroll(0,getHeight(),-1);
		}
	}
	public void cleanLine(int line) {
		fData.cleanLine(getPositionOfLine(line));
	}

	public void copy(ITerminalTextData source) {
		int n=source.getHeight();
		setDimensions(source.getHeight(),source.getWidth());
		for (int i = 0; i < n; i++) {
			fData.copyLine(source, i, getPositionOfLine(i));
		}
	}

	public void copyLine(ITerminalTextData source, int sourceLine, int destLine) {
		fData.copyLine(source, sourceLine, getPositionOfLine(destLine));
	}

	public void copyRange(ITerminalTextData source, int sourceStartLine, int destStartLine, int length) {
		assert (destStartLine>=0 && destStartLine+length<=fHeight) || throwRuntimeException();
		for (int i = 0; i < length; i++) {
			fData.copyLine(source, i+sourceStartLine, getPositionOfLine(i+destStartLine));
		}
	}

	public char getChar(int line, int column) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		return fData.getChar(getPositionOfLine(line), column);
	}

	public char[] getChars(int line) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		return fData.getChars(getPositionOfLine(line));
	}

	public int getHeight() {
		return fHeight;
	}

	public LineSegment[] getLineSegments(int line, int startCol, int numberOfCols) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		return fData.getLineSegments(getPositionOfLine(line), startCol, numberOfCols);
	}

	public int getMaxHeight() {
		return fMaxHeight;
	}

	public Style getStyle(int line, int column) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		return fData.getStyle(getPositionOfLine(line), column);
	}

	public Style[] getStyles(int line) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		return fData.getStyles(getPositionOfLine(line));
	}

	public int getWidth() {
		return fData.getWidth();
	}

	public ITerminalTextDataSnapshot makeSnapshot() {
		return fData.makeSnapshot();
	}
	private void cleanLines(int line, int len) {
		for (int i = line; i < line+len; i++) {
			fData.cleanLine(getPositionOfLine(i));
		}
	}
	public void scroll(int startLine, int size, int shift) {
		assert (startLine>=0 && startLine+size<=fHeight) || throwRuntimeException();
		if(shift>=fMaxHeight || -shift>=fMaxHeight) {
			cleanLines(startLine, fMaxHeight-startLine);
			return;
		}
		if(size==fHeight) {
			// This is the case this class is optimized for!
			moveOffset(-shift);
			// we only have to clean the lines that appear by the move 
			if(shift<0) {
				cleanLines(Math.max(startLine, startLine+size+shift),Math.min(-shift, getHeight()-startLine));
			} else {
				cleanLines(startLine, Math.min(shift, getHeight()-startLine));
			}
		} else {
			// we have to copy the lines.
			if(shift<0) {
				// move the region up
				// shift is negative!!
				for (int i = startLine; i < startLine+size+shift; i++) {
					fData.copyLine(fData, getPositionOfLine(i-shift), getPositionOfLine(i));
				}
				// then clean the opened lines
				cleanLines(Math.max(0, startLine+size+shift),Math.min(-shift, getHeight()-startLine));
			} else {
				for (int i = startLine+size-1; i >=startLine && i-shift>=0; i--) {
					fData.copyLine(fData, getPositionOfLine(i-shift), getPositionOfLine(i));
				}
				cleanLines(startLine, Math.min(shift, getHeight()-startLine));
			}
		}
	}

	public void setChar(int line, int column, char c, Style style) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		fData.setChar(getPositionOfLine(line), column, c, style);
	}

	public void setChars(int line, int column, char[] chars, int start, int len, Style style) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		fData.setChars(getPositionOfLine(line), column, chars, start, len, style);
	}

	public void setChars(int line, int column, char[] chars, Style style) {
		assert (line>=0 && line<fHeight) || throwRuntimeException();
		fData.setChars(getPositionOfLine(line), column, chars, style);
	}

	public void setDimensions(int height, int width) {
		assert height>=0 || throwRuntimeException();
		assert width>=0 || throwRuntimeException();
		if(height > fMaxHeight)
			setMaxHeight(height);
		fHeight=height;
		if(width!=fData.getWidth())
			fData.setDimensions(fMaxHeight, width);
	}

	public void setMaxHeight(int maxHeight) {
		assert maxHeight>=fHeight || throwRuntimeException();
		// move everything to offset0
		int start=getPositionOfLine(0);
		if(start!=0) {
			// invent a more efficient algorithm....
			ITerminalTextData buffer=new TerminalTextDataStore();
			// create a buffer with the expected height
			buffer.setDimensions(maxHeight, getWidth());
			int n=Math.min(fMaxHeight-start,maxHeight);
			// copy the first part
			buffer.copyRange(fData, start, 0, n);
			// copy the second part
			if(n<maxHeight)
				buffer.copyRange(fData, 0, n, Math.min(fMaxHeight-n,maxHeight-n));
			// copy the buffer back to our data
			fData.copy(buffer);
			shiftOffset(-start);
		} else {
			fData.setDimensions(maxHeight, fData.getWidth());
		}
		fMaxHeight=maxHeight;
	}
	public int getCursorColumn() {
		throw new UnsupportedOperationException();
	}
	public int getCursorLine() {
		throw new UnsupportedOperationException();
	}
	public void setCursorColumn(int column) {
		throw new UnsupportedOperationException();
	}
	public void setCursorLine(int line) {
		throw new UnsupportedOperationException();
	}

}
