/**
 * Returns 1 (true) if the font object type 1 passed as a parameter
 * exists and is added successfully to the manager loading the font directly from
 * ::IND_Image object and a configuration file, both generated with MudFont
 * (modified version for IndieLib can be found in the section tools).
 *
 * The posibility of changing the font from an ::IND_Image object is offered in case
 * that you want to change the original font with any modification or filter from
 * ::IND_ImageManager.
 *
 * @param pNewFont					Pointer to a new object type 1 font.
 * @param pImage					Pointer to an object ::IND_Image that contains a previously loaded font from a graphic file generated by MudFont (see tools section).
 * @param pFile						Name of the configuration file of the font generated by MudFont (see tools section).
 * @param pType						Font type (see ::IND_Type).
 * @param pQuality					Font quality (see ::IND_Quality).
 */
bool IND_FontManager::addMudFont(IND_Font		*pNewFont,
                                 IND_Image		*pImage,
                                 const char     *pFile,
                                 IND_Type		pType,
                                 IND_Quality	pQuality) {
	g_debug->header("Parsing and loading MudFont font", DebugApi::LogHeaderBegin);
	g_debug->header("File name:", DebugApi::LogHeaderInfo);
	g_debug->dataChar(pFile, 1);

	if (!_ok) {
		writeMessage();
		return 0;
	}

	// ----- Width and height of the bitmap font MUST be power of two -----

	IND_Math mMath;

	if (!mMath.isPowerOfTwo(pImage->getWidth()) ||
	        !mMath.isPowerOfTwo(pImage->getHeight())) {
		g_debug->header("This operation can not be done", DebugApi::LogHeaderInfo);
		g_debug->dataChar("", 1);
		g_debug->header("The height and width of the MudFont font must be power of 2", DebugApi::LogHeaderError);
		return 0;
	}
    
    // ----- XML font parsing -----
    
	if (!parseMudFont(pNewFont, pFile)) {
		g_debug->header("Fatal error, cannot load the MudFont font xml file", DebugApi::LogHeaderError);
		return 0;
	}
    
	pNewFont->setFileName(pFile);

	// ----- Bitmap (IND_Surface object) creation -----

	IND_Surface *mNewSurface = IND_Surface::newSurface();
	if (!_surfaceManager->add(mNewSurface, pImage, pType, pQuality))
		return 0;

	// IND_Surface object MUST have one block ONLY
	if (mNewSurface->getNumBlocks() > 1) {
		_surfaceManager->remove(mNewSurface);
		return 0;
	}

	pNewFont->setSurface(mNewSurface);

	// ----- Puts the object into the manager -----

	addToList(pNewFont);

	// ----- g_debug -----

	g_debug->header("MudFont font parsed and loaded", DebugApi::LogHeaderEnd);

	return 1;
}
/*
 ==================
 Parses an Angelcode
 XML font file
 Uses Tinyxml
 ==================
 */
