/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
package org.cocos2d.label_nodes;

import org.cocos2d.cocoa.CCGeometry.CCRect;
import org.cocos2d.cocoa.CCGeometry.CCSize;
import org.cocos2d.include.CCProtocols.CCLabelProtocol;
import org.cocos2d.include.ccConfig;
import org.cocos2d.include.ccMacros;
import org.cocos2d.include.ccTypes.CCTextAlignment;
import org.cocos2d.include.ccTypes.CCVerticalTextAlignment;
import org.cocos2d.nodes.CCSprite;
import org.cocos2d.shaders.CCGLProgram;
import org.cocos2d.shaders.CCShaderCache;
import org.cocos2d.textures.CCTexture2D;
import org.cocos2d.utils.CCFormatter;

/**
 * @addtogroup GUI
 * @{
 * @addtogroup label
 * @{
 */

/** @brief CCLabelTTF is a subclass of CCTextureNode that knows how to render text labels
*
* All features from CCTextureNode are valid in CCLabelTTF
*
* CCLabelTTF objects are slow. Consider using CCLabelAtlas or CCLabelBMFont instead.
*/
public class CCLabelTTF extends CCSprite implements CCLabelProtocol {

	public CCLabelTTF() {
		m_hAlignment = CCTextAlignment.kCCTextAlignmentCenter;
		m_vAlignment = CCVerticalTextAlignment.kCCVerticalTextAlignmentTop;
		m_pFontName = null;
		m_fFontSize = 0.0f;
		m_string = "";
	}

	@Override
	public String description() {
		return CCFormatter.format("<CCLabelTTF | FontName = %s, FontSize = %.1f>", m_pFontName, m_fFontSize);
	}

	/** creates a CCLabelTTF with a font name and font size in points
	 * @since v2.0.1
	 */
	public static CCLabelTTF create(final String string, final String fontName, float fontSize) {
		return CCLabelTTF.create(string, fontName, fontSize,
				CCSize.Zero, CCTextAlignment.kCCTextAlignmentCenter, CCVerticalTextAlignment.kCCVerticalTextAlignmentTop);
	}

	/** creates a CCLabelTTF from a fontname, horizontal alignment, dimension in points,  and font size in points.
	 * @since v2.0.1
	 */
	public static CCLabelTTF create(final String string, final String fontName, float fontSize,
			final CCSize dimensions, CCTextAlignment hAlignment) {
		return CCLabelTTF.create(string, fontName, fontSize, dimensions, hAlignment, CCVerticalTextAlignment.kCCVerticalTextAlignmentTop);
	}

	/** creates a CCLabel from a fontname, alignment, dimension in points and font size in points
	 * @since v2.0.1
	 */
	public static CCLabelTTF create(final String string, final String fontName, float fontSize,
			final CCSize dimensions, CCTextAlignment hAlignment, 
			CCVerticalTextAlignment vAlignment) {
		CCLabelTTF pRet = new CCLabelTTF();
		if(pRet != null && pRet.initWithString(string, fontName, fontSize, dimensions, hAlignment, vAlignment)) {
			return pRet;
		}
		pRet = null;
		return null;
	}

	/** initializes the CCLabelTTF with a font name and font size */
	public boolean initWithString(final String label, final String fontName, float fontSize) {
		return this.initWithString(label, fontName, fontSize, 
				CCSize.Zero, CCTextAlignment.kCCTextAlignmentLeft, CCVerticalTextAlignment.kCCVerticalTextAlignmentTop);
	}

	/** initializes the CCLabelTTF with a font name, alignment, dimension and font size */
	public boolean initWithString(final String label, final String fontName, float fontSize,
			final CCSize dimensions, CCTextAlignment alignment) {
		return this.initWithString(label, fontName, fontSize, dimensions, alignment, CCVerticalTextAlignment.kCCVerticalTextAlignmentTop);
	}

	/** initializes the CCLabelTTF with a font name, alignment, dimension and font size */
	public boolean initWithString(final String string, final String fontName, float fontSize,
			final CCSize dimensions, CCTextAlignment hAlignment, 
			CCVerticalTextAlignment vAlignment) {
		if (super.init()) {
			// shader program
			this.setShaderProgram(CCShaderCache.sharedShaderCache().programForKey(SHADER_PROGRAM));

			m_tDimensions.setSize(dimensions);
			m_hAlignment = hAlignment;
			m_vAlignment = vAlignment;
			m_pFontName = new String(fontName);
			m_fFontSize = fontSize;

			this.setString(string);

			return true;
		}

		return false;
	}

