/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.formatter.align;

import org.eclipse.jdt.internal.formatter.Location;
import org.eclipse.jdt.internal.formatter.Scribe;

/**
 * Alignment management
 * 
 * @since 2.1
 */
public class Alignment {

	// name of alignment
	public String name;
	
	// link to enclosing alignment
	public Alignment enclosing;
	 
	// start location of this alignment
	public Location location;
	
	// indentation management
	public int fragmentIndex;
	public int fragmentCount;
	public int[] fragmentIndentations;
	public boolean needRedoColumnAlignment;

	// chunk management
	public int chunkStartIndex;
	public int chunkKind;

	// break management	
	public int originalIndentationLevel;
	public int breakIndentationLevel;
	public int shiftBreakIndentationLevel;
	public int[] fragmentBreaks;
	public boolean wasSplit;

	public Scribe scribe;
	
	/* 
	 * Alignment modes
	 */
	public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional)
	public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
	public static final int	M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation)

	// split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN
	
	/** foobar(#fragment1, #fragment2, <ul>
	 *  <li>    #fragment3, #fragment4 </li>
	 * </ul>
	 */
	public static final int M_COMPACT_SPLIT = 16; // fill each line with all possible fragments

	/** foobar(<ul>
	 * <li>    #fragment1, #fragment2,  </li>
	 * <li>     #fragment5, #fragment4, </li>
	 * </ul>
	 */
	public static final int M_COMPACT_FIRST_BREAK_SPLIT = 32; //  compact mode, but will first try to break before first fragment

	/** foobar(<ul>
	 * <li>     #fragment1,  </li>
	 * <li>     #fragment2,  </li>
	 * <li>     #fragment3 </li>
	 * <li>     #fragment4,  </li>
	 * </ul>
	 */
	public static final int M_ONE_PER_LINE_SPLIT = 32+16; // one fragment per line

	/** 
	 * foobar(<ul>
	 * <li>     #fragment1,  </li>
	 * <li>        #fragment2,  </li>
	 * <li>        #fragment3 </li>
	 * <li>        #fragment4,  </li>
	 * </ul>
	 */ 
	public static final int M_NEXT_SHIFTED_SPLIT = 64; // one fragment per line, subsequent are indented further

	/** foobar(#fragment1, <ul>
	 * <li>      #fragment2,  </li>
	 * <li>      #fragment3 </li>
	 * <li>      #fragment4,  </li>
	 * </ul>
	 */
	public static final int M_NEXT_PER_LINE_SPLIT = 64+16; // one per line, except first fragment (if possible)

	//64+32
	//64+32+16
	
	// mode controlling column alignments
	/** 
	 * <table BORDER COLS=4 WIDTH="100%" >
	 * <tr><td>#fragment1A</td>            <td>#fragment2A</td>       <td>#fragment3A</td>  <td>#very-long-fragment4A</td></tr>
	 * <tr><td>#fragment1B</td>            <td>#long-fragment2B</td>  <td>#fragment3B</td>  <td>#fragment4B</td></tr>
	 * <tr><td>#very-long-fragment1C</td>  <td>#fragment2C</td>       <td>#fragment3C</td>  <td>#fragment4C</td></tr>
	 * </table>
	 */
	public static final int M_MULTICOLUMN = 256; // fragments are on same line, but multiple line of fragments will be aligned vertically
	
	public static final int M_NO_ALIGNMENT = 0;
	
	public int mode;
	
	public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT | M_NEXT_SHIFTED_SPLIT | M_COMPACT_SPLIT | M_COMPACT_FIRST_BREAK_SPLIT | M_NEXT_PER_LINE_SPLIT;

	// alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen
	public static final int R_OUTERMOST = 1;
	public static final int R_INNERMOST = 2;
	public int tieBreakRule;
	
	// alignment effects on a per fragment basis
	public static int NONE = 0;
	public static int BREAK = 1;
	
	// chunk kind
	public static final int CHUNK_FIELD = 1;
	public static final int CHUNK_METHOD = 2;
	public static final int CHUNK_TYPE = 3;
	public static final int CHUNK_ENUM = 4;

	// location to align and break on.
	public Alignment(String name, int mode, int tieBreakRule, Scribe scribe, int fragmentCount, int sourceRestart, int continuationIndent){
		
		this.name = name;
		this.location = new Location(scribe, sourceRestart);
		this.mode = mode;
		this.tieBreakRule = tieBreakRule;
		this.fragmentCount = fragmentCount;
		this.scribe = scribe;
		this.originalIndentationLevel = this.scribe.indentationLevel;
		this.wasSplit = false;
		
		// initialize the break indentation level, using modes and continuationIndentationLevel preference
		final int indentSize = this.scribe.indentationSize;
		int currentColumn = this.location.outputColumn;
		if (currentColumn == 1) {
		    currentColumn = this.location.outputIndentationLevel + 1;
		}
		
		if ((mode & M_INDENT_ON_COLUMN) != 0) {
			// indent broken fragments at next indentation level, based on current column
			this.breakIndentationLevel = this.scribe.getNextIndentationLevel(currentColumn);
			if (this.breakIndentationLevel == this.location.outputIndentationLevel) {
				this.breakIndentationLevel += (continuationIndent * indentSize);
			}
		} else if ((mode & M_INDENT_BY_ONE) != 0) {
			// indent broken fragments exactly one level deeper than current indentation
			this.breakIndentationLevel = this.location.outputIndentationLevel + indentSize;
		} else {
			this.breakIndentationLevel = this.location.outputIndentationLevel + continuationIndent * indentSize;
		}
		this.shiftBreakIndentationLevel = this.breakIndentationLevel + indentSize;

		this.fragmentIndentations = new int[this.fragmentCount];
		this.fragmentBreaks = new int[this.fragmentCount];

		// check for forced alignments
		if ((this.mode & M_FORCE) != 0) {
			couldBreak();
		}					
	}
	
	public boolean checkChunkStart(int kind, int startIndex, int sourceRestart) {
		if (this.chunkKind != kind) {
			this.chunkKind = kind;
			
			// when redoing same chunk alignment, must not reset
			if (startIndex != this.chunkStartIndex) {
				this.chunkStartIndex = startIndex;
				this.location.update(this.scribe, sourceRestart);
				reset();
			}
			return true;
		}
		return false;
	}

	public void checkColumn() {
		if ((this.mode & M_MULTICOLUMN) != 0) {
			int currentIndentation = this.scribe.getNextIndentationLevel(this.scribe.column+(this.scribe.needSpace ? 1 : 0));
			int fragmentIndentation = this.fragmentIndentations[this.fragmentIndex];
			if (currentIndentation > fragmentIndentation) {
				this.fragmentIndentations[this.fragmentIndex] =  currentIndentation;
				if (fragmentIndentation != 0) {
					for (int i = this.fragmentIndex+1; i < this.fragmentCount; i++) {
						this.fragmentIndentations[i] = 0;
					}
					this.needRedoColumnAlignment = true;
				}
			}
			// backtrack only once all fragments got checked
			if (this.needRedoColumnAlignment && this.fragmentIndex == this.fragmentCount-1) { // alignment too small

//				if (CodeFormatterVisitor.DEBUG){
//					System.out.println("ALIGNMENT TOO SMALL");
//					System.out.println(this);
//				}
				this.needRedoColumnAlignment = false;
				int relativeDepth = 0;
				Alignment targetAlignment = this.scribe.memberAlignment;
				while (targetAlignment != null){
					if (targetAlignment == this){
						throw new AlignmentException(AlignmentException.ALIGN_TOO_SMALL, relativeDepth);
					}
					targetAlignment = targetAlignment.enclosing;
					relativeDepth++;
				}
			}
		}
	}
		
	public boolean couldBreak(){
		int i;
		switch(mode & SPLIT_MASK){

			/*  # aligned fragment
			 *  foo(
			 *     #AAAAA, #BBBBB,
			 *     #CCCC);
			 */
			case M_COMPACT_FIRST_BREAK_SPLIT : 
				if (this.fragmentBreaks[0] == NONE) {
					this.fragmentBreaks[0] = BREAK;
					this.fragmentIndentations[0] = this.breakIndentationLevel;
					return wasSplit = true;
				}
				i = this.fragmentIndex;
				do {
					if (this.fragmentBreaks[i] == NONE) {
						this.fragmentBreaks[i] = BREAK;
						this.fragmentIndentations[i] = this.breakIndentationLevel;
						return wasSplit = true;
					}
				} while (--i >= 0);
				break;
			/*  # aligned fragment
			 *  foo(#AAAAA, #BBBBB,
			 *     #CCCC);
			 */
			case M_COMPACT_SPLIT : 
				i = this.fragmentIndex;
				do {
					if (this.fragmentBreaks[i] == NONE) {
						this.fragmentBreaks[i] = BREAK;
						this.fragmentIndentations[i] = this.breakIndentationLevel;						
						return wasSplit = true;
					}
				} while (--i >= 0);
				break;

			/*  # aligned fragment
			 *  foo(
			 *      #AAAAA,
			 *          #BBBBB,
			 *          #CCCC);
			 */
			case M_NEXT_SHIFTED_SPLIT :
				if (this.fragmentBreaks[0] == NONE) {
					this.fragmentBreaks[0] = BREAK;					
					this.fragmentIndentations[0] = this.breakIndentationLevel;
					for (i = 1; i < this.fragmentCount; i++){
						this.fragmentBreaks[i] = BREAK;
						this.fragmentIndentations[i] = this.shiftBreakIndentationLevel;
					}
					return wasSplit = true;
				}
				break;
				
			/*  # aligned fragment
			 *  foo(
			 *      #AAAAA,
			 *      #BBBBB,
			 *      #CCCC);
			 */
			case M_ONE_PER_LINE_SPLIT :
				if (this.fragmentBreaks[0] == NONE) {
					for (i = 0; i < this.fragmentCount; i++){
						this.fragmentBreaks[i] = BREAK;
						this.fragmentIndentations[i] = this.breakIndentationLevel;
					}
					return wasSplit = true;
				}
			/*  # aligned fragment
			 *  foo(#AAAAA,
			 *      #BBBBB,
			 *      #CCCC);
			 */
			case M_NEXT_PER_LINE_SPLIT : 
				if (this.fragmentBreaks[0] == NONE) {
					if (this.fragmentCount > 1
							&& this.fragmentBreaks[1] == NONE) {
						if ((this.mode & M_INDENT_ON_COLUMN) != 0) {
							this.fragmentIndentations[0] = this.breakIndentationLevel;
						}
						for (i = 1; i < this.fragmentCount; i++) {
							this.fragmentBreaks[i] = BREAK;
							this.fragmentIndentations[i] = this.breakIndentationLevel;
						}
						return wasSplit = true;
					}
				}
				break;
		}		
		return false; // cannot split better
	}
	
	public Alignment getAlignment(String targetName) {

		if (targetName.equals(this.name)) return this;
		if (this.enclosing == null) return null;
		
		return this.enclosing.getAlignment(targetName);
	}
		
	// perform alignment effect for current fragment
	public void performFragmentEffect(){
		if ((this.mode & M_MULTICOLUMN) == 0) {
			switch(this.mode & SPLIT_MASK) {
				case Alignment.M_COMPACT_SPLIT :
				case Alignment.M_COMPACT_FIRST_BREAK_SPLIT :
				case Alignment.M_NEXT_PER_LINE_SPLIT :
				case Alignment.M_NEXT_SHIFTED_SPLIT :
				case Alignment.M_ONE_PER_LINE_SPLIT :
					break;
				default:
					return;
			}
		}
		
		if (this.fragmentBreaks[this.fragmentIndex] == BREAK) {
			this.scribe.printNewLine();
		}
		if (this.fragmentIndentations[this.fragmentIndex] > 0) {
			this.scribe.indentationLevel = this.fragmentIndentations[this.fragmentIndex];
		}
	}					

	// reset fragment indentation/break status	
	public void reset() {

		if (fragmentCount > 0){
			this.fragmentIndentations = new int[this.fragmentCount];
			this.fragmentBreaks = new int[this.fragmentCount];
		}

		// check for forced alignments
		if ((mode & M_FORCE) != 0) {
			couldBreak();
		}		
	}		

	public void toFragmentsString(StringBuffer buffer){
		// default implementation
	}
	
	public String toString() {
		StringBuffer buffer = new StringBuffer(10);
		buffer
			.append(getClass().getName())
			.append(':')
			.append("<name: ")	//$NON-NLS-1$
			.append(this.name)
			.append(">");	//$NON-NLS-1$
		if (this.enclosing != null) {
			buffer
				.append("<enclosingName: ")	//$NON-NLS-1$
				.append(this.enclosing.name)
				.append('>');
		}
		buffer.append('\n');	

		for (int i = 0; i < this.fragmentCount; i++){
			buffer
				.append(" - fragment ")	//$NON-NLS-1$
				.append(i)
				.append(": ")	//$NON-NLS-1$
				.append("<break: ")	//$NON-NLS-1$
				.append(this.fragmentBreaks[i] > 0 ? "YES" : "NO")	//$NON-NLS-1$	//$NON-NLS-2$
				.append(">")	//$NON-NLS-1$
				.append("<indent: ")	//$NON-NLS-1$
				.append(this.fragmentIndentations[i])
				.append(">\n");	//$NON-NLS-1$
		}
		buffer.append('\n');	
		return buffer.toString();
	}
	
	public void update() {
		for (int i = 1; i < this.fragmentCount; i++){
		    if (this.fragmentBreaks[i] == BREAK) {
		        this.fragmentIndentations[i] = this.breakIndentationLevel;
		    }
		}
	}
}
