/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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.odftoolkit.simple.common.navigation;

import java.net.URI;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;
import org.odftoolkit.odfdom.dom.OdfContentDom;
import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.dom.OdfStylesDom;
import org.odftoolkit.odfdom.dom.element.OdfStylableElement;
import org.odftoolkit.odfdom.dom.element.OdfStyleBase;
import org.odftoolkit.odfdom.dom.element.dc.DcCreatorElement;
import org.odftoolkit.odfdom.dom.element.dc.DcDateElement;
import org.odftoolkit.odfdom.dom.element.office.OfficeAnnotationElement;
import org.odftoolkit.odfdom.dom.element.style.StyleParagraphPropertiesElement;
import org.odftoolkit.odfdom.dom.element.style.StyleTextPropertiesElement;
import org.odftoolkit.odfdom.dom.element.text.TextAElement;
import org.odftoolkit.odfdom.dom.element.text.TextConditionalTextElement;
import org.odftoolkit.odfdom.dom.element.text.TextPElement;
import org.odftoolkit.odfdom.dom.element.text.TextParagraphElementBase;
import org.odftoolkit.odfdom.dom.element.text.TextSElement;
import org.odftoolkit.odfdom.dom.element.text.TextSpanElement;
import org.odftoolkit.odfdom.dom.element.text.TextUserFieldDeclElement;
import org.odftoolkit.odfdom.dom.style.OdfStyleFamily;
import org.odftoolkit.odfdom.dom.style.props.OdfStylePropertiesSet;
import org.odftoolkit.odfdom.dom.style.props.OdfStyleProperty;
import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeAutomaticStyles;
import org.odftoolkit.odfdom.incubator.doc.style.OdfStyle;
import org.odftoolkit.odfdom.incubator.doc.text.OdfTextHeading;
import org.odftoolkit.odfdom.incubator.doc.text.OdfTextParagraph;
import org.odftoolkit.odfdom.incubator.doc.text.OdfTextSpan;
import org.odftoolkit.odfdom.pkg.OdfElement;
import org.odftoolkit.odfdom.pkg.OdfFileDom;
import org.odftoolkit.simple.Document;
import org.odftoolkit.simple.TextDocument;
import org.odftoolkit.simple.common.TextExtractor;
import org.odftoolkit.simple.common.field.ConditionField;
import org.odftoolkit.simple.common.field.Field;
import org.odftoolkit.simple.common.field.Field.FieldType;
import org.odftoolkit.simple.common.field.Fields;
import org.odftoolkit.simple.common.field.VariableField;
import org.odftoolkit.simple.draw.Image;
import org.odftoolkit.simple.table.Table;
import org.odftoolkit.simple.text.Paragraph;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * <code>TextSelection</code> describes a sub element in a paragraph element or
 * a heading element. It is recognized by the container element, which type
 * should be {@link org.odftoolkit.odfdom.incubator.doc.text.OdfTextParagraph
 * OdfTextParagraph} or
 * {@link org.odftoolkit.odfdom.incubator.doc.text.OdfTextHeading
 * OdfTextHeading}, the start index of text content in container element and the
 * text content of this <code>Selection</code>.
 */
public class TextSelection extends Selection {

	String mMatchedText;
	private OdfTextParagraph mParagraph;
	private OdfTextHeading mHeading;
	private int mIndexInContainer;
	private boolean mIsInserted;
	private boolean isSelectionReplaced = false;

	/**
	 * Constructor of <code>TextSelection</code>.
	 *
	 * @param text
	 *            the text content of this <code>TextSelection</code>
	 * @param containerElement
	 *            the paragraph element or heading element that contains this
	 *            <code>TextSelection</code>
	 * @param index
	 *            the start index of the text content in container element
	 *
	 */
	TextSelection(Navigation search, String text, OdfElement containerElement,
			int index) {
		this.search = search;
		mMatchedText = text;
		if (containerElement instanceof OdfTextParagraph) {
			mParagraph = (OdfTextParagraph) containerElement;
		} else if (containerElement instanceof OdfTextHeading) {
			mHeading = (OdfTextHeading) containerElement;
		}
		mIndexInContainer = index;
	}

	public TextNavigation getTextNavigation() {
		if (search instanceof TextNavigation) {
			return (TextNavigation) search;
		}
		return null;
	}
	/**
	 * Create a new <code>TextSelection</code>.
	 *
	 * @param text
	 *            the text content of this <code>TextSelection</code>
	 * @param containerElement
	 *            the paragraph element or heading element that contains this
	 *            <code>TextSelection</code>
	 * @param index
	 *            the start index of the text content in container element
	 *
	 * @since 0.5.5
	 */
	public static TextSelection newTextSelection(Navigation search,
			String text, OdfElement containerElement, int index) {
		TextSelection selection = new TextSelection(search, text,
				containerElement, index);
		Selection.SelectionManager.registerItem(selection);
		return selection;
	}

	/**
	 * Get the paragraph element or heading element that contains this
	 * <code>TextSelection</code>.
	 *
	 * @return OdfElement the container element
	 */
	@Override
	public OdfElement getElement() {
		return getContainerElement();
	}

	/**
	 * Get the paragraph element or heading element that contains this text.
	 *
	 * @return OdfElement
	 */
	public OdfElement getContainerElement() {
		if (mParagraph != null) {
			return mParagraph;
		} else {
			return mHeading;
		}
	}

	/**
	 * Get the start index of the text content of its container element.
	 *
	 * @return index the start index of the text content of its container
	 *         element
	 */
	@Override
	public int getIndex() {
		return mIndexInContainer;
	}

	/**
	 * Get the text content of this <code>TextSelection</code>.
	 *
	 * @return text the text content
	 */
	public String getText() {
		return mMatchedText;
	}

	/**
	 * Delete the selection from the document the other matched selection in the
	 * same container element will be updated automatically because the start
	 * index of the following selections will be changed when the previous
	 * selection has been deleted.
	 *
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 */
	@Override
	public void cut() throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		OdfElement container = getContainerElement();
		delete(mIndexInContainer, mMatchedText.length(), container);
		SelectionManager.refreshAfterCut(this);
		mMatchedText = "";
	}

	/**
	 * Apply a style to the selection so that the text style of this selection
	 * will append the specified style.
	 *
	 * @param style
	 *            the style can be from the current document or user defined
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 */
	public void applyStyle(OdfStyleBase style) throws InvalidNavigationException {
		// append the specified style to the selection
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		OdfElement parentElement = getContainerElement();

		int leftLength = getText().length();
		int index = mIndexInContainer;

		appendStyle(index, leftLength, parentElement, style);

	}

	/**
	 * Replace the text content of selection with a new string.
	 *
	 * @param newText
	 *            the replace text String
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 */
	public void replaceWith(String newText) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		OdfElement parentElement = getContainerElement();
		int leftLength = getText().length();
		int index = mIndexInContainer;
		delete(index, leftLength, parentElement);
		OdfTextSpan textSpan = new OdfTextSpan((OdfFileDom) parentElement.getOwnerDocument());
		textSpan.addContentWhitespace(newText);
		mIsInserted = false;
		insertOdfElement(textSpan, index, parentElement);
		// optimize the parent element
		optimize(parentElement);
		int offset = newText.length() - leftLength;
		SelectionManager.refresh(getContainerElement(), offset, index + getText().length());
		mMatchedText = newText;
	}

	/**
	 * Replace the text content of selection with a new Table.
	 *
	 * @param newTable
	 *            the replace Table
	 * @return
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 * @return the new Table in the TextDocument
	 */
	public Table replaceWith(Table newTable) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		TableSelection nextTableSelection=new TableSelection(this);
		return nextTableSelection.replaceWithTable(newTable);
	}
	/**
	 * Replace the text content of selection with a new Image.
	 *
	 * @param newImage
	 *            the replace Image
	 * @return
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 * @return the new Image in the TextDocument,the image name is set to "replace" + System.currentTimeMillis(), please update the name to others by yourself.
	 */
	public Image replaceWith(Image newImage) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		ImageSelection nextImageSelection=new ImageSelection(this);
		return nextImageSelection.replaceWithImage(newImage);
	}
	/**
	 * Replace the text content of selection with a new Image.
	 *
	 * @param imageUri
	 *            the replace Image URI
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 * @return the new Image in the TextDocument,the image name is set to "replace" + System.currentTimeMillis(), please update the name to others by yourself.
	 */
	public Image replaceWith(URI imageUri) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		ImageSelection nextImageSelection=new ImageSelection(this);
		return nextImageSelection.replaceWithImage(imageUri);
	}
	/**
	 * Replace the content with a Field
	 *
	 * @param orgField
	 *            the reference Field to replace.
     * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 * @return the created field.
	 */
	public Field replaceWith(Field orgField) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		Field newfield=null;
		OdfElement parentElement = getContainerElement();
		Paragraph orgparagraph = Paragraph.getInstanceof((TextParagraphElementBase) parentElement);
		TextDocument document = (TextDocument) orgparagraph.getOwnerDocument();

		FieldSelection nextFieldSelection=new FieldSelection(this);
		FieldType fieldType = orgField.getFieldType();

		switch (fieldType) {
		case DATE_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case FIXED_DATE_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case TIME_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case FIXED_TIME_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case PREVIOUS_PAGE_NUMBER_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case CURRENT_PAGE_NUMBER_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case NEXT_PAGE_NUMBER_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case PAGE_COUNT_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case TITLE_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case SUBJECT_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case AUTHOR_NAME_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case AUTHOR_INITIALS_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case CHAPTER_FIELD:
			newfield=nextFieldSelection.replaceWithSimpleField(fieldType);
			break;
		case SIMPLE_VARIABLE_FIELD:
			VariableField SimpleVariableField = (VariableField)orgField;
			String simplefieldname = SimpleVariableField.getVariableName();
			VariableField simplefield=Fields.createSimpleVariableField(document, simplefieldname);
			nextFieldSelection.replaceWithVariableField(simplefield);
			newfield=simplefield;
			break;
		case USER_VARIABLE_FIELD:
			VariableField userVariableField = (VariableField)orgField;
			TextUserFieldDeclElement textUserFieldDeclElement =(TextUserFieldDeclElement) userVariableField.getOdfElement();
			String fieldname = userVariableField.getVariableName();
			String value=textUserFieldDeclElement.getOfficeStringValueAttribute();
			VariableField variableField=Fields.createUserVariableField(document, fieldname,value);
			nextFieldSelection.replaceWithVariableField(variableField);
			newfield=variableField;
			break;
		case CONDITION_FIELD:
			ConditionField conditionField = (ConditionField)orgField;
			TextConditionalTextElement textConditionalTextElement =(TextConditionalTextElement) conditionField.getOdfElement();
			String StringValueIfFalse=textConditionalTextElement.getTextStringValueIfFalseAttribute();
			String StringValueIfTrue=textConditionalTextElement.getTextStringValueIfTrueAttribute();
			String StringCondition=textConditionalTextElement.getTextConditionAttribute();
			boolean CurrentValue=textConditionalTextElement.getTextCurrentValueAttribute();
			ConditionField newdConditionField = nextFieldSelection.replaceWithConditionField(StringCondition, StringValueIfTrue, StringValueIfFalse);
			TextConditionalTextElement newTextConditionalTextElement=(TextConditionalTextElement)newdConditionField.getOdfElement();
			newTextConditionalTextElement.setTextCurrentValueAttribute(CurrentValue);
			newfield=newdConditionField;
			break;
		case HIDDEN_TEXT_FIELD:
			ConditionField conditionFieldHIDDEN = (ConditionField)orgField;
			TextConditionalTextElement textConditionalTextElementHIDDEN =(TextConditionalTextElement) conditionFieldHIDDEN.getOdfElement();
			String StringValueIfFalseHIDDEN=textConditionalTextElementHIDDEN.getTextStringValueIfFalseAttribute();
			String StringConditionHIDDEN=textConditionalTextElementHIDDEN.getTextConditionAttribute();
			boolean CurrentValueHIDDEN=textConditionalTextElementHIDDEN.getTextCurrentValueAttribute();
			ConditionField newdConditionFieldHIDDEN = nextFieldSelection.replaceWithHiddenTextField(StringConditionHIDDEN, StringValueIfFalseHIDDEN);
			TextConditionalTextElement newTextConditionalTextElementHIDDEN=(TextConditionalTextElement)newdConditionFieldHIDDEN.getOdfElement();
			newTextConditionalTextElementHIDDEN.setTextCurrentValueAttribute(CurrentValueHIDDEN);
			newfield=newdConditionFieldHIDDEN;
			break;
		case REFERENCE_FIELD:
		default: throw new IllegalArgumentException("Simple Java API for ODF doesn't support this type now.");
		}
		return newfield;
	}

	/**
	 * Replace the content with a paragraph, the paragraph can be in the same TextDocument or in a different Document.
	 *
	 * @param newParagraph
	 *            the reference paragraph to replace.
     * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 * @return the replaced Paragraph.
	 */
	public Paragraph replaceWith(Paragraph newParagraph) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		ParagraphSelection nextParagraphSelection=new ParagraphSelection(this);
		return nextParagraphSelection.replaceWithParagraph(newParagraph);
	}
	/**
	 * Replace the content with a TextDocument with Styles.
	 * Note: You need cache the TextNavigation.nextSelection item because after
	 * you replace currtenTextSelection with TextDocument, TextNavigation.nextSelection will search from the inserted Content,
	 * it will make you into a loop if the Search keyword also can be found in the new inserted Content.
	 * </p>
	 * The right way to use this replaceWithTextDocument(TextDocument textDocument) method should like this:
	 * <Code>
	 * <p>	search = new TextNavigation("SIMPLE", doc);    </p>
	 * <p>	TextSelection currtenTextSelection,nextTextSelection=null;</p>
	 * <p>		while (search.hasNext()) {</p>
	 * <p>			if(nextTextSelection!=null){</p>
	 * <p>				currtenTextSelection=nextTextSelection;</p>
	 * <p>			}else {</p>
	 * <p>			 	currtenTextSelection = (TextSelection) search.nextSelection();</p>
	 * <p>			}</p>
	 * <p>			nextTextSelection = (TextSelection) search.nextSelection();</p>
	 * <p>			if(currtenTextSelection!=null){</p>
	 * <p>				try {</p>
	 * <p>					nextTextSelection.replaceWithTextDocument(sourcedoc);</p>
	 * <p>				} catch (Exception e) {</p>
	 * <p>					e.printStackTrace();</p>
	 * <p>				}</p>
	 * <p>			}</p>
	 * <p>		}</p>
	 * <p>		if(nextTextSelection!=null){</p>
	 * <p>			try {</p>
	 * <p>				nextTextSelection.replaceWithTextDocument(sourcedoc);</p>
	 * <p>			} catch (Exception e) {</p>
	 * <p>				e.printStackTrace();</p>
	 * <p>			}</p>
	 * <p>		}</p>
	 * </Code>
	 *
	 * @param newTextDocument
	 *            the reference TextDocument to replace.
	 * @throws InvalidNavigationException
	 */
	public void replaceWith(TextDocument newTextDocument) throws InvalidNavigationException{
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		TextDocumentSelection nextTextDocumentSelection=new TextDocumentSelection(this);
		try {
			nextTextDocumentSelection.replaceWithTextDocument(newTextDocument);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * Create a span element for this text selection.
	 *
	 * @return the created text span element for this selection
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 * @since 0.5.5
	 */
	public TextSpanElement createSpanElement() throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		OdfElement parentElement = getContainerElement();
		int leftLength = getText().length();
		int index = mIndexInContainer;
		delete(index, leftLength, parentElement);
		OdfTextSpan textSpan = new OdfTextSpan((OdfFileDom) parentElement.getOwnerDocument());
		textSpan.addContentWhitespace(getText());
		mIsInserted = false;
		insertOdfElement(textSpan, index, parentElement);
		// optimize the parent element
		optimize(parentElement);

		return textSpan;
	}

	/**
	 * Paste this selection just before a specific selection.
	 *
	 * @param positionItem
	 *            a selection that is used to point out the position
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 */
	@Override
	public void pasteAtFrontOf(Selection positionItem) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		int indexOfNew = 0;
		OdfElement newElement = positionItem.getElement();
		if (positionItem instanceof TextSelection) {
			indexOfNew = ((TextSelection) positionItem).getIndex();
			newElement = ((TextSelection) positionItem).getContainerElement();
		}

		OdfTextSpan textSpan = getSpan((OdfFileDom) positionItem.getElement().getOwnerDocument());
		mIsInserted = false;
		insertOdfElement(textSpan, indexOfNew, newElement);
		adjustStyle(newElement, textSpan, null);
		SelectionManager.refreshAfterPasteAtFrontOf(this, positionItem);
	}

	/**
	 * Paste this selection just after a specific selection.
	 *
	 * @param positionItem
	 *            a selection that is used to point out the position
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 */
	@Override
	public void pasteAtEndOf(Selection positionItem) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		// TODO: think about and test if search item is a element selection
		int indexOfNew = 0;
		OdfElement newElement = positionItem.getElement();
		if (positionItem instanceof TextSelection) {
			indexOfNew = ((TextSelection) positionItem).getIndex() + ((TextSelection) positionItem).getText().length();
			newElement = ((TextSelection) positionItem).getContainerElement();
		}
		OdfTextSpan textSpan = getSpan((OdfFileDom) positionItem.getElement().getOwnerDocument());
		mIsInserted = false;
		insertOdfElement(textSpan, indexOfNew, newElement);
		adjustStyle(newElement, textSpan, null);
		SelectionManager.refreshAfterPasteAtEndOf(this, positionItem);
	}
	public void setSelectionReplaced(boolean b) {
		this.isSelectionReplaced = b;
	}
	public boolean isSelectionReplaced() {
		return this.isSelectionReplaced;
	}

	/**
	 * Add a hypertext reference to the selection.
	 *
	 * @param url
	 *            the URL of this hypertext reference
	 * @throws InvalidNavigationException
	 *             if the selection is unavailable.
	 */
	public void addHref(URL url) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		OdfElement parentElement = getContainerElement();
		int leftLength = getText().length();
		int index = mIndexInContainer;
		addHref(index, leftLength, parentElement, url.toString());
	}

	/**
	 * Add a comment to the selection.
	 *
	 * @param content
	 *            the content of this comment.
	 * @param creator
	 *            the creator of this comment, if <code>creator</code> is null,
	 *            the value of <code>System.getProperty("user.name")</code> will
	 *            be used.
	 * @throws InvalidNavigationException
	 *            if the selection is unavailable.
	 * @since 0.6.5
	 */
	public void addComment(String content, String creator) throws InvalidNavigationException {
		if (validate() == false) {
			throw new InvalidNavigationException("No matched string at this position");
		}
		// create annotation element
		OdfElement parentElement = getContainerElement();
		OdfFileDom dom = (OdfFileDom) parentElement.getOwnerDocument();
		OfficeAnnotationElement annotationElement = dom.newOdfElement(OfficeAnnotationElement.class);
		// set creator
		DcCreatorElement dcCreatorElement = annotationElement.newDcCreatorElement();
		if (creator == null) {
			creator = System.getProperty("user.name");
		}
		dcCreatorElement.setTextContent(creator);
		// set date
		String dcDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date());
		DcDateElement dcDateElement = annotationElement.newDcDateElement();
		dcDateElement.setTextContent(dcDate);
		TextPElement notePElement = annotationElement.newTextPElement();
		TextSpanElement noteSpanElement = notePElement.newTextSpanElement();
		// set comment style
		OdfOfficeAutomaticStyles styles = null;
		if (dom instanceof OdfContentDom) {
			styles = ((OdfContentDom) dom).getAutomaticStyles();
		} else if (dom instanceof OdfStylesDom) {
			styles = ((OdfStylesDom) dom).getAutomaticStyles();
		}
		OdfStyle textStyle = styles.newStyle(OdfStyleFamily.Text);
		StyleTextPropertiesElement styleTextPropertiesElement = textStyle.newStyleTextPropertiesElement(null);
		styleTextPropertiesElement.setStyleFontNameAttribute("Tahoma");
		styleTextPropertiesElement.setFoFontSizeAttribute("10pt");
		styleTextPropertiesElement.setStyleFontNameAsianAttribute("Lucida Sans Unicode");
		styleTextPropertiesElement.setStyleFontSizeAsianAttribute("12pt");
		noteSpanElement.setStyleName(textStyle.getStyleNameAttribute());
		// set comment content
		noteSpanElement.setTextContent(content);
		// insert comment to its position
		insertOdfElement(annotationElement, mIndexInContainer, parentElement);
		// three text length plus two '\r'
		int offset = content.length() + 1 + dcDate.length() + 1 + creator.length();
		SelectionManager.refresh(getContainerElement(), offset, getIndex());
	}

	/**
	 * return a String Object representing this selection value the text content
	 * of the selection, start index in the container element and the text
	 * content of the container element will be provided.
	 *
	 * @return a String representation of the value of this
	 *         <code>TextSelection</code>
	 */
	@Override
	public String toString() {
		return "[" + mMatchedText + "] started from " + mIndexInContainer + " in paragraph:"
				+ TextExtractor.getText(getContainerElement());
	}

	@Override
	protected void refreshAfterFrontalDelete(Selection deleteItem) {
		if (deleteItem instanceof TextSelection) {
			mIndexInContainer -= ((TextSelection) deleteItem).getText().length();
		}
	}

	@Override
	protected void refreshAfterFrontalInsert(Selection pasteItem) {
		if (pasteItem instanceof TextSelection) {
			mIndexInContainer += ((TextSelection) pasteItem).getText().length();
		}
	}

	@Override
	protected void refresh(int offset) {
		mIndexInContainer += offset;
		if (mIndexInContainer < 0) {
			mIndexInContainer = 0;
		}
	}

	void cleanBreakProperty(Paragraph paragraph) {
		TextNavigation search = this.getTextNavigation();
		if (search == null)
			throw new IllegalStateException("Navigation is null");
		OdfStyleBase styleElement = paragraph.getStyleHandler()
				.getStyleElementForRead();
		String name = styleElement.getAttribute("style:name");
		String newName = null;
		OdfElement modifiedStyleElement = search
				.getModifiedStyleElement(styleElement);
		if (modifiedStyleElement == null) {
			modifiedStyleElement = (OdfElement) styleElement.cloneNode(true);
			search.addModifiedStyleElement(styleElement, modifiedStyleElement);
			NodeList paragraphProperties = modifiedStyleElement
					.getElementsByTagName("style:paragraph-properties");
			if (paragraphProperties != null
					&& paragraphProperties.getLength() > 0) {
				StyleParagraphPropertiesElement property = (StyleParagraphPropertiesElement) paragraphProperties
						.item(0);
				property.removeAttribute("fo:break-before");
				property.removeAttribute("fo:break-after");
				property.removeAttribute("style:page-number");
			}
			modifiedStyleElement.removeAttribute("style:master-page-name");
			newName = name + "-" + makeUniqueName();
			NamedNodeMap attributes = modifiedStyleElement.getAttributes();
			if (attributes != null) {
				for (int i = 0; i < attributes.getLength(); i++) {
					Node item = attributes.item(i);
					String value = item.getNodeValue();
					if (name.equals(value)) {
						item.setNodeValue(newName);
						break;
					}
				}
			}
			styleElement.getParentNode().appendChild(modifiedStyleElement);
		} else {
			newName = modifiedStyleElement.getAttribute("style:name");
		}
		NamedNodeMap attributes = paragraph.getOdfElement().getAttributes();
		if (attributes != null) {
			for (int i = 0; i < attributes.getLength(); i++) {
				Node item = attributes.item(i);
				String value = item.getNodeValue();
				if (name.equals(value)) {
					item.setNodeValue(newName);
					break;
				}
			}
		}
		this.getTextNavigation().setHandlePageBreak(true);
	}
	String makeUniqueName() {
		return String.format("p%06x", (int) (Math.random() * 0xffffff));
	}
	/*
	 * Return a new span that cover this selection and keep the original style
	 * of this <code>Selection</code>.
	 */
	private OdfTextSpan getSpan(OdfFileDom ownerDoc) {

		OdfElement parentElement = getContainerElement();
		if (parentElement != null) {
			OdfElement copyParentNode = (OdfElement) parentElement.cloneNode(true);
			if (ownerDoc != parentElement.getOwnerDocument()) {
				copyParentNode = (OdfElement) ownerDoc.adoptNode(copyParentNode);
			}
			OdfTextSpan textSpan = new OdfTextSpan(ownerDoc);
			int sIndex = mIndexInContainer;
			int eIndex = sIndex + mMatchedText.length();
			// delete the content except the selection string
			// delete from the end to start, so that the postion will not be
			// impact by delete action
			delete(eIndex, TextExtractor.getText(copyParentNode).length() - eIndex, copyParentNode);
			delete(0, sIndex, copyParentNode);
			optimize(copyParentNode);
			Node childNode = copyParentNode.getFirstChild();
			while (childNode != null) {
				textSpan.appendChild(childNode.cloneNode(true));
				childNode = childNode.getNextSibling();
			}
			// apply text style for the textSpan
			if (copyParentNode instanceof OdfStylableElement) {
				applyTextStyleProperties(getTextStylePropertiesDeep((OdfStylableElement) copyParentNode), textSpan);
			}
			return textSpan;
		}
		return null;
	}

	/*
	 * Optimize the text element by deleting the empty text node.
	 */
	private void optimize(Node pNode) {
		// check if the text:a can be optimized
		Node node = pNode.getFirstChild();
		while (node != null) {
			Node nextNode = node.getNextSibling();
			// if ((node.getNodeType() == Node.ELEMENT_NODE) &&
			// (node.getPrefix().equals("text"))) {
			if (node instanceof OdfTextSpan) {
				if (TextExtractor.getText((OdfTextSpan) node).length() == 0) {
					node.getParentNode().removeChild(node);
				} else {
					optimize(node);
				}
			}
			node = nextNode;
		}
	}

	/*
	 * Apply the <code>styleMap</code> to the <code>toElement</code> reserve the
	 * style property of toElement, if it is also exist in <code>styleMap</code>
	 */
	private void applyTextStyleProperties(Map<OdfStyleProperty, String> styleMap, OdfStylableElement toElement) {
		if (styleMap != null) {
			// preserve the style property of toElement if it is also exist in
			// styleMap
			OdfStyle resultStyleElement = toElement.getAutomaticStyles().newStyle(OdfStyleFamily.Text);
			for (Map.Entry<OdfStyleProperty, String> entry : styleMap.entrySet()) {
				if (toElement.hasProperty(entry.getKey())) {
					resultStyleElement.setProperty(entry.getKey(), toElement.getProperty(entry.getKey()));
				} else {
					resultStyleElement.setProperty(entry.getKey(), entry.getValue());
				}
			}
			toElement.setStyleName(resultStyleElement.getStyleNameAttribute());
		}
	}

	/*
	 * Insert <code>odfElement</code>, span or annotation, into the from index of <code>pNode<code>.
	 */
	private void insertOdfElement(OdfElement odfElement, int fromIndex, Node pNode) {
		if (fromIndex < 0) {
			fromIndex = 0;
		}
		if (fromIndex == 0 && mIsInserted) {
			return;
		}
		int nodeLength = 0;
		Node node = pNode.getFirstChild();
		while (node != null) {
			if (fromIndex <= 0 && mIsInserted) {
				return;
			}
			if (node.getNodeType() == Node.TEXT_NODE) {
				nodeLength = node.getNodeValue().length();
				if ((fromIndex != 0) && (nodeLength < fromIndex)) {
					fromIndex -= nodeLength;
				} else {
					// insert result after node, and insert an new text node
					// after the result node
					String value = node.getNodeValue();
					StringBuffer buffer = new StringBuffer();
					buffer.append(value.substring(0, fromIndex));
					// insert the text span in appropriate position
					node.setNodeValue(buffer.toString());
					Node nextNode = node.getNextSibling();
					Node parNode = node.getParentNode();
					Node newNode = node.cloneNode(true);
					newNode.setNodeValue(value.substring(fromIndex, value.length()));
					if (nextNode != null) {
						parNode.insertBefore(odfElement, nextNode);
						parNode.insertBefore(newNode, nextNode);
					} else {
						parNode.appendChild(odfElement);
						parNode.appendChild(newNode);
					}
					mIsInserted = true;
					return;
				}
			} else if (node.getNodeType() == Node.ELEMENT_NODE) {
				// text:s
				if (node.getLocalName().equals("s")) {
					try {
						nodeLength = Integer.parseInt(((Element) node).getAttributeNS(OdfDocumentNamespace.TEXT
								.getUri(), "c"));
					} catch (Exception e) {
						nodeLength = 1;
					}
					fromIndex -= nodeLength;
				} else if (node.getLocalName().equals("line-break")) {
					nodeLength = 1;
					fromIndex--;
				} else if (node.getLocalName().equals("tab")) {
					nodeLength = 1;
					fromIndex--;
				} else {
					nodeLength = TextExtractor.getText((OdfElement) node).length();
					insertOdfElement(odfElement, fromIndex, node);
					fromIndex -= nodeLength;
				}
			}
			node = node.getNextSibling();
		}
	}

	/*
	 * The <code>textSpan</code> must be the child element of
	 * <code>parentNode</code> this method is used to keep the style of text
	 * span when it has been insert into the <code>parentNode</code> if we don't
	 * deal with the style, the inserted span will also have the style of
	 * <code>parentNode</code>.
	 */
	private void adjustStyle(Node parentNode, OdfTextSpan textSpan, Map<OdfStyleProperty, String> styleMap) {
		if (parentNode instanceof OdfStylableElement) {
			OdfStylableElement pStyleNode = (OdfStylableElement) parentNode;
			if (styleMap == null) {
				styleMap = getTextStylePropertiesDeep(pStyleNode);
			}
			Node node = parentNode.getFirstChild();
			while (node != null) {
				if (node.getNodeType() == Node.TEXT_NODE) {
					if (node.getTextContent().length() > 0) {
						Node nextNode = node.getNextSibling();
						OdfTextSpan span = new OdfTextSpan((OdfFileDom) node.getOwnerDocument());
						span.appendChild(node);
						if (nextNode != null) {
							parentNode.insertBefore(span, nextNode);
						} else {
							parentNode.appendChild(span);
						}
						node = span;
						applyTextStyleProperties(styleMap, (OdfStylableElement) node);
					}
				} else if ((node instanceof OdfStylableElement)) {
					if (!node.equals(textSpan)) {
						Map<OdfStyleProperty, String> styles = getTextStylePropertiesDeep(pStyleNode);
						Map<OdfStyleProperty, String> styles1 = getTextStylePropertiesDeep((OdfStylableElement) node);
						if (styles == null) {
							styles = styles1;
						} else if (styles1 != null) {
							styles.putAll(styles1);
						}
						int comp = node.compareDocumentPosition(textSpan);
						// if node contains textSpan, then recurse the node
						if ((comp & Node.DOCUMENT_POSITION_CONTAINED_BY) > 0) {
							adjustStyle(node, textSpan, styles);
						} else {
							applyTextStyleProperties(styles, (OdfStylableElement) node);
						}
					}
				}
				node = node.getNextSibling();
			}
			// change the parentNode to default style
			// here we don't know the default style name, so here just
			// remove the text:style-name attribute
			pStyleNode.removeAttributeNS(OdfDocumentNamespace.TEXT.getUri(), "style-name");
		}
	}

	/*
	 * Delete the <code>pNode<code> from the <code>fromIndex</code> text, and
	 * delete <code>leftLength</code> text.
	 */
	private void delete(int fromIndex, int leftLength, Node pNode) {
		if ((fromIndex == 0) && (leftLength == 0)) {
			return;
		}
		int nodeLength = 0;
		Node node = pNode.getFirstChild();
		while (node != null) {
			if ((fromIndex == 0) && (leftLength == 0)) {
				return;
			}
			if (node.getNodeType() == Node.TEXT_NODE) {
				nodeLength = node.getNodeValue().length();
			} else if (node.getNodeType() == Node.ELEMENT_NODE) {
				// text:s
				if (node.getLocalName().equals("s")) {
					try {
						nodeLength = Integer.parseInt(((Element) node).getAttributeNS(OdfDocumentNamespace.TEXT
								.getUri(), "c"));
					} catch (Exception e) {
						nodeLength = 1;
					}
				} else if (node.getLocalName().equals("line-break")) {
					nodeLength = 1;
				} else if (node.getLocalName().equals("tab")) {
					nodeLength = 1;
				} else {
					nodeLength = TextExtractor.getText((OdfElement) node).length();
				}
			}
			if (nodeLength <= fromIndex) {
				fromIndex -= nodeLength;
			} else {
				// the start index is in this node
				if (node.getNodeType() == Node.TEXT_NODE) {
					String value = node.getNodeValue();
					StringBuffer buffer = new StringBuffer();
					buffer.append(value.substring(0, fromIndex));
					int endLength = fromIndex + leftLength;
					int nextLength = value.length() - endLength;
					fromIndex = 0;
					if (nextLength >= 0) {
						// delete the result
						buffer.append(value.substring(endLength, value.length()));
						leftLength = 0;
					} else {
						leftLength = endLength - value.length();
					}
					node.setNodeValue(buffer.toString());

				} else if (node.getNodeType() == Node.ELEMENT_NODE) {
					// if text:s?????????
					// text:s
					if (node.getLocalName().equals("s")) {
						// delete space
						((TextSElement) node).setTextCAttribute(new Integer(nodeLength - fromIndex));
						leftLength = leftLength - (nodeLength - fromIndex);
						fromIndex = 0;
					} else if (node.getLocalName().equals("line-break") || node.getLocalName().equals("tab")) {
						fromIndex = 0;
						leftLength--;
						Node nodeMerker = node.getNextSibling();
						pNode.removeChild(node);
						node = nodeMerker;
						continue;
					} else {
						delete(fromIndex, leftLength, node);
						int length = (fromIndex + leftLength) - nodeLength;
						leftLength = length > 0 ? length : 0;
						fromIndex = 0;
					}
				}
			}
			node = node.getNextSibling();
		}
	}

	/*
	 * Add href for a range text of <code>pNode<code> from the
	 * <code>fromIndex</code> text, and the href will cover
	 * <code>leftLength</code> text.
	 */
	private void addHref(int fromIndex, int leftLength, Node pNode, String href) {
		if ((fromIndex == 0) && (leftLength == 0)) {
			return;
		}
		int nodeLength = 0;
		Node node = pNode.getFirstChild();

		while (node != null) {
			if ((fromIndex == 0) && (leftLength == 0)) {
				return;
			}
			if (node.getNodeType() == Node.TEXT_NODE) {
				nodeLength = node.getNodeValue().length();
			} else if (node.getNodeType() == Node.ELEMENT_NODE) {
				// text:s
				if (node.getLocalName().equals("s")) {
					try {
						nodeLength = Integer.parseInt(((Element) node).getAttributeNS(OdfDocumentNamespace.TEXT
								.getUri(), "c"));
					} catch (Exception e) {
						nodeLength = 1;
					}
				} else if (node.getLocalName().equals("line-break")) {
					nodeLength = 1;
				} else if (node.getLocalName().equals("tab")) {
					nodeLength = 1;
				} else {
					nodeLength = TextExtractor.getText((OdfElement) node).length();
				}

			}
			if (nodeLength <= fromIndex) {
				fromIndex -= nodeLength;
			} else {
				// the start index is in this node
				if (node.getNodeType() == Node.TEXT_NODE) {
					String value = node.getNodeValue();
					node.setNodeValue(value.substring(0, fromIndex));
					int endLength = fromIndex + leftLength;
					int nextLength = value.length() - endLength;

					Node nextNode = node.getNextSibling();
					Node parNode = node.getParentNode();
					// init text:a
					TextAElement textLink = new TextAElement((OdfFileDom) node.getOwnerDocument());
					Node newNode = null;
					if (nextLength >= 0) {
						textLink.setTextContent(value.substring(fromIndex, endLength));
						newNode = node.cloneNode(true);
						newNode.setNodeValue(value.substring(endLength, value.length()));
						leftLength = 0;
					} else {
						textLink.setTextContent(value.substring(fromIndex, value.length()));
						leftLength = endLength - value.length();
					}
					textLink.setXlinkTypeAttribute("simple");
					textLink.setXlinkHrefAttribute(href);

					if (nextNode != null) {
						parNode.insertBefore(textLink, nextNode);
						if (newNode != null) {
							parNode.insertBefore(newNode, nextNode);
						}
					} else {
						parNode.appendChild(textLink);
						if (newNode != null) {
							parNode.appendChild(newNode);
						}
					}
					fromIndex = 0;
					if (nextNode != null) {
						node = nextNode;
					} else {
						node = textLink;
					}

				} else if (node.getNodeType() == Node.ELEMENT_NODE) {
					// if text:s?????????
					// text:s
					if (node.getLocalName().equals("s")) {
						// delete space
						((TextSElement) node).setTextCAttribute(new Integer(nodeLength - fromIndex));
						leftLength = leftLength - (nodeLength - fromIndex);
						fromIndex = 0;

					} else if (node.getLocalName().equals("line-break") || node.getLocalName().equals("tab")) {
						fromIndex = 0;
						leftLength--;
					} else {
						addHref(fromIndex, leftLength, node, href);
						int length = (fromIndex + leftLength) - nodeLength;
						leftLength = length > 0 ? length : 0;
						fromIndex = 0;
					}
				}
			}
			node = node.getNextSibling();
		}
	}

	/*
	 * Get a map containing text properties of the specified styleable
	 * <code>element</code>.
	 *
	 * @return a map of text properties.
	 */
	private Map<OdfStyleProperty, String> getTextStyleProperties(OdfStylableElement element) {
		String styleName = element.getStyleName();
		OdfStyleBase styleElement = element.getAutomaticStyles().getStyle(styleName, element.getStyleFamily());

		if (styleElement == null) {
			styleElement = element.getDocumentStyle();
		}
		if (styleElement != null) {
			// check if it is the style:defaut-style
			if ((styleElement.getPropertiesElement(OdfStylePropertiesSet.ParagraphProperties) == null)
					&& (styleElement.getPropertiesElement(OdfStylePropertiesSet.TextProperties) == null)) {
				styleElement = ((Document) ((OdfFileDom) styleElement.getOwnerDocument()).getDocument())
						.getDocumentStyles().getDefaultStyle(styleElement.getFamily());
			}
			TreeMap<OdfStyleProperty, String> result = new TreeMap<OdfStyleProperty, String>();
			OdfStyleFamily family = OdfStyleFamily.Text;
			if (family != null) {
				for (OdfStyleProperty property : family.getProperties()) {
					if (styleElement.hasProperty(property)) {
						result.put(property, styleElement.getProperty(property));
					}
				}
			}
			return result;
		}
		return null;
	}

	/*
	 * Get a map containing text properties of the specified styleable
	 * <code>element</code>. The map will also include any properties set by
	 * parent styles.
	 *
	 * @return a map of text properties.
	 */
	private Map<OdfStyleProperty, String> getTextStylePropertiesDeep(OdfStylableElement element) {
		String styleName = element.getStyleName();
		OdfStyleBase styleElement = element.getAutomaticStyles().getStyle(styleName, element.getStyleFamily());
		if (styleElement == null) {
			styleElement = element.getDocumentStyle();
		}
		TreeMap<OdfStyleProperty, String> result = new TreeMap<OdfStyleProperty, String>();
		while (styleElement != null) {
			// check if it is the style:defaut-style
			if ((styleElement.getPropertiesElement(OdfStylePropertiesSet.ParagraphProperties) == null)
					&& (styleElement.getPropertiesElement(OdfStylePropertiesSet.TextProperties) == null)) {
				styleElement = ((Document) ((OdfFileDom) styleElement.getOwnerDocument()).getDocument())
						.getDocumentStyles().getDefaultStyle(styleElement.getFamily());
			}
			OdfStyleFamily family = OdfStyleFamily.Text;
			if (family != null) {
				for (OdfStyleProperty property : family.getProperties()) {
					if (styleElement.hasProperty(property)) {
						result.put(property, styleElement.getProperty(property));
					}
				}
			}
			styleElement = styleElement.getParentStyle();
		}
		return result;
	}

	/*
	 * Validate if the <code>Selection</code> is still available.
	 *
	 * @return true if the selection is available; false if the
	 * <code>Selection</code> is not available.
	 */
	private boolean validate() {
		if (getContainerElement() == null) {
			return false;
		}
		OdfElement container = getContainerElement();
		if (container == null) {
			return false;
		}
		String content = TextExtractor.getText(container);
		if (content.indexOf(mMatchedText, mIndexInContainer) == mIndexInContainer) {
			return true;
		} else {
			return false;
		}
	}

	/*
	 * Append specified style for a range text of <code>pNode<code> from
	 * <code>fromIndex</code> and cover <code>leftLength</code>
	 */
	private void appendStyle(int fromIndex, int leftLength, Node pNode, OdfStyleBase style) {
		if ((fromIndex == 0) && (leftLength == 0)) {
			return;
		}
		int nodeLength = 0;
		Node node = pNode.getFirstChild();
		while (node != null) {
			if ((fromIndex == 0) && (leftLength == 0)) {
				return;
			}
			if (node.getNodeType() == Node.TEXT_NODE) {
				nodeLength = node.getNodeValue().length();
			} else if (node.getNodeType() == Node.ELEMENT_NODE) {
				// text:s
				if (node.getLocalName().equals("s")) {
					try {
						nodeLength = Integer.parseInt(((Element) node).getAttributeNS(OdfDocumentNamespace.TEXT
								.getUri(), "c"));
					} catch (Exception e) {
						nodeLength = 1;
					}
				} else if (node.getLocalName().equals("line-break")) {
					nodeLength = 1;
				} else if (node.getLocalName().equals("tab")) {
					nodeLength = 1;
				} else {
					nodeLength = TextExtractor.getText((OdfElement) node).length();
				}
			}
			if (nodeLength <= fromIndex) {
				fromIndex -= nodeLength;
			} else {
				// the start index is in this node
				if (node.getNodeType() == Node.TEXT_NODE) {
					String value = node.getNodeValue();
					node.setNodeValue(value.substring(0, fromIndex));
					int endLength = fromIndex + leftLength;
					int nextLength = value.length() - endLength;

					Node nextNode = node.getNextSibling();
					Node parNode = node.getParentNode();
					// init text:a
					OdfTextSpan textSpan = new OdfTextSpan((OdfFileDom) node.getOwnerDocument());
					Node newNode = null;
					if (nextLength >= 0) {
						textSpan.setTextContent(value.substring(fromIndex, endLength));
						newNode = node.cloneNode(true);
						newNode.setNodeValue(value.substring(endLength, value.length()));
						leftLength = 0;
					} else {
						textSpan.setTextContent(value.substring(fromIndex, value.length()));
						leftLength = endLength - value.length();
					}
					textSpan.setProperties(style.getStyleProperties());

					if (nextNode != null) {
						parNode.insertBefore(textSpan, nextNode);
						if (newNode != null) {
							parNode.insertBefore(newNode, nextNode);
						}
					} else {
						parNode.appendChild(textSpan);
						if (newNode != null) {
							parNode.appendChild(newNode);
						}
					}
					fromIndex = 0;
					if (nextNode != null) {
						node = nextNode;
					} else {
						node = textSpan;
					}

				} else if (node.getNodeType() == Node.ELEMENT_NODE) {
					// if text:s?????????
					// text:s
					if (node.getLocalName().equals("s")) {
						// delete space
						((TextSElement) node).setTextCAttribute(new Integer(nodeLength - fromIndex));
						leftLength = leftLength - (nodeLength - fromIndex);
						fromIndex = 0;

					} else if (node.getLocalName().equals("line-break") || node.getLocalName().equals("tab")) {
						fromIndex = 0;
						leftLength--;
					} else {
						appendStyle(fromIndex, leftLength, node, style);
						int length = (fromIndex + leftLength) - nodeLength;
						leftLength = length > 0 ? length : 0;
						fromIndex = 0;
					}
				}
			}
			node = node.getNextSibling();
		}
	}
}
