package com.mxgraph.io.vdx;

import java.util.HashMap;
import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * This class allows get the text contained in a shape formated with tags html.<br/>
 * The properties referenced in the Text element are processed by this class.
 */
public class mxVdxTextParser
{
	/**
	 * Shape that contains the text.
	 */
	mxVdxShape shape;

	/**
	 * Master Shape of the shape.
	 */
	mxMasterShape masterShape;

	/**
	 * Stylesheet with the Text Style.
	 */
	mxStyleSheet styleSheet;

	/**
	 * Stylesheet with the default text style.
	 */
	mxStyleSheet defaultStyle;

	/**
	 * Last cp's IX referenced in the Text Element.
	 */
	String cp = "";

	/**
	 * Last pp's IX referenced in the Text Element.
	 */
	String pp = "";

	/**
	 * Last tp's IX referenced in the Text Element.
	 */
	String tp = "";

	/**
	 * Last fld's IX referenced in the Text Element.
	 */
	String fld = "";

	/**
	 * Creates a new instance of mxVdxTextParser.
	 * @param shape Shape that contains the text.
	 * @param masterShape Master Shape of the shape.
	 * @param styleSheet Stylesheet with the Text Style. 
	 */
	public mxVdxTextParser(mxVdxShape shape, mxMasterShape masterShape,
			mxStyleSheet styleSheet)
	{
		this.shape = shape;
		this.masterShape = masterShape;
		this.styleSheet = styleSheet;
		this.defaultStyle = mxPropertiesManager.getInstance().getTextStyle();
	}

	/**
	 * Returns the text contained in the shape formated with tags html.<br/>
	 * @return Text content in html.
	 */
	public String getHtmlTextContent()
	{
		List<Node> child = null;
		String ret = "";
		if (shape.hasText())
		{
			child = shape.getTextChildrens();
		}
		else if ((masterShape != null) && masterShape.hasText())
		{
			child = masterShape.getTextChildrens();
		}
		boolean first = true;
		if (child != null)
		{
			for (Node e : child)
			{
				if (e.getNodeName().equals("cp"))
				{
					Element elem = (Element) e;
					cp = elem.getAttribute("IX");
				}
				else if (e.getNodeName().equals("tp"))
				{
					Element elem = (Element) e;
					tp = elem.getAttribute("IX");
				}
				else if (e.getNodeName().equals("pp"))
				{
					Element elem = (Element) e;
					pp = elem.getAttribute("IX");
					if (first)
					{
						first = false;
					}
					else
					{
						ret += "</p>";
					}
					String para = "<p>";
					ret += getTextParagraphFormated(para);
				}
				else if (e.getNodeName().equals("fld"))
				{
					Element elem = (Element) e;
					fld = elem.getAttribute("IX");
					String text = elem.getTextContent();
					text = textToList(text, pp);
					text = text.replaceAll("\n", "<br/>");
					ret += getTextCharFormated(text);
				}
				else if (e.getNodeName().equals("#text"))
				{
					String text = e.getNodeValue();
					text = textToList(text, pp);
					text = text.replaceAll("\n", "<br/>");
					ret += getTextCharFormated(text);

				}
			}
		}
		String end = first ? "" : "</p>";
		ret += end;
		if (!shape.hasXForm1D())
		{
			ret = mxVdxUtils.surroundedByTags(ret, "div");
			HashMap<String, Object> styleMap = new HashMap<String, Object>();
			styleMap.put("width", shape.getDimentions().getX() * 0.71 + "px");
			styleMap.put("max-width", shape.getDimentions().getX() * 0.71
					+ "px");
			ret = insertAttributes(ret, styleMap);
		}
		return ret;
	}

	/**
	 * Transform plain text into a html list if the Para element referenced by
	 * pp indicates it.
	 * @param text Text to be transformed.
	 * @param pp Reference to a Para element.
	 * @return Text like a html list.
	 */
	public String textToList(String text, String pp)
	{
		if (!pp.equals(""))
		{
			String bullet = getBulletValue(pp);
			if (!bullet.equals("0"))
			{
				String[] entries = text.split("\n");
				String ret = "";
				for (String entry : entries)
				{
					ret += mxVdxUtils.surroundedByTags(entry, "li");
				}
				ret = mxVdxUtils.surroundedByTags(ret, "ul");
				HashMap<String, Object> styleMap = new HashMap<String, Object>();
				if (bullet.equals("4"))
				{
					styleMap.put("list-style-type", "square");
				}
				else
				{
					styleMap.put("list-style-type", "disc");
				}
				ret = this.insertAttributes(ret, styleMap);
				return ret;
			}
		}
		return text;
	}