	/** initializes the CCLabelTTF */
	@Override
	public boolean init() {
		return this.initWithString("", "Helvetica", 12);
	}

	/** Creates an label.
	 */
	public static CCLabelTTF create() {
		CCLabelTTF pRet = new CCLabelTTF();
		if (pRet != null && pRet.init()) {
		} else {
			pRet = null;
		}
		return pRet;
	}

	/** changes the string to render
	 * @warning Changing the string is as expensive as creating a new CCLabelTTF. To obtain better performance use CCLabelAtlas
	 */
	@Override
	public void setString(final String string) {
		ccMacros.CCAssert(string != null, "Invalid string");

		if (m_string.compareTo(string) != 0) {
			m_string = string;

			this.updateTexture();
		}
	}

	@Override
	public String getString() {
		return m_string;
	}

	public CCTextAlignment getHorizontalAlignment() {
		return m_hAlignment;
	}

	public void setHorizontalAlignment(CCTextAlignment alignment) {
		if (alignment != m_hAlignment) {
			m_hAlignment = alignment;

			// Force update
			if (m_string.length() > 0) {
				this.updateTexture();
			}
		}
	}

	public CCVerticalTextAlignment getVerticalAlignment() {
		return m_vAlignment;
	}

	public void setVerticalAlignment(CCVerticalTextAlignment verticalAlignment) {
		if (verticalAlignment != m_vAlignment) {
			m_vAlignment = verticalAlignment;

			// Force update
			if (m_string.length() > 0) {
				this.updateTexture();
			}
		}
	}

	public CCSize getDimensions() {
		return m_tDimensions;
	}

	public void setDimensions(final CCSize dim) {
		if (dim.width != m_tDimensions.width || dim.height != m_tDimensions.height) {
			m_tDimensions.setSize(dim);

			// Force update
			if (m_string.length() > 0) {
				this.updateTexture();
			}
		}
	}

	public float getFontSize() {
		return m_fFontSize;
	}

	public void setFontSize(float fontSize) {
		if (m_fFontSize != fontSize) {
			m_fFontSize = fontSize;

			// Force update
			if (m_string.length() > 0) {
				this.updateTexture();
			}
		}
	}

	public String getFontName() {
		return m_pFontName;
	}

	public void setFontName(final String fontName) {
		if (m_pFontName.compareTo(fontName)!= 0) {
			m_pFontName = new String(fontName);

			// Force update
			if (m_string.length() > 0) {
				this.updateTexture();
			}
		}
	}

	private boolean updateTexture() {
		CCTexture2D tex;

		// let system compute label's width or height when its value is 0
		// refer to cocos2d-x issue #1430
		tex = new CCTexture2D();

		tex.initWithString( m_string,
							m_pFontName,
							m_fFontSize * ccMacros.CC_CONTENT_SCALE_FACTOR(),
							ccMacros.CC_SIZE_POINTS_TO_PIXELS(m_tDimensions), 
							m_hAlignment,
							m_vAlignment);

		this.setTexture(tex);

		CCRect rect = new CCRect();
		rect.size = m_pobTexture.getContentSize();
		this.setTextureRect(rect);

		return true;
	}

	/** Dimensions of the label in Points */
	protected CCSize m_tDimensions = new CCSize();

	/** The alignment of the label */
	protected CCTextAlignment m_hAlignment;

	/** The vertical alignment of the label */
	protected CCVerticalTextAlignment m_vAlignment;

	/** Font name used in the label */
	protected String m_pFontName;

	/** Font size of the label */
	protected float m_fFontSize;

	protected String m_string;

	@SuppressWarnings("unused")
	private static final String SHADER_PROGRAM = (ccConfig.CC_USE_LA88_LABELS != 0) ? CCGLProgram.kCCShader_PositionTextureColor : CCGLProgram.kCCShader_PositionTextureA8Color;
}

// end of GUI group
/// @}
/// @}
