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

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


/**
 * スタイルシート要素定義。
 */
class CSSParser {
	private static final char	NULL = '\u0000';
	private CSSParser(){}

	private static char safe( char[] ch, int offset ) {
		if ( ch.length - 1 < offset )	return NULL;
		if ( offset < 0 )	return NULL;
		return ch[offset];
	}

	static String[]	split( String str, char ... deli ) {
		if ( str == null )	return null;
		ArrayList<String>	ret = new ArrayList<String>();
		char[]	ch = str.toCharArray();
		StringBuilder	buf = new StringBuilder();
		boolean	comment_f = false;
		char	start = NULL;
		for ( int i = 0; i < ch.length; i++ ) {
			if ( comment_f ) {
				if ( ch[i] == '*' && safe( ch, i + 1 ) == '/' ) {
					i++;
					comment_f = false;
					continue;
				}
			}
			if ( ch[i] == '\\' ) {
				char[]	crlf = new char[]{	safe( ch, i + 1 ), safe( ch, i + 2 ) };
				if ( (crlf[0] == '\r' && crlf[1] == '\n') || (crlf[0] == '\n' && crlf[1] == '\r') ) {
					i += 2;
					continue;
				}
				if ( crlf[0] == '\r' || crlf[0] == '\n' || crlf[0] == '\f' ) {
					i++;
					continue;
				}
				buf = buf.append( ch[i] );
				i++;
				if ( i < ch.length )	buf = buf.append( ch[i] );
				continue;
			}
			if ( start != NULL ) {
				if ( ch[i] == start ) {
					start = NULL;
				}
				buf = buf.append( ch[i] );
				continue;
			}
			if ( ch[i] == '\'' || ch[i] == '"' ) {
				start = ch[i];
				buf = buf.append( ch[i] );
				continue;
			}
			boolean	split_f = false;
			for ( int j = 0; j < deli.length; j++ ) {
				if ( ch[i] == deli[j] ) {
					split_f = true;
					break;
				}
			}
			if ( split_f ) {
				String	hit = buf.toString();
				if ( !hit.isEmpty() )	ret.add( hit );
				buf = new StringBuilder();
				continue;
			}
			if ( ch[i] == '<' && safe( ch, i + 1 ) == '!' && safe( ch, i + 2 ) == '-' && safe( ch, i + 3 ) == '-' ) {
				i += 3;
				continue;
			}
			if ( ch[i] == '-' && safe( ch, i + 1 ) == '-' && safe( ch, i + 2 ) == '>' ) {
				i += 2;
				continue;
			}
			if ( ch[i] == '/' && safe( ch, i + 1 ) == '*' ) {
				i++;
				comment_f = true;
				continue;
			}
			buf = buf.append( ch[i] );
		}
		String	last = buf.toString();
		if ( !last.isEmpty() )	ret.add( last );
		return ret.toArray( new String[0] );
	}

	static String escape( String s ) {
		char[]	ch = s.toCharArray();
		StringBuilder	buf = new StringBuilder();
		for ( int i = 0; i < ch.length; i++ ) {
			if ( ch[i] < '0' || (ch[i] > '9' && ch[i] < 'A') || (ch[i] > 'Z' && ch[i] < 'a') || ch[i] > 'z' ) {
				if ( ch[i] != '\\' ) {
					buf = buf.append( '\\' );
				}
			}
			buf = buf.append( ch[i] );
		}
		return buf.toString();
	}
}

