/** 
 * @file llui_libtest.cpp
 * @brief Integration test for the LLUI library
 *
 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */
#include "linden_common.h"

#include "llui_libtest.h"

// project includes
#include "llwidgetreg.h"

// linden library includes
#include "llcontrol.h"		// LLControlGroup
#include "lldir.h"
#include "lldiriterator.h"
#include "llerrorcontrol.h"
#include "llfloater.h"
#include "llfontfreetype.h"
#include "llfontgl.h"
#include "lltransutil.h"
#include "llui.h"
#include "lluictrlfactory.h"

#include <iostream>

// *TODO: switch to using TUT
// *TODO: teach Parabuild about this program, run automatically after full builds

// I believe these must be globals, not stack variables.  JC
LLControlGroup gSavedSettings("Global");	// saved at end of session
LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session
LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings

// [RLVa:KB] - Checked: 2010-11-12 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
#include "llavatarname.h"

// Stub for rlvGetAnonym
std::string rlvGetAnonym(const LLAvatarName& avName)
{
	static std::string strAnonym = "A resident";
	return strAnonym;
}
// [/RLVa:KB]

// We can't create LLImageGL objects because we have no window or rendering 
// context.  Provide enough of an LLUIImage to test the LLUI library without
// an underlying image.
class TestUIImage : public LLUIImage
{
public:
	TestUIImage()
	:	LLUIImage( std::string(), NULL ) // NULL ImageGL, don't deref!
	{ }

	/*virtual*/ S32 getWidth() const
	{
		return 16;
	}

	/*virtual*/ S32 getHeight() const
	{
		return 16;
	}
};


class LLTexture ;
// We need to supply dummy images
class TestImageProvider : public LLImageProviderInterface
{
public:
	/*virtual*/ LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority)
	{
		return makeImage();
	}

	/*virtual*/ LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority)
	{
		return makeImage();
	}

	/*virtual*/ void cleanUp()
	{
	}

	LLPointer<LLUIImage> makeImage()
	{
		LLPointer<LLTexture> image_gl;
		LLPointer<LLUIImage> image = new TestUIImage(); //LLUIImage( std::string(), image_gl);
		mImageList.push_back(image);
		return image;
	}
	
public:
	// Unclear if we need this, hold on to one copy of each image we make
	std::vector<LLPointer<LLUIImage> > mImageList;
};
TestImageProvider gTestImageProvider;

void init_llui()
{
	// Font lookup needs directory support
#if LL_DARWIN
	const char* newview_path = "../../../../newview";
#else
	const char* newview_path = "../../../newview";
#endif
	gDirUtilp->initAppDirs("SecondLife", newview_path);
	gDirUtilp->setSkinFolder("default", "en");
	
	// colors are no longer stored in a LLControlGroup file
	LLUIColorTable::instance().loadFromSettings();

	std::string config_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings.xml");
	gSavedSettings.loadFromFile(config_filename);
	
	// See LLAppViewer::init()
	LLUI::settings_map_t settings;
	settings["config"] = &gSavedSettings;
	settings["ignores"] = &gWarningSettings;
	settings["floater"] = &gSavedSettings;
	settings["account"] = &gSavedPerAccountSettings;
	
	// Don't use real images as we don't have a GL context
	LLUI::initClass(settings, &gTestImageProvider);
	
	const bool no_register_widgets = false;
	LLWidgetReg::initClass( no_register_widgets );

	// Otherwise we get translation warnings when setting up floaters
	// (tooltips for buttons)
	std::set<std::string> default_args;
	LLTransUtil::parseStrings("strings.xml", default_args);
	LLTransUtil::parseLanguageStrings("language_settings.xml");
	LLFontManager::initClass();
	
	// Creating widgets apparently requires fonts to be initialized,
	// otherwise it crashes.
	LLFontGL::initClass(96.f, 1.f, 1.f,
						gDirUtilp->getAppRODataDir(),
						"fonts.xml",
						f.0,
						false );	// don't create gl textures
	
	LLFloaterView::Params fvparams;
	fvparams.name("Floater View");
	fvparams.rect( LLRect(0,480,640,0) );
	fvparams.mouse_opaque(false);
	fvparams.follows.flags(FOLLOWS_ALL);
	fvparams.tab_stop(false);
	gFloaterView = LLUICtrlFactory::create<LLFloaterView> (fvparams);
}

/*==========================================================================*|
static std::string get_xui_dir()
{
	std::string delim = gDirUtilp->getDirDelimiter();
	return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim;
}

// buildFromFile() no longer supports generate-output-LLXMLNode
void export_test_floaters()
{
	// Convert all test floaters to new XML format
	std::string delim = gDirUtilp->getDirDelimiter();
	std::string xui_dir = get_xui_dir() + "en" + delim;
	std::string filename;

	LLDirIterator iter(xui_dir, "floater_test_*.xml");
	while (iter.next(filename))
	{
		if (filename.find("_new.xml") != std::string::npos)
		{
			// don't re-export other test floaters
			continue;
		}
		LL_INFOS() << "Converting " << filename << LL_ENDL;
		// Build a floater and output new attributes
		LLXMLNodePtr output_node = new LLXMLNode();
		LLFloater* floater = new LLFloater(LLSD());
		floater->buildFromFile(	filename,
								//	 FALSE,	// don't open floater
								output_node);
		std::string out_filename = gDirUtilp->add(xui_dir, filename);
		std::string::size_type extension_pos = out_filename.rfind(".xml");
		out_filename.resize(extension_pos);
		out_filename += "_new.xml";
		
		LL_INFOS() << "Output: " << out_filename << LL_ENDL;
		LLFILE* floater_file = LLFile::fopen(out_filename.c_str(), "w");
		LLXMLNode::writeHeaderToFile(floater_file);
		output_node->writeToFile(floater_file);
		fclose(floater_file);
	}
}
|*==========================================================================*/

int main(int argc, char** argv)
{
	// Must init LLError for llerrs to actually cause errors.
	LLError::initForApplication(".");

	init_llui();
	
//	export_test_floaters();
	
	return 0;
}