	/**
	 * Returns the value of the Bullet element of the shape.<br/>
	 * This element may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the Bullet element.
	 * @return String value of the Bullet element.
	 */
	public String getBulletValue(String index)
	{
		String bullet = "0";
		if (shape.hasBullet(index))
		{
			bullet = shape.getBullet(index);
		}
		else if (masterShape != null && masterShape.hasBullet(index))
		{
			bullet = masterShape.getBullet(index);
		}
		else if (styleSheet != null && styleSheet.hasBullet(index))
		{
			bullet = styleSheet.getBullet(index);
		}
		else if (defaultStyle != null && defaultStyle.hasBullet(index))
		{
			bullet = defaultStyle.getBullet(index);
		}
		return bullet;
	}

	/**
	 * Returns the paragraph formated according the properties in the last
	 * Para element referenced.
	 * @param para Paragraph to be formated
	 * @return Formated paragraph.
	 */
	public String getTextParagraphFormated(String para)
	{
		String ret = "";
		HashMap<String, Object> styleMap = new HashMap<String, Object>();

		styleMap.put("text-align", getHorzAlign(pp));
		styleMap.put("text-indent", getIndFirst(pp));
		styleMap.put("margin-left", getIndLeft(pp));
		styleMap.put("margin-right", getIndRight(pp));
		styleMap.put("margin-top", getSpcBefore(pp) + "px");
		styleMap.put("margin-bottom", getSpcAfter(pp) + "px");
		styleMap.put("line-height", getSpcLine(pp));
		styleMap.put("direction", getTextDirection(pp));
		ret += insertAttributes(para, styleMap);
		return ret;
	}

	/**
	 * Returns the direction of the text. It may be right to left or left to right.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the Flags element.
	 * @return The direction of the text.
	 */
	public String getTextDirection(String index)
	{
		String direction = "ltr";
		if (shape.hasFlags(index))
		{
			direction = shape.getFlags(index);
		}
		else if (masterShape != null && masterShape.hasFlags(index))
		{
			direction = masterShape.getFlags(index);
		}
		else if (styleSheet != null && styleSheet.hasFlags(index))
		{
			direction = styleSheet.getFlags(index);
		}
		else if (defaultStyle != null && defaultStyle.hasFlags(index))
		{
			direction = defaultStyle.getFlags(index);
		}
		if (direction.equals("0"))
		{
			direction = "ltr";
		}
		else if (direction.equals("1"))
		{
			direction = "rtl";
		}
		return direction;
	}

	/**
	 * Returns the space between lines in a paragraph.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the SpLine element.
	 * @return The space between lines n pixels.
	 */
	public String getSpcLine(String index)
	{
		String ret = "0";
		boolean isPercent = false;
		double space = 0;
		if (shape.hasSpLine(index))
		{
			space = shape.getSpLine(index);
		}
		else if (masterShape != null && masterShape.hasSpLine(index))
		{
			space = masterShape.getSpLine(index);
		}
		else if (styleSheet != null && styleSheet.hasSpLine(index))
		{
			space = styleSheet.getSpLine(index);
		}
		else if (defaultStyle != null && defaultStyle.hasSpLine(index))
		{
			space = defaultStyle.getSpLine(index);
		}
		if (space > 0)
		{
			space = space * mxVdxUtils.conversionFactor();
		}
		else if (space == 0)
		{
			space = 100;
			isPercent = true;
		}
		else
		{
			space = Math.abs(space) * 100;
			isPercent = true;
		}
		ret = String.valueOf(space);
		ret += isPercent ? "%" : "px";
		return ret;
	}

	/**
	 * Returns the space before a paragraph.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the SpBefore element.
	 * @return The space before the paragraph in pixels.
	 */
	public String getSpcBefore(String index)
	{
		String ret = "0";

		if (shape.hasSpBefore(index))
		{
			ret = shape.getSpBefore(index);
		}
		else if (masterShape != null && masterShape.hasSpBefore(index))
		{
			ret = masterShape.getSpBefore(index);
		}
		else if (styleSheet != null && styleSheet.hasSpBefore(index))
		{
			ret = styleSheet.getSpBefore(index);
		}
		else if (defaultStyle != null && defaultStyle.hasSpBefore(index))
		{
			ret = defaultStyle.getSpBefore(index);
		}

		return ret;
	}

	/**
	 * Returns the space after a paragraph.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the SpAfter element.
	 * @return The space after the paragraph in pixels.
	 */
	public String getSpcAfter(String index)
	{
		String ret = "0";

		if (shape.hasSpAfter(index))
		{
			ret = shape.getSpAfter(index);
		}
		else if (masterShape != null && masterShape.hasSpAfter(index))
		{
			ret = masterShape.getSpAfter(index);
		}
		else if (styleSheet != null && styleSheet.hasSpAfter(index))
		{
			ret = styleSheet.getSpAfter(index);
		}
		else if (defaultStyle != null && defaultStyle.hasSpAfter(index))
		{
			ret = defaultStyle.getSpAfter(index);
		}

		return ret;
	}

	/**
	 * Returns the indent to left in a paragraph.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the IndLeft element.
	 * @return The indent to left in a paragraph in pixels.
	 */
	public String getIndLeft(String index)
	{
		String ret = "0";

		if (shape.hasIndentLeft(index))
		{
			ret = shape.getIndentLeft(index);
		}
		else if (masterShape != null && masterShape.hasIndentLeft(index))
		{
			ret = masterShape.getIndentLeft(index);
		}
		else if (styleSheet != null && styleSheet.hasIndentLeft(index))
		{
			ret = styleSheet.getIndentLeft(index);
		}
		else if (defaultStyle != null && defaultStyle.hasIndentLeft(index))
		{
			ret = defaultStyle.getIndentLeft(index);
		}

		return ret;
	}

	/**
	 * Returns the indent to right in a paragraph.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the IndRight element.
	 * @return The indent to right in a paragraph in pixels.
	 */
	public String getIndRight(String index)
	{
		String ret = "0";

		if (shape.hasIndentRight(index))
		{
			ret = shape.getIndentRight(index);
		}
		else if (masterShape != null && masterShape.hasIndentRight(index))
		{
			ret = masterShape.getIndentRight(index);
		}
		else if (styleSheet != null && styleSheet.hasIndentRight(index))
		{
			ret = styleSheet.getIndentRight(index);
		}
		else if (defaultStyle != null && defaultStyle.hasIndentRight(index))
		{
			ret = defaultStyle.getIndentRight(index);
		}

		return ret;
	}

	/**
	 * Returns the indent of the first line in a paragraph.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the IndFirst element.
	 * @return The indent of the first line in a paragraph in pixels.
	 */
	public String getIndFirst(String index)
	{
		String ret = "0";

		if (shape.hasIndentFirst(index))
		{
			ret = shape.getIndentFirst(index);
		}
		else if (masterShape != null && masterShape.hasIndentFirst(index))
		{
			ret = masterShape.getIndentFirst(index);
		}
		else if (styleSheet != null && styleSheet.hasIndentFirst(index))
		{
			ret = styleSheet.getIndentFirst(index);
		}
		else if (defaultStyle != null && defaultStyle.hasIndentFirst(index))
		{
			ret = defaultStyle.getIndentFirst(index);
		}
		return ret;
	}

	/**
	 * Return the value of the horizontal align.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Para element that contains the HorzAlign element.
	 * @return The value of the horizontal align in a paragraph.
	 */
	public String getHorzAlign(String index)
	{
		String ret = "center";
		int align = 0;
		if (shape.hasHorizontalAlign(index))
		{
			align = shape.getHorizontalAlign(index);
		}
		else if (masterShape != null && masterShape.hasHorizontalAlign(index))
		{
			align = masterShape.getHorizontalAlign(index);
		}
		else if (styleSheet != null && styleSheet.hasHorizontalAlign(index))
		{
			align = styleSheet.getHorizontalAlign(index);
		}
		else if (defaultStyle != null && defaultStyle.hasHorizontalAlign(index))
		{
			align = defaultStyle.getHorizontalAlign(index);
		}
		switch (align)
		{
			case 0:
				ret = "left";
				break;
			case 1:
				ret = "center";
				break;
			case 2:
				ret = "right";
				break;
			case 3:
				ret = "justify";
		}
		return ret;
	}

