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


import java.net.*;
import java.util.*;

import paraselene.*;
import paraselene.tag.*;


class TagSource extends Tag implements Source {
	private static long seq = 0;
	private String val_name;

	String getTagString() {
		return new Text( getFirstTag() ).toString( HTMLPart.StringMode.BODY );
	}

	TagSource( String n, boolean single_f ) {
		super( n, single_f );
		val_name = "tag" + Long.toString( seq );
		seq++;
		if ( seq < 0 )	seq = 0;
	}

	public String getValName() {
		return val_name;
	}

	private String getAttributeSource( Attribute a ) throws TagException {
		String	name = a.getName();
		String	val = a.getString();

		if ( "name".equals( name ) && val != null ) {
			val = Page.getIndexName( val );
		}

		StringBuilder	buf = new StringBuilder( "new Attribute(" );
		buf = buf.append( Make.escape( name ) );
		buf = buf.append( "," );
		if ( Converter.isColor( name ) ) {
			try {
				if ( val != null ) {
					val = new Color( val ).toString();
				}
			}
			catch(Exception e){
				throw new TagException( "色の指定が不正です" );
			}
			buf = buf.append( "new Color(" );
			buf = buf.append( Make.escape( val ) );
			buf = buf.append( "))" );
			return buf.toString();
		}

		else if ( Converter.isNumber( name ) ) {
			try {
				new NumberValue( val );
			}
			catch(Exception e){
				throw new TagException( "値の指定が不正です" );
			}
			buf = buf.append( "new NumberValue(" );
			buf = buf.append( Make.escape( val ) );
			buf = buf.append( "))" );
			return buf.toString();
		}
		else if ( Converter.isMultiNumber( name ) ) {
			String[]	p = val.split( "," );
			for ( int i = 0; i < p.length; i++ ) {
				try {
					new NumberValue( p[i] );
				}
				catch(Exception e){
					throw new TagException( "値の指定が不正です" );
				}
				if ( i > 0 )	buf = buf.append( "," );
				buf = buf.append( "new NumberValue(" );
				buf = buf.append( Make.escape( p[i] ) );
				buf = buf.append( ")" );
			}
			buf = buf.append( ")" );
			return buf.toString();
		}

		else if ( Converter.isStyle( name ) ) {
			buf = buf.append( "new Style(Property.create(" );
			buf = buf.append( Make.escape( val ) );
			buf = buf.append( "," );
			buf = buf.append( Make.escape( ((PrePage)getAssignedTag().getAssignedPage()).getParsingCharset() ) );
			buf = buf.append( ")))" );
			return buf.toString();
		}

		boolean	uri_f = Converter.isURI( name );
		if ( !uri_f ) {
			if ( "param".equals( getName() ) ) {
				if ( "value".equalsIgnoreCase( name ) ) {
					Attribute	name_atr = getAttribute( "name" );
					if ( name_atr != null ) {
						String	name_str = name_atr.getString();
						if ( name_str != null ) {
							int	cnt = Param.PARAM_URI.getDataCount();
							for ( int i = 0; i < cnt; i++ ) {
								String	p_name = Param.PARAM_URI.getData( i );
								if ( p_name.equalsIgnoreCase( name_str ) ) {
									uri_f = true;
									break;
								}
							}
						}
					}
				}
			}
		}

		if ( uri_f ) {
			try {
				URI	uri = new URI( val );
				val = Linker.readme.resolvePath( uri );
			}
			catch(Exception e){
				throw new TagException( "URI[" + val + "]の指定が不正です" );
			}
			buf = buf.append( "new URIValue(" );
			buf = buf.append( val );
			buf = buf.append( "))" );
			return buf.toString();
		}

		buf = buf.append( "new Text(");
		buf = buf.append( Make.escape( val ) );
		buf = buf.append( "))" );
		return buf.toString();
	}

	private static String append( String ... s ) {
		StringBuilder	buf = new StringBuilder();
		for ( int i = 0; i < s.length; i++ ) {
			buf = buf.append( s[i] );
		}
		return buf.toString();
	}

	private static boolean orEquals( String s1, String ... s2 ) {
		for ( int i = 0; i < s2.length; i++ ) {
			if ( s1.equals( s2[i] ) )	return true;
		}
		return false;
	}

	private Attribute[]	eraseAttribute( Attribute[] a ) {
		ArrayList<Attribute>	ret = new ArrayList<Attribute>();
		for ( int i = 0; i < a.length; i++ ) {
			String	name = a[i].getName(), val = a[i].getString();
			if ( val != null && "id".equals( name ) ) {
				if ( val.indexOf( "paraselene$id$" ) >= 0 )	continue;
			}
			ret.add( a[i] );
		}
		return ret.toArray( new Attribute[0] );
	}

	public String toSource() {
		StringBuilder	buf = null;
		try {
			String[]	name = TagMap.getSource( this );
			buf = new StringBuilder( name[0] );
			buf = buf.append( " " );
			buf = buf.append( val_name );
			buf = buf.append( "=" );
			buf = buf.append( name[1] );
			buf = buf.append( ";\n" );
			Attribute[]	attr = eraseAttribute( getAllAttribute() );
			if ( attr.length > 0 ) {
				buf = buf.append( val_name );
				buf = buf.append( ".setAttribute(" );
				for ( int i = 0; i < attr.length; i++ ) {
					if ( i > 0 ) {
						buf = buf.append( "," );
					}
					buf = buf.append( getAttributeSource( attr[i] ) );
				}
				buf = buf.append( ");\n" );
			}
			int	cnt = getHTMLPartCount();
			for ( int i = 0; i < cnt; i++ ) {
				Source	src = (Source)getHTMLPart( i );
				buf = buf.append( src.toSource() );
				buf = buf.append( val_name );
				buf = buf.append( ".addHTMLPart(" );
				buf = buf.append( src.getValName() );
				buf = buf.append( ");\n" );
			}
		}
		catch(TagException e) {
			System.err.println( e.getMessage() );
			System.err.println( toString() );
			System.exit( 1 );
		}
		return buf.toString();
	}

	protected Text makeText( String str ) {
		return new TextSource( str );
	}
}

