package org.paneris.spindent;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Run
{
	static final String allOptionsArr[]= {
		"-keepComments", "-servlet", "-VBScript", "-noVBScript",
		"-xml", "-htmlUpperCase", "-htmlLowerCase", "-unindParenth",
		"-indCaseKeyword", "-indCode", "-mixCodeOpener", "-t", "-1", "-2", "-3", "-4"};
	static final String allDescArr[]= {
		"preserve multiple spaces in comments",
		"source is Java [servlet] or VBScript program rather than JSP/ASP",
		"recognize VBScript; misindents JSP/PHP/Javascript",
		"don't recognize VBScript (as in Javascript ASP)",
		"indent XML and XHTML, don't transform tags to uppercase",
		"transform tags to uppercase",
		"transform tags to lowercase",
		"don't indent code within parenthesis",
		"indent \"case\" keyword along with other code",
		"indent code within <% %> and <? ?> at one deeper level",
		"don't align <% and <? to the left",
		"indent with tabs, default 1 character; forces -mixCodeOpener",
		"indent with 1 whitespace character",
		"indent with 2 whitespace characters - default",
		"indent with 3",
		"indent with 4"
	};

	static void printHelp() {
		System.err.println( "Run:            java org.paneris.SPindent.Run [options] inFile [outFile]");
		System.err.println( "                dashes '-' can be used for standard input/output");
		System.err.println( "If only one file specified, it's overwritten. Options are case insensitive:");
		int longestOption=0;
		for(int i=0; i<allOptionsArr.length; i++)
			longestOption= Math.max(longestOption,allOptionsArr[i].length());
		for(int i=0; i<allOptionsArr.length; i++)
			System.err.println( allOptionsArr[i]+ Indent.spaces(longestOption-allOptionsArr[i].length()+1) +allDescArr[i]);
		Indent.reInit();
	}

  public static void main(String args[])
  {
		System.err.println( "SPindent        [Server] Page indent" );
		System.err.println( "                JSP, PHP, ASP VBScript; HTML, Javascript; XML, SSI");
		System.err.println( "Ver 1.01        http://paneris.org/~peterk/SPindent/" );

		int longestOption=0;
		String allOptionsLw[]= new String[allOptionsArr.length];
		for(int i=0; i<allOptionsArr.length; i++)
			allOptionsLw[i]= allOptionsArr[i].toLowerCase();
		List allOptions= Arrays.asList(allOptionsLw);

		ArrayList options= new ArrayList(), filenames= new ArrayList();
		for(int i=0; i<args.length; i++) {
			String arg= args[i];
			if( arg.charAt(0)=='-' && arg.length()>1)
				options.add( arg.toLowerCase());
			else
				filenames.add( arg);
		}

		if( filenames.size()>2) {
			System.err.println( "Too much filenames or option(s) without dashes.");
			printHelp();
			return;
		}
		if( filenames.size()<1) {
			System.err.println( "One or 2 file parameters or dashes '-' required.");
			printHelp();
			return;
		}
		if( filenames.size()==1)
			filenames.add( filenames.get(0));

		boolean isASPfile=false, isXMLfile=false, isServletFile=false;
		try {
			InputStream inStream;
			String inName= (String)filenames.get(0);
			if( !inName.equals("-")) {
				inStream= new java.io.FileInputStream( inName);
				String lowerName= inName.toLowerCase();
				if( lowerName.endsWith(".asp"))
					isASPfile=true;
				else if( lowerName.endsWith(".xml"))
					isXMLfile=true;
				else if( lowerName.endsWith(".java"))
					isServletFile=true;
			}
			else inStream= System.in;

			if( options.contains(allOptions.get(1))) //-servlet option
				isServletFile=true;

			String translation;
			synchronized(Engine.synchro) {
				synchronized(Indent.synchro) {
					Indent.reInit();
					Engine.reInit();
					if(isASPfile)
						Engine.VBScript=true;
					else if(isXMLfile)
						Engine.XMLindent=true;

					Parser parser;
					if( !isServletFile)
						parser= new Parser(inStream);
					else
						parser= new Parser( new ParserTokenManager( new SimpleCharStream(inStream,1,1), ParserConstants.CODE));

					boolean setIndentWidth=false;
					for(int i=0; i<options.size(); i++) {
						int indexInAll= allOptions.indexOf( options.get(i));
						switch(indexInAll) {
							case  0: Engine.shortenCommentSpaces=false; break;
							case 	1: break; //-servlet option
							case  2: Engine.VBScript=true; break;
							case  3: Engine.VBScript=false; break;
							case  4: Engine.XMLindent=true; //no break
							case  5: Engine.tagsToUppercase=true; Engine.tagsToLowercase=false; break;
							case  6: Engine.tagsToUppercase=false; Engine.tagsToLowercase=true; break;
							case  7: Engine.parenthIndent=false; break;
							case  8: Engine.unindentCase=false; break;
							case  9: Engine.codeIndent=true; Engine.unindentOpenCode=false; break;
							case 10: Engine.unindentOpenCode=false; break;
							case 11: Indent.indentChar='\t'; Engine.unindentOpenCode=false; if(!setIndentWidth) Indent.indent=1; break;
							case 12: Indent.indent=1; setIndentWidth=true; break;
							case 13: Indent.indent=2; setIndentWidth=true; break;
							case 14: Indent.indent=3; setIndentWidth=true; break;
							case 15: Indent.indent=4; setIndentWidth=true; break;
							default: System.err.println("Ignored unknown option " +options.get(i)); break;
						}
					}
					parser.disable_tracing();
					translation= parser.File();
				}
			}
			inStream.close();
		
			java.io.OutputStream  outStream;
			String outName= (String)filenames.get(1);
			if( !outName.equals("-"))
				outStream= new java.io.FileOutputStream( outName);
			else outStream= System.out;
			outStream.write( translation.getBytes() );
			outStream.close();
		}
		catch(Exception e) { System.err.println(e); }
  }
}