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

import java.util.*;
import paraselene.*;
import paraselene.tag.*;


class SaxContainer {
	private DynamicPage pp;
	private Stack<Tag>	stack = new Stack<Tag>();
	private boolean	dmy_stack = false;
	private Tag	tag = null;
	private Tag	first_tag = null;
	private HTMLPart last_part = null;
	private int	escape = 0;

	SaxContainer( DynamicPage p ) {
		pp = p;
	}

	void addTag( String name, ArrayList<Attribute> attr ) throws Exception {
		HTMLPart.StringMode	mode = Tag.selectMode( name );
		if (mode == HTMLPart.StringMode.TEXTAREA || mode == HTMLPart.StringMode.PLAIN)	escape++;
		add( pp.makeTag( name, attr ) );
	}

	private void add( HTMLPart p ) {
		last_part = p;
		Tag	nt = null;
		if ( p instanceof Tag ) {
			nt = (Tag)p;
			if ( "meta".equals( nt.getName() ) ) {
				Attribute	attr = nt.getAttribute( "http-equiv" );
				if ( attr != null ) {
					if ( "Content-Type".equalsIgnoreCase( attr.getString() ) ) {
						attr = nt.getAttribute( "content" );
						if ( attr != null )	pp.parse_encode = attr.getString();
						nt.setVisible( false );
					}
				}
			}
			else if ( "tbody".equals( nt.getName() ) ) {
				nt.setVisible( false );
			}
			else if ( "tfoot".equals( nt.getName() ) ) {
				nt.setVisible( false );
			}
			else if ( "thead".equals( nt.getName() ) ) {
				nt.setVisible( false );
			}
		}

		if ( tag != null ) {
			tag.addHTMLPart( p );
		}
		if ( nt != null ) {
			tag = nt;
			stack.push( tag );
			if ( first_tag == null ) {
				first_tag = tag;
				pp.setMainTag( tag );
			}
		}
	}

	private void delete( Tag t ) {
		Tag[]	tag = t.getTagArray();
		for ( int i = tag.length - 1; i >= 0; i-- ) {
			if ( !tag[i].isVisible() ) {
				t.exclude( tag[i] );
			}
		}
	}

	void endTag() {
		HTMLPart.StringMode	mode = Tag.selectMode( tag.getName() );
		if (mode == HTMLPart.StringMode.TEXTAREA || mode == HTMLPart.StringMode.PLAIN)	escape--;
		tag.replaceBR();
		delete( tag );
		stack.pop();
		if ( stack.empty() ) {
			tag = null;
		}
		else {
			tag = stack.peek();
		}
	}

	void addText( char[] data, boolean xml_f ) {
		addText( data, 0, data.length, xml_f );
	}

	void addText( char[] data, int start, int length, boolean xml_f ) {
		String	name = tag.getName();
		StringBuilder	buf = new StringBuilder();
		boolean			crlf_f = false;
		length += start;
		for ( int i = start; i < length; i++ ) {
			if ( data[i] == '\u00a0' ) {
				data[i] = ' ';
			}
			else if ( escape == 0 && (data[i] == '\n' || data[i] == '\r' || data[i] == '\t') ) {
				data[i] = ' ';
				if ( data[i] != '\t' )	crlf_f = true;
			}
			if ( escape == 0 && data[i] == ' ' && i > 0 && xml_f ) {
				if ( data[i - 1] == ' ' )	continue;
			}
			if ( data[i] == ' ' && last_part instanceof Tag ) {
				Tag	t = (Tag)last_part;
				if ( !t.isSimpleTag() ) {
					last_part = null;
					continue;
				}
			}
			buf = buf.append( data[i] );
			last_part = null;
		}
/**
		if ( "noframes".equals( name ) ) {
			StringBuilder	sub = new StringBuilder( "<body name='body'>" );
			sub = sub.append( buf );
			sub = sub.append( "</body>" );
			DynamicPage	sub_page = pp.makePage();
			try {
				sub_page.create( sub.toString() );
				Tag	body = sub_page.getTag( "body" );
				int	cnt = body.getHTMLPartCount();
				for ( int i = 0; i < cnt; i++ ) {
					HTMLPart	p = body.getHTMLPart( 0 );
					body.removeHTMLPart( 0 );
					tag.addHTMLPart( p );
				}
			}
			catch( DynamicPageException e ) {
				e.printStackTrace();
			}
		}
**/
//		else {
			String	str = buf.toString();
			if ( crlf_f )	str = str.trim();
			if ( str.isEmpty() )	return;
			add( pp.makeText( str ) );
//		}
	}

}


