import java.util.*;
////////////////////////////////////////////////////////////////
//継承元のXMLタグのクラス　木構造の葉にあたる要素
//空要素タグ：中身の要素を持たず<name x="0" y="0" .... />の形
//タグ名はコンストラクタで指定する　変更は不可
//プロパティーは文字列として自由に設定可能（検査なし）
public class XML_Tag implements Text
{
	String name=null;
	
	//タグのプロパティーを管理する種のメンバ
	Properties properties=new Properties();
	public void setProperty(String key,String value)
	{
		properties.setProperty(key,value);
	}
	//プロパティーを1行の文字列に変換する
	protected String getProperties()
	{
		StringBuffer buffer=new StringBuffer();
		Enumeration enume=properties.propertyNames();
		while(enume.hasMoreElements()){
			String key=(String)(enume.nextElement());
			buffer.append(key+"=\""+properties.getProperty(key)+"\" ");
		}
		return buffer.toString();
	}
	
	//コンストラクタ　引数を持つコンストラクタしかないので継承では注意
	public XML_Tag(String name)
	{
		this.name=name;
	}
	public String getName()	
	{
		return name;
	}
	public String getText()
	{
		return getText("");
	}
	public String getText(String indent)
	{
		StringBuffer buffer=new StringBuffer();
		buffer.append(indent+"<"+getName()+" "+getProperties()+" />");
		return buffer.toString();
	}
	//読み取りは未実装
	public boolean setText(String str)
	{
		return false;
	}
}
////////////////////////////////////////////////////////////////
//継承例1
class SVG_Rect extends XML_Tag//矩形要素クラス
{	
	public SVG_Rect(int x,int y,int width,int height,String fill)
	{
		super("rect");//継承親のコンストラクタ呼び出し
		setProperty("x",""+x);//文字列の足し算では整数型の値などが自動的に文字列に変換されることを利用
		setProperty("y",""+y);
		setProperty("width",""+width);
		setProperty("height",""+height);
		if(fill!=null) setProperty("fill",fill);//塗りつぶしの色はプロパティーに
	}
}
////////////////////////////////////////////////////////////////
//継承例2
//コメントは例外的な形をしたタグ
//プロパティーは無いが　コメント文がある
//<!--コメント-->の形
class CommentTag extends XML_Tag
{
	String comment=null;
	//コメントの文字列で初期化ただし「--」を含んではいけない
	public CommentTag(String comment)
	{
		super(null);
		this.comment= comment;
	}
	public String getText(String indent)
	{
		return indent+"<!--"+comment+"-->";
	}
}

////////////////////////////////////////////////////////////
//継承例3　空要素タグを継承して中身を持つタグを作る
//中身の要素を持つタグ　木構造の枝にあたる要素
//開始タグと終了タグで中身の要素を挟む形式になる
//<name x="0" y="0" .... >
//    <name1 ..../>
//    <name2 ..../>
//</name>
//の形
//空要素タグを継承し中身のリストを持てるようにした
//テキスト形式への変換で字下げされたテキストにするため一工夫

class ContainerTag extends XML_Tag
{
	//開始タグと終了タグの間にある中身の要素タグの管理用
	Vector<XML_Tag> tags=new Vector<XML_Tag>();//中身のタグリスト
	//中身の要素の追加と削除
	public void add(XML_Tag t)
	{
		tags.add(t);
	}
	public void remove(XML_Tag t)
	{
		tags.remove(t);
	}
	//中身の要素のテキスト化を行う
	//字下げを行うため、各行の先頭にindentの文字列が挿入される
	protected String getElements(String indent)
	{
		StringBuffer buffer=new StringBuffer();
		for(XML_Tag t:tags){
			//文字下げ追加
			buffer.append(t.getText(indent));
			buffer.append("\n");
		}
		return buffer.toString();
	}
	//コンストラクタ
	public ContainerTag(String name)
	{
		super(name);
	}
	//プロパティーを含む開始タグ、中身のタグ、終了タグを複数行の字下げされた文字列に変換する
	public String getText(String indent)
	{
		StringBuffer buffer=new StringBuffer();
		buffer.append(indent+"<"+getName()+" "+getProperties()+" >\n");//開始タグ
		buffer.append(getElements(indent+"    "));//中身のTagを書き加える
		buffer.append(indent+"</"+getName()+">");//終了タグ
		return buffer.toString();
	}
}
///////////////////////////////////////////////////////
//継承例4　
//SVGのルート要素
class SVG_Root extends ContainerTag//SVGのルート要素クラス
{
	static final String XMLNS="http://www.w3.org/2000/svg";
	public SVG_Root(int x,int y,int width,int height)
	{
		super("svg");//継承親のコンストラクタ呼び出し
		//
		setProperty("widthl",""+width);
		setProperty("height",""+height);
		setProperty("viewBox",""+x+" "+y+" "+width+" "+height);
		setProperty("xmlns",XMLNS);
	}
}
