/*
 * Copyright 2002-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.axis.message;

import org.apache.axis.InternalException;
import org.w3c.dom.DOMException;

/**
 * A representation of a node whose value is text. A <CODE>
 *   Text</CODE> object may represent text that is content or text
 *   that is a comment.
 *
 * @author Davanum Srinivas (dims@yahoo.com)
 * @author Heejune Ahn      (cityboy@tmax.co.kr)
 */
public class Text extends NodeImpl implements javax.xml.soap.Text {

    public Text(org.w3c.dom.CharacterData data) {
        if ( data == null )
        {
           throw new IllegalArgumentException( "Text value may not be null." );
        }
        textRep = data;
    }

    public Text(String s) {
        try {
            org.w3c.dom.Document doc = org.apache.axis.utils.XMLUtils.newDocument();
            textRep = doc.createTextNode(s);
        } catch (javax.xml.parsers.ParserConfigurationException e) {
            throw new InternalException(e);
        }
    }

    public Text()
    {
        this((String)null);
    }

    /**
     * Retrieves whether this <CODE>Text</CODE> object
     * represents a comment.
     * @return  <CODE>true</CODE> if this <CODE>Text</CODE> object is
     *     a comment; <CODE>false</CODE> otherwise
     */
    public boolean isComment() {
        String temp = textRep.getNodeValue().trim();
        if(temp.startsWith("<!--") && temp.endsWith("-->"))
            return true;
        return false;
    }

    /**
     * Implementation of DOM TEXT Interface
     * *************************************************************
     */

    // Overriding the MessageElement Method, where it throws exeptions.
    public String getNodeValue() throws DOMException {
        return textRep.getNodeValue();
    }

    // Overriding the MessageElement Method, where it throws exeptions.
    public void setNodeValue(String nodeValue) throws DOMException{
        setDirty();
        textRep.setNodeValue(nodeValue);
    }

    /**
     * Use the textRep, and convert it to org.apache.axis.Text
     * in order to keep the Axis SOAP strcture after operation
     *
     * This work would be easier if constructor, Text(org.w3c.dom.Text)
     * is defined
     *
     * @since SAAJ 1.2
     * @param offset
     * @return
     * @throws DOMException
     */
    public org.w3c.dom.Text splitText(int offset) throws DOMException
    {
        int length = textRep.getLength();
        // take the first part, and save the second part for new Text
        // length check and exception will be thrown here, no need to duplicated check
        String tailData = textRep.substringData(offset,length);
        textRep.deleteData(offset,length);

        // insert the first part again as a new node
        Text tailText = new Text(tailData);
        org.w3c.dom.Node myParent = getParentNode();
        if(myParent != null){
            org.w3c.dom.NodeList brothers = myParent.getChildNodes();
            for(int i = 0;i  < brothers.getLength(); i++){
                if(brothers.item(i).equals(this)){
                    myParent.insertBefore(tailText, this);
                    return tailText;
                }
            }
        }
        return tailText;
    }

    /**
     * @since SAAJ 1.2
     */
    public String getData() throws DOMException {
        return textRep.getData();
    }

    /**
     * @since SAAJ 1.2
     */
    public void setData(String data) throws DOMException  {
        textRep.setData(data);
    }

    /**
     * @since SAAJ 1.2
     *
     * @return
     */
    public int getLength(){
        return textRep.getLength();
    }

    /**
     * @since SAAJ 1.2
     * @param offset
     * @param count
     * @return
     * @throws DOMException
     */
    public String substringData(int offset, int count)throws DOMException {
        return textRep.substringData(offset,count);
    }

    /**
     *
     * @since SAAJ 1.2
     * @param arg
     * @throws DOMException
     */
    public void appendData(String arg) throws DOMException {
        textRep.appendData(arg);
    }

    /**
     * @since SAAJ 1.2
     * @param offset
     * @param arg
     * @throws DOMException
     */
    public void insertData(int offset,  String arg)throws DOMException {
        textRep.insertData(offset, arg);
    }

    /**
     * @since SAAJ 1.2
     * @param offset
     * @param count
     * @param arg
     * @throws DOMException
     */
    public void replaceData(int offset, int count, String arg) throws DOMException   {
        textRep.replaceData(offset, count, arg);
    }

    /**
     * @since SAAJ 1.2
     * @param offset
     * @param count
     * @throws DOMException
     */
    public void deleteData(int offset, int count) throws DOMException {
        textRep.deleteData(offset, count);
    }

    public String toString()
    {
        return textRep.getNodeValue();
    }

    public boolean equals( Object obj )
    {
        if ( !( obj instanceof Text ) )
        {
            return false;
        }
        return this == obj || hashCode() == obj.hashCode();
    }

    public int hashCode()
    {
        if ( textRep == null )
        {
           return -1;
        }
        return ( textRep.getData() != null ? textRep.getData().hashCode() : 0 );
    }

}