bool IND_FontManager::parseAngelCodeFont(IND_Font *pNewFont,const char *pFileName, IND_Type pType, IND_Quality pQuality) {
	TiXmlDocument   *mXmlDoc = new TiXmlDocument(pFileName);
    
	// Fatal error, cannot load
	if (!mXmlDoc->LoadFile()) {
        DISPOSE(mXmlDoc);
     	return 0;
    }
    
    // Setting font filename
    pNewFont->setFileName(pFileName);
    
    // Setting the type of the font
    pNewFont->setFontType(IND_Font::FONTTYPE_AngelCode);
    
    
    // Document root
	TiXmlElement *mXFont = 0;
	mXFont = mXmlDoc->FirstChildElement("font");
    
	if (!mXFont) {
		g_debug->header("Invalid name for document root, should be <font>", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
    
    //TODO : info element variables ... maybe
    
    //TODO : common element variables ... maybe
    
    //TODO : pages, this one needs to be done ... MudFont have (allways?) just one page .. Angelcode can have multiple
    
    // Image loading
    
    // Pages element
    TiXmlElement *mXPages = 0;
	mXPages = mXFont->FirstChildElement("pages");
    
    if (!mXPages) {
		g_debug->header("The <font> element doesn't have a <pages> child element", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
    // Page element
	TiXmlElement *mXPage = 0;
	mXPage = mXPages->FirstChildElement("page");
    
	if (!mXPage) {
		g_debug->header("There are no <page> elements to parse", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
	// Parse each page
	int mPageCount = 0;
	while (mXPage) {
        
        // Id
		if (mXPage->Attribute("id")) {
			//pNewFont->getLetters() [mCharCount]._letter = static_cast<unsigned char>(atoi(mXChar->Attribute("id")));  //TODO : FIXME !! id refers to font image, starting from 0 -> 
		} else {
			g_debug->header("The <page> element doesn't have a \"id\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
        // File
        if (mXPage->Attribute("file")) {
            
            IND_Image *mNewImage = IND_Image::newImage();
            bool noImgError = _imageManager->add(mNewImage, mXPage->Attribute("file"));
            if (!noImgError) {
                DISPOSEMANAGED(mNewImage);
                g_debug->header("Failed at adding page image for Angelcode font", DebugApi::LogHeaderError);
                mXmlDoc->Clear();
                delete mXmlDoc;
                return 0;
            }
            
            // ----- Width and height of the bitmap font MUST be power of two -----
            
            IND_Math mMath;
            
            if (!mMath.isPowerOfTwo(mNewImage->getWidth()) ||
                !mMath.isPowerOfTwo(mNewImage->getHeight())) {
                g_debug->header("This operation can not be done", DebugApi::LogHeaderInfo);
                g_debug->dataChar("", 1);
                g_debug->header("The height and width of the AngelCode font font must be power of 2", DebugApi::LogHeaderError);
                mXmlDoc->Clear();
                delete mXmlDoc;
                return 0;
            }
            
            // ----- Bitmap (IND_Surface object) creation -----
            
            IND_Surface *mNewSurface = IND_Surface::newSurface();
            if (!_surfaceManager->add(mNewSurface, mNewImage, pType, pQuality)) {
                mXmlDoc->Clear();
                delete mXmlDoc;
                return 0;
            }   
            
            // IND_Surface object MUST have one block ONLY
            if (mNewSurface->getNumBlocks() > 1) {
                mXmlDoc->Clear();
                delete mXmlDoc;
                _surfaceManager->remove(mNewSurface);
                return 0;
            }
            
            pNewFont->setSurface(mNewSurface); // TODO: somehow handle more than one font surface, - this relates to the "id" attribute parsed..
            
		} else {
			g_debug->header("The <page> element doesn't have a \"file\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
        // Move to the next char declaration
        mXPage = mXPage->NextSiblingElement("page");
        
		mPageCount++;
	
    }
   
   
    // Chars element
    TiXmlElement *mXChars = 0;
	mXChars = mXFont->FirstChildElement("chars");
    
    if (!mXChars) {
		g_debug->header("The <font> element doesn't have a <chars> child element", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
    
    if (mXChars->Attribute("count")) {
		pNewFont->setNumChars(atoi(mXChars->Attribute("count")));
		pNewFont->setLetters(new IND_Font::LETTER [pNewFont->getNumChars()]);
	} else {
		g_debug->header("The <chars> element doesn't have a \"count\" attribute", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
    
    // Char element
	TiXmlElement *mXChar = 0;
	mXChar = mXChars->FirstChildElement("char");
    
	if (!mXChar) {
		g_debug->header("There are no <char> elements to parse", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
	// Parse each char
	int mCharCount = 0;
	while (mXChar) {
		
        // Id
		if (mXChar->Attribute("id")) {
			pNewFont->getLetters() [mCharCount]._letter = static_cast<unsigned char>(atoi(mXChar->Attribute("id")));
		} else {
			g_debug->header("The <char> element doesn't have a \"id\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
		// x
		if (mXChar->Attribute("x")) {
			pNewFont->getLetters() [mCharCount]._x = atoi(mXChar->Attribute("x"));
		} else {
			g_debug->header("The <char> element doesn't have a \"x\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
		// y
		if (mXChar->Attribute("y")) {
			pNewFont->getLetters() [mCharCount]._y = atoi(mXChar->Attribute("y"));
		} else {
			g_debug->header("The <char> element doesn't have a \"y\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
		// width
		if (mXChar->Attribute("width")) {
			pNewFont->getLetters() [mCharCount]._width = atoi(mXChar->Attribute("width"));
		} else {
			g_debug->header("The <char> element doesn't have a \"width\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
		// height
		if (mXChar->Attribute("height")) {
			pNewFont->getLetters() [mCharCount]._height = atoi(mXChar->Attribute("height"));
		} else {
			g_debug->header("The <char> element doesn't have a \"height\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
		// xoffset
		if (mXChar->Attribute("xoffset")) {
			pNewFont->getLetters() [mCharCount]._xOffset = atoi(mXChar->Attribute("xoffset"));
		} else {
			g_debug->header("The char doesn't have a \"xoffset\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}

		// yoffset
		if (mXChar->Attribute("yoffset")) {
			pNewFont->getLetters() [mCharCount]._yOffset = atoi(mXChar->Attribute("yoffset"));
		} else {
			g_debug->header("The <char> element doesn't have a \"yoffset\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
        // xadvance
		if (mXChar->Attribute("xadvance")) {
			pNewFont->getLetters() [mCharCount]._xAdvance = atoi(mXChar->Attribute("xadvance"));
		} else {
			g_debug->header("The <char> element doesn't have a \"xadvance\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}

        // page
		if (mXChar->Attribute("page")) {
			pNewFont->getLetters() [mCharCount]._page = atoi(mXChar->Attribute("page"));
		} else {
			g_debug->header("The <char> element doesn't have a \"page\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
 
        // chnl
		if (mXChar->Attribute("chnl")) {
			pNewFont->getLetters() [mCharCount]._chnl = atoi(mXChar->Attribute("chnl"));
		} else {
			g_debug->header("The <char> element doesn't have a \"chnl\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}

        
		// Move to the next char declaration
		mXChar = mXChar->NextSiblingElement("char");
        
		mCharCount++;
	}
    
    
    
    
    // Kernings element
    TiXmlElement *mXKernings = 0;
	mXKernings = mXFont->FirstChildElement("kernings");
    
    if (!mXKernings) {
		g_debug->header("The <font> element doesn't have a <kernings> child element", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
    
    if (mXKernings->Attribute("count")) {
        pNewFont->setNumKernings(atoi(mXKernings->Attribute("count")));
		pNewFont->setKernings(new IND_Font::KERNING [pNewFont->getNumKernings()]);
	} else {
		g_debug->header("The <kernings> element doesn't have a \"count\" attribute", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
    
    // Kerning element
	TiXmlElement *mXKerning = 0;
	mXKerning = mXKernings->FirstChildElement("kerning");
    
	if (!mXKerning) {
		g_debug->header("There are no <kerning> elements to parse", DebugApi::LogHeaderError);
		mXmlDoc->Clear();
		delete mXmlDoc;
		return 0;
	}
    
	// Parse each kerning
	int mKerCount = 0;
	while (mXKerning) {
		
        // First
		if (mXKerning->Attribute("first")) {
            pNewFont->getKernings()[mKerCount]._first = atoi(mXKerning->Attribute("first"));
		} else {
			g_debug->header("The <kerning> element doesn't have a \"first\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
        // Second
		if (mXKerning->Attribute("second")) {
			pNewFont->getKernings()[mKerCount]._second = atoi(mXKerning->Attribute("second"));
		} else {
			g_debug->header("The <kerning> element doesn't have a \"second\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
                
        // Amount
		if (mXKerning->Attribute("amount")) {
			pNewFont->getKernings()[mKerCount]._amount = atoi(mXKerning->Attribute("amount"));
		} else {
			g_debug->header("The <kerning> element doesn't have a \"second\" attribute", DebugApi::LogHeaderError);
			mXmlDoc->Clear();
			delete mXmlDoc;
			return 0;
		}
        
        // Move to the next kerning declaration
		mXKerning = mXKerning->NextSiblingElement("kerning");
        
		mKerCount++;
	}


    
    
    
	mXmlDoc->Clear();
	delete mXmlDoc;
    
	return 1;
}