/*
 * Paraselene
 * Copyright (c) 2009, 2010  Akira Terasaki
 * このファイルは同梱されているLicense.txtに定めた条件に同意できる場合にのみ
 * 利用可能です。
 */
package paraselene.mockup;


import java.io.*;
import java.util.*;

public abstract class Output {
	enum Status {
		OK,
		SKIP,
	}

	protected abstract String getFileByte();

	static String toHtmlPath( String path ) {
		String[]	parts = path.split( "[/\\\\]" );
		StringBuilder	buf = new StringBuilder( parts[0] );
		for ( int i = 1; i < parts.length; i++ ) {
			buf = buf.append( "/" );
			buf = buf.append( parts[i] );
		}
		return buf.toString();
	}

	static String toOSPath( String path ) {
		String[]	parts = path.split( "[/\\\\]" );
		StringBuilder	buf = new StringBuilder();
		for ( int i = 0; i < parts.length; i++ ) {
			buf = buf.append( File.separator );
			buf = buf.append( parts[i] );
		}
		return buf.toString();
	}

	public static void mkdir( String dir ) {
		if ( dir == null )	return;
		if ( new File( dir ).exists() )	return;
		String[]	path = dir.split( "[/\\\\]+" );
		StringBuilder	buf = new StringBuilder();
		for ( int i = 0; i < path.length; i++ ) {
			buf = buf.append( path[i] );
			buf = buf.append( File.separator );
			new File( buf.toString() ).mkdir();
		}
	}

	static void rmdir( String dir ) {
		File	file = new File( dir );
		if ( !file.exists() )	return;
		if ( file.isDirectory() ) {
			if ( Param.isNoClear( file.getName() ) )	return;
			File[]	list = file.listFiles();
			for ( int i = 0; i < list.length; i++ ) {
				rmdir( list[i].getPath() );
			}
		}
		boolean	ret = file.delete();
		Linker.readme.echo( dir );
		if ( ret )	Linker.readme.echoln( " was deleted." );
		else	Linker.readme.echoln( " was not deleted." );
	}

	private static String scanLine( String str ) {
		char[]	ch = str.toCharArray();
		StringBuilder	buf = new StringBuilder();
		for ( int i = 0; i < ch.length; i++ ) {
			if ( ch[i] == '\n' || ch[i] == '\r' ) {
				if ( i > 0 ) {
					if ( ch[i - 1] == '\n' || ch[i - 1] == '\r' ) {
						if ( ch[i] != ch[i - 1] )	continue;
					}
				}
				buf.append( LineSeparator.getUse() );
				continue;
			}
			buf.append( ch[i] );
		}
		return buf.toString();
	}

	private static String stripLine( String str ) {
		char[]	ch = str.toCharArray();
		StringBuilder	buf = new StringBuilder();
		for ( int i = 0; i < ch.length; i++ ) {
/*
			if ( ch[i] == '\n' || ch[i] == '\r' ) {
				continue;
			}
*/
			buf.append( ch[i] );
		}
		return buf.toString();
	}

	public String toString() {
		return stripLine( getFileByte() );
	}

	public InputStream getInputStream( String chset ) throws UnsupportedEncodingException {
		return new ByteArrayInputStream( toString().getBytes( chset ) );
	}

	public Status write( File file, OutputNo out_no, long org_tm ) throws Exception {
		if ( org_tm > 0  && file.exists() ) {
			if ( file.lastModified() > org_tm )	return Status.SKIP;
		}
		mkdir( file.getParent() );
		char[]	str = scanLine( getFileByte() ).toCharArray();
		BufferedWriter	bw = null;
		Exception	ex = null;
		try {
			bw = new BufferedWriter(
				new OutputStreamWriter(
				new FileOutputStream( file ), Param.SOURCE_ENCODE.get() ) );
			bw.write( SourceHead.getHead( file ) );
			for ( int i = 0; i < str.length; i++ ) {
				if ( str[i] == '#' ) {
					i++;
					if ( str[i] != '#' ) {
						bw.write( scanLine( out_no.getString( Integer.parseInt( new String( str, i, 1 ), Character.MAX_RADIX ) ) ) );
						continue;
					}
				}
				bw.write( str[i] );
			}
		}
		catch( Exception e ) {
			ex = e;
		}
		if ( bw != null ) {
			try {
				bw.close();
			}
			catch( Exception e ) {}
		}
		if ( ex != null )	throw ex;
		return Status.OK;
	}
}