	/**
	 * Inserts the style attributes contained in attr into the text.<br/>
	 * The text must be surrounded by tags html.
	 * @param text Text where the attributes must be inserted.
	 * @param attr Map with the attributes.
	 * @return Text with the attributes applied like style.
	 */
	public String insertAttributes(String text, HashMap<String, Object> attr)
	{
		int i = text.indexOf(">");
		String tail = text.substring(i);
		String head = text.substring(0, i);
		String style = " style=\"" + mxVdxUtils.getStyleString(attr, ":")
				+ "\"";
		return head + style + tail;
	}

	/**
	 * Returns the text formated according the properties in the last
	 * Char element referenced.
	 * @param text Text to be formated
	 * @return Formated text.
	 */
	public String getTextCharFormated(String text)
	{
		String ret = "";
		String color = "color:" + this.getTextColor(cp) + ";";
		String size = "font-size:" + this.getTextSize(cp) + "px;";
		String font = "font-family:" + this.getTextFont(cp) + ";";
		String direction = "direction:" + this.getCharDirection(cp) + ";";
		String space = "letter-spacing:" + this.getCharSpace(cp) + "px;";
		int pos = this.getPos(cp);
		boolean bold = this.isBold(cp);
		boolean italic = this.isItalic(cp);
		boolean underline = this.isUnderline(cp);
		boolean strike = this.isStrikeThru(cp);
		boolean smallCap = this.isSmallCaps(cp);
		int tCase = this.getCase(cp);

		if (tCase == 1)
		{
			text = text.toUpperCase();
		}
		else if (tCase == 2)
		{
			text = mxVdxUtils.toInitialCapital(text);
		}
		if (smallCap)
		{
			text = mxVdxUtils.toSmallCaps(text, this.getTextSize(cp));
		}

		if (pos == 1)
		{
			text = mxVdxUtils.surroundedByTags(text, "sup");
		}
		else if (pos == 2)
		{
			text = mxVdxUtils.surroundedByTags(text, "sub");
		}
		if (bold)
		{
			text = mxVdxUtils.surroundedByTags(text, "b");
		}
		if (italic)
		{
			text = mxVdxUtils.surroundedByTags(text, "i");
		}
		if (underline)
		{
			text = mxVdxUtils.surroundedByTags(text, "u");
		}
		if (strike)
		{
			text = mxVdxUtils.surroundedByTags(text, "s");
		}

		ret += "<font style=\"" + size + font + color + direction + space
				+ "\">" + text + "</font>";
		return ret;
	}

	/**
	 * Returns the space between characters.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the LetterSpace element.
	 * @return String representation of the space between characters in pixels.
	 */
	public String getCharSpace(String index)
	{
		String space = "0";
		if (shape.hasLetterSpace(index))
		{
			space = shape.getLetterSpace(index);
		}
		else if (masterShape != null && masterShape.hasLetterSpace(index))
		{
			space = masterShape.getLetterSpace(index);
		}
		else if (styleSheet != null && styleSheet.hasLetterSpace(index))
		{
			space = styleSheet.getLetterSpace(index);
		}
		else if (defaultStyle != null && defaultStyle.hasLetterSpace(index))
		{
			space = defaultStyle.getLetterSpace(index);
		}
		return space;
	}

	/**
	 * Returns the direction of the text. It may be right to left or left to right.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the RTLText element.
	 * @return Direction of the text.
	 */
	public String getCharDirection(String index)
	{
		String direction = "ltr";
		if (shape.hasRTLText(index))
		{
			direction = shape.getRTLText(index);
		}
		else if (masterShape != null && masterShape.hasRTLText(index))
		{
			direction = masterShape.getRTLText(index);
		}
		else if (styleSheet != null && styleSheet.hasRTLText(index))
		{
			direction = styleSheet.getRTLText(index);
		}
		else if (defaultStyle != null && defaultStyle.hasRTLText(index))
		{
			direction = defaultStyle.getRTLText(index);
		}
		if (direction.equals("0"))
		{
			direction = "ltr";
		}
		else if (direction.equals("1"))
		{
			direction = "rtl";
		}
		return direction;
	}

	/**
	 * Returns the value of the case property.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Case element.
	 * @return  Value of the case property.
	 */
	public int getCase(String index)
	{
		int tCase = 0;
		if (shape.hasTextStyle(index))
		{
			tCase = shape.getTextCase(index);
		}
		else if (masterShape != null && masterShape.hasTextCase(index))
		{
			tCase = masterShape.getTextCase(index);
		}
		else if (styleSheet != null && styleSheet.hasTextCase(index))
		{
			tCase = styleSheet.getTextCase(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextCase(index))
		{
			tCase = defaultStyle.getTextCase(index);
		}
		return tCase;
	}

	/**
	 * Returns the Position of the text(If is superscript, subscript or normal text).<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Pos element.
	 * @return Value of the Pos element.
	 */
	public int getPos(String index)
	{
		int pos = 0;
		if (shape.hasTextPos(index))
		{
			pos = shape.getTextPos(index);
		}
		else if (masterShape != null && masterShape.hasTextPos(index))
		{
			pos = masterShape.getTextPos(index);
		}
		else if (styleSheet != null && styleSheet.hasTextPos(index))
		{
			pos = styleSheet.getTextPos(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextPos(index))
		{
			pos = defaultStyle.getTextPos(index);
		}
		return pos;
	}

	/**
	 * Checks if the style property of the Char element of index = 'index' 
	 * indicates bold.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Style element.
	 * @return Returns <code>true</code> if the style property of the Char element of 
	 * index = 'index' indicates bold.
	 */
	public boolean isBold(String index)
	{
		boolean isBold = false;
		String style = "";
		if (shape.hasTextStyle(index))
		{
			style = shape.getTextStyle(index);
		}
		else if (masterShape != null && masterShape.hasTextStyle(index))
		{
			style = masterShape.getTextStyle(index);
		}
		else if (styleSheet != null && styleSheet.hasTextStyle(index))
		{
			style = styleSheet.getTextStyle(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextStyle(index))
		{
			style = defaultStyle.getTextStyle(index);
		}
		if (!style.equals(""))
		{
			int value = Integer.parseInt(style);
			isBold = ((value & 1) == 1);
		}
		return isBold;
	}

	/**
	 * Checks if the style property of the Char element of index = 'index' 
	 * indicates italic.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Style element.
	 * @return Returns <code>true</code> if the style property of the Char element of 
	 * index = 'index' indicates italic.
	 */
	public boolean isItalic(String index)
	{
		boolean isItalic = false;
		String style = "";
		if (shape.hasTextStyle(index))
		{
			style = shape.getTextStyle(index);
		}
		else if (masterShape != null && masterShape.hasTextStyle(index))
		{
			style = masterShape.getTextStyle(index);
		}
		else if (styleSheet != null && styleSheet.hasTextStyle(index))
		{
			style = styleSheet.getTextStyle(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextStyle(index))
		{
			style = defaultStyle.getTextStyle(index);
		}
		if (!style.equals(""))
		{
			int value = Integer.parseInt(style);
			isItalic = ((value & 2) == 2);
		}
		return isItalic;
	}

	/**
	 * Checks if the style property of the Char element of index = 'index' 
	 * indicates underline.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Style element.
	 * @return Returns <code>true</code> if the style property of the Char element of 
	 * index = 'index' indicates underline.
	 */
	public boolean isUnderline(String index)
	{
		boolean isUnderline = false;
		String style = "";
		if (shape.hasTextStyle(index))
		{
			style = shape.getTextStyle(index);
		}
		else if (masterShape != null && masterShape.hasTextStyle(index))
		{
			style = masterShape.getTextStyle(index);
		}
		else if (styleSheet != null && styleSheet.hasTextStyle(index))
		{
			style = styleSheet.getTextStyle(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextStyle(index))
		{
			style = defaultStyle.getTextStyle(index);
		}
		if (!style.equals(""))
		{
			int value = Integer.parseInt(style);
			isUnderline = ((value & 4) == 4);
		}
		return isUnderline;
	}

	/**
	 * Checks if the style property of the Char element of index = 'index'
	 * indicates small caps.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Style element.
	 * @return Returns <code>true</code> if the style property of the Char element of
	 * index = 'index' indicates small caps.
	 */
	public boolean isSmallCaps(String index)
	{
		boolean isSmallCaps = false;
		String style = "";
		if (shape.hasTextStyle(index))
		{
			style = shape.getTextStyle(index);
		}
		else if (masterShape != null && masterShape.hasTextStyle(index))
		{
			style = masterShape.getTextStyle(index);
		}
		else if (styleSheet != null && styleSheet.hasTextStyle(index))
		{
			style = styleSheet.getTextStyle(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextStyle(index))
		{
			style = defaultStyle.getTextStyle(index);
		}
		if (!style.equals(""))
		{
			int value = Integer.parseInt(style);
			isSmallCaps = ((value & 8) == 8);
		}
		return isSmallCaps;
	}

	/**
	 * Checks if the strikethru property of the Char element of index = 'index'
	 * indicates true.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the StrikeThru element.
	 * @return Returns <code>true</code> if the strikethru property of the Char
	 * element of index = 'index' indicates true.
	 */
	public boolean isStrikeThru(String index)
	{
		boolean isStrikeThru = false;
		if (shape.hasTextStrike(index))
		{
			isStrikeThru = shape.getTextStrike(index);
		}
		else if (masterShape != null && masterShape.hasTextStrike(index))
		{
			isStrikeThru = masterShape.getTextStrike(index);
		}
		else if (styleSheet != null && styleSheet.hasTextStrike(index))
		{
			isStrikeThru = styleSheet.getTextStrike(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextStrike(index))
		{
			isStrikeThru = defaultStyle.getTextStrike(index);
		}
		return isStrikeThru;
	}

	/**
	 * Returns the actual font defined by the Char element referenced in cp.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Font element.
	 * @return Returns the name of the font.
	 */
	public String getTextFont(String index)
	{
		String font = "";
		if (shape.hasTextFont(index))
		{
			font = shape.getTextFont(index);
		}
		else if (masterShape != null && masterShape.hasTextFont(index))
		{
			font = masterShape.getTextFont(index);
		}
		else if (styleSheet != null && styleSheet.hasTextFont(index))
		{
			font = styleSheet.getTextFont(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextFont(index))
		{
			font = defaultStyle.getTextFont(index);
		}
		return font;
	}

	/**
	 * Returns the actual text size defined by the Char element referenced in cp.<br/>
	 * This property may to be founded in the shape, master shape, stylesheet or
	 * default stylesheet.
	 * @param index Index of the Char element that contains the Size element.
	 * @return Returns the size of the font in pixels.
	 */
	private String getTextSize(String index)
	{
		String size = "12";
		if (shape.hasTextSize(index))
		{
			size = shape.getTextSize(index);
		}
		else if (masterShape != null && masterShape.hasTextSize(index))
		{
			size = masterShape.getTextSize(index);
		}
		else if (styleSheet != null && styleSheet.hasTextSize(index))
		{
			size = styleSheet.getTextSize(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextSize(index))
		{
			size = defaultStyle.getTextSize(index);
		}
		double s = Double.valueOf(size) * 0.71;
		return String.valueOf(s);
	}

	/**
	* Returns the actual color defined by the Char element referenced in cp.<br/>
	* This property may to be founded in the shape, master shape, stylesheet or
	* default stylesheet.
	* @param index Index of the Char element that contains the Color element.
	* @return Returns the color of the text in hexadecimal.
	*/
	private String getTextColor(String index)
	{
		String color = "#000000";
		if (shape.hasTextColor(index))
		{
			color = shape.getTextColor(index);
		}
		else if (masterShape != null && masterShape.hasTextColor(index))
		{
			color = masterShape.getTextColor(index);
		}
		else if (styleSheet != null && styleSheet.hasTextColor(index))
		{
			color = styleSheet.getTextColor(index);
		}
		else if (defaultStyle != null && defaultStyle.hasTextColor(index))
		{
			color = defaultStyle.getTextColor(index);
		}
		return color;
	}
}
