/*****************************************************************************
 * Copyright (C) The Apache Software Foundation. All rights reserved.        *
 * ------------------------------------------------------------------------- *
 * This software is published under the terms of the Apache Software License *
 * version 1.1, a copy of which has been included  with this distribution in *
 * the LICENSE file.                                                         *
 *****************************************************************************/
 
package org.apache.slide.util.conf;

import java.util.*;

import org.apache.slide.common.Domain;
import org.apache.slide.util.Configuration;

/**
 */
public class Element {

    private String name;
    private Hashtable attributes;
    private Vector children;
    private String data;
    private String comment;
    private Element parent;
    
    public Element getParent() {
        return parent;
    }
    
    public String getName() {
        return name;
    }

    public void setName(String s) {
        name = s;
    }

    public boolean hasAttributes() {
        return !attributes.isEmpty();
    }

    public Enumeration getAttributeNames() {
        return attributes.keys();
    }

    public String getAttributeValue(String s) {
        String value = (String) attributes.get(s);
        
        if (value != null) {
            return substituteVariables(value);
        }
        return value;
    }

    public void setAttribute(String s, String s1) {
        attributes.put(s, s1);
    }

    public void removeAttribute(String s) {
        attributes.remove(s);
    }

    public void clearAttributes() {
        attributes.clear();
    }

    public Enumeration getChildren() {
        return children.elements();
    }

    public Enumeration getChildren(String s) {
        Vector vector = new Vector();
        for(Enumeration enumeration = getChildren(); enumeration.hasMoreElements();) {
            Element element = (Element) enumeration.nextElement();
            if(element.getName().equals(s))
                vector.addElement(element);
        }
        return vector.elements();
    }

    public Element getChild(String name) {
        Enumeration enumeration = getChildren(name);
        if (!enumeration.hasMoreElements()) {
            return null;
        }
        return (Element) enumeration.nextElement();
    }

    public boolean hasChildren() {
        return !children.isEmpty();
    }

    public int countChildren() {
        return children.size();
    }

    public void addChild(Element element)
    throws NullPointerException {
        if(element == null) {
            throw new NullPointerException("Child cannot be null");
        }
        children.addElement(element);
    }

    public void clearChildren() {
        children.removeAllElements();
    }

    public String getData() {
        if (data != null) {
            return substituteVariables(data);
        }
        return data;
    }

    public void setData(Object s) {
        data = s.toString().trim();
    }

    public void clearData() {
        data = "";
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String s) {
        comment = s;
    }

    public void clearComment() {
        comment = "";
    }

    public Element() {
        this("", null);
    }

    public Element(String s, Element parent) {
        this.parent = parent;
        name = s;
        attributes = new Hashtable();
        children = new Vector();
        data = "";
        comment = "";
    }
    
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Name=" + name);
        buffer.append(" Data=" + data);
        for (Enumeration e = getChildren(); e.hasMoreElements(); ) {
            Element el = (Element) e.nextElement();
            buffer.append("  " + el.toString());
        }
        return buffer.toString();
    }
    
    private String substituteVariables(String text) {
        if (text.indexOf('$') == -1) return text;
        
        StringTokenizer tokenizer = new StringTokenizer(text, "$");
        
        StringBuffer b = new StringBuffer();
        
        for (;tokenizer.hasMoreTokens();) {
            String token = tokenizer.nextToken();

            if (token.startsWith("{")) {
                int endPos = token.indexOf('}');
                if (endPos > 0) {
                    String tail = token.substring(endPos+1);
                    String var = token.substring(1, endPos);
                    
                    String value = Domain.getProperty(var);
                    if (value == null) {
                        // try definitions in slide.properties
                        value = Configuration.getProperty(var);
                    }
                    if (value == null) {
                        // try system definitions
                        value = System.getProperty(var);
                    }
                    if (value != null) {
                        b.append(value);
                    } else {
                        b.append("${").append(var).append("}");
                    }
                    
                    b.append(tail);
                }
            } else {
                b.append(token);
            }
        }
        
        return b.toString();
    }
}
