Newer
Older
Import / research / ui / TweakableProperties / src / main.cpp
// Project Headers
//#include "Tweakables.h"
#include "Application.h"
#include "Window.h"
#include "Painter.h"
#include "SignalSlot.h"
#include "Widget.h"
#include "Network.h"
#include "MemoryMapping.h"
#include "CommonWidgets.h"
#include "Test.h"
#include "XmlParser.h"
#include "Uibuilder.h"

#include <iostream>
#include <iomanip>
#include <climits>
#include <fstream>
#include <cctype>
#include <cstdarg>


// TODO: doxygen style documentation everywhere


USING_NAMESPACE


#if 0


class MyWindow : public Window
{
public:
	int m_mouseX;
	int m_mouseY;
	MouseButtons m_mouseButtons;
	MouseState  m_mouseState;
	Property<String> m_labelText;
	Label m_label;

	MyWindow(const char* name, const char* file) : Window("Test"), m_labelText(), m_label(this, m_labelText)
	{
		//flags = WF_EraseBackground;
		m_label.setGeometry(100, 100, 200, 200);
		m_label.text = "blah";
		m_label.text = "Label Text";
		//m_label.text.valueChanged.invoke();
//		Variant v(234);
//		m_label.update(v);
	}
	
	void PlotGraph(Painter& p, const char *a_graphTitle, int a_xOff, int a_yOff, int a_width, int a_height)
	{
		p.setPen(0xffffff);
		// Show lines where the cursor is
		if (m_mouseX > a_xOff && m_mouseX < (a_xOff + a_width))
			p.drawLine(m_mouseX, a_yOff, m_mouseX, a_yOff + a_height);
		if (m_mouseY > a_yOff && m_mouseY < (a_yOff + a_height))
			p.drawLine(a_xOff, m_mouseY, a_xOff + a_width, m_mouseY);
	}

	void paintEvent(PaintEvent& a_event)//CUTE_PaintTarget* a_target, int a_mouseX, int a_mouseY, int a_keyState)
	{
		Painter p(this);

		p.setBrush(0x000000);
		p.drawRectangle(0, 0, width(), height());

		// Visualize the mouse
		uint32_t mouseStateColor = 0xff0000; 
										//(m_mouseState == MS_Up) ? 0x00ff00 : (m_mouseState == MS_Down) ? 0xff0000 :
										//(m_mouseState == MS_DoubleClick) ? 0x0000ff : 0x000000;		

		p.setBrush((m_mouseButtons & MB_Left) ? mouseStateColor : 0xffffff);
		p.drawRectangle(10, 10, 20, 20);
		p.setBrush((m_mouseButtons & MB_Middle) ? mouseStateColor : 0xffffff);
		p.drawRectangle(35, 10, 20, 20);
		p.setBrush((m_mouseButtons & MB_Right) ? mouseStateColor : 0xffffff);
		p.drawRectangle(60, 10, 20, 20);

		PlotGraph(p, "Test Chart", 50, 50, width() - 100, height() - 130);
	}

	void keyEvent(KeyEvent& a_event)//int a_keyCode, bool a_keyDown)
	{
	}

	void mouseEvent(MouseEvent& a_event)//int a_x, int a_y, int a_buttonMask, MouseButtons a_mouseButton, MouseState a_mouseState)
	{
		m_mouseX = a_event.m_x;
		m_mouseY = a_event.m_y;
		m_mouseButtons = a_event.m_buttons;
		//m_mouseState = a_event.m_mouseState;
		repaint();
	}
	
	void wheelEvent(WheelEvent& a_event)//int a_x, int a_y, int a_wheelVal)
	{
	}
};



class TestBox : public Widget
{
public:
	TestBox(Widget* a_parent)
		: Widget(a_parent, false, 0, 0, 10, 10)
	{
		m_mouseX = m_mouseY = 0;
		m_color = 0x70525252;
	}

	void sizeOptions(SizeOptions& a_sizeOptions)
	{
		a_sizeOptions.m_minimum.m_width    = 200;
		a_sizeOptions.m_minimum.m_height   = 50;
		a_sizeOptions.m_preferred.m_width  = 280;
		a_sizeOptions.m_preferred.m_height = 256;
		a_sizeOptions.m_maximum.m_width    = 65536;
		a_sizeOptions.m_maximum.m_height   = 5000;
	}

	void paintEvent(PaintEvent& a_event)
	{
		Painter p(this);
		p.setBrush(0x000000);
		p.drawRectangle(0, 0, width() - 10, height());
		p.setBrush(0x888888);
		p.drawRectangle(2, 2, width() - 14, height() - 4);
		p.drawText(3, 3, "X: %i Y: %i", m_mouseX, m_mouseY);

		m_color += 0x101010;
		p.setBrush(m_color);
		p.drawRectangle(width() - 10, 0, width(), height());
	}

	void mouseEvent(MouseEvent& a_event)
	{
		m_mouseX = a_event.m_x;
		m_mouseY = a_event.m_y;
		repaint();
	}

	int m_color;
	int m_mouseX, m_mouseY;
};


#endif


class CludgeBoolProperty : public Property<bool>
{
public:
	void cludgeSet(bool) { set(false); } // set the value without invoking valueChanged
};



// Useful for radio button groups
// pass in a list of Propery<bool> pointers, and terminate the argument list with NULL
void makeExclusiveBoolPropertySet(Property<bool>* a_value1, ...)
{
	va_list list;
	va_start(list, a_value1);
	Vector<CludgeBoolProperty*> radioButtonGroup;
	CludgeBoolProperty* nextVal = (CludgeBoolProperty*)a_value1;
	while (nextVal) {
		radioButtonGroup.push_back(nextVal);
		nextVal = va_arg(list, CludgeBoolProperty*);
	}
	va_end(list);

	for (unsigned i = 0; i < radioButtonGroup.size(); i++)
		for (unsigned j = 0; j < radioButtonGroup.size(); j++)
			if (i != j)
				connect(radioButtonGroup[i]->valueChanged, radioButtonGroup[j], &CludgeBoolProperty::cludgeSet);
}


/*

// Example DTD, for example plist

<!ENTITY % plistObject "(array | data | date | dict | real | integer | string | true | false )" >
<!ELEMENT plist %plistObject;>
<!ATTLIST plist version CDATA "1.0" >

<!-- Collections -->
<!ELEMENT array (%plistObject;)*>
<!ELEMENT dict (key, %plistObject;)*>
<!ELEMENT key (#PCDATA)>

<!--- Primitive types -->
<!ELEMENT string (#PCDATA)>
<!ELEMENT data (#PCDATA)> <!-- Contents interpreted as Base-64 encoded -->
<!ELEMENT date (#PCDATA)> <!-- Contents should conform to a subset of ISO 8601 (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'.  Smaller units may be omitted with a loss of precision) -->

<!-- Numerical primitives -->
<!ELEMENT true EMPTY>  <!-- Boolean constant true -->
<!ELEMENT false EMPTY> <!-- Boolean constant false -->
<!ELEMENT real (#PCDATA)> <!-- Contents should represent a floating point number matching ("+" | "-")? d+ ("."d*)? ("E" ("+" | "-") d+)? where d is a digit 0-9.  -->
<!ELEMENT integer (#PCDATA)> <!-- Contents should represent a (possibly signed) integer number in base 10 -->

*/
/*

// example plist

           <?xml version="1.0" encoding="UTF-8"?>
           <!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
           http://www.apple.com/DTDs/PropertyList-1.0.dtd >
           <plist version="1.0">
           <dict>
                <key>Label</key>
                <string>com.example.exampled</string>
                <key>ProgramArguments</key>
                <array>
                     <string>exampled</string>
                </array>
                <key>KeepAlive</key>
                <true/>
           </dict>
           </plist>
*/

class PropertySet
{
public:

};


class TestWindow : public Window
{
public:
	Property<String> m_labelText;

	Property<bool> m_checkBoxChecked1;
	Property<bool> m_radioButtonChecked1;
	Property<bool> m_checkBoxChecked2;
	Property<bool> m_radioButtonChecked2;
	Property<bool> m_checkBoxChecked3;
	Property<bool> m_radioButtonChecked3;
	Property<bool> m_checkBoxChecked4;
	Property<bool> m_radioButtonChecked4;

	Property<int>  m_sliderValue;
	Property<int>  m_comboValue;

	void buttonPressed(int)
	{
		printf("button pressed\n");
	}

	TestWindow(const char* name) : Window(name)
	{
		XmlParser parser;
		XmlDomTreeBuilder domTree;
		UiBuilder uiBuilder(this);

		uiBuilder.registerProperty("m_labelText"          , m_labelText);
		uiBuilder.registerProperty("m_checkBoxChecked1"	  , m_checkBoxChecked1);
		uiBuilder.registerProperty("m_radioButtonChecked1", m_radioButtonChecked1);
		uiBuilder.registerProperty("m_checkBoxChecked2"	  , m_checkBoxChecked2);
		uiBuilder.registerProperty("m_radioButtonChecked2", m_radioButtonChecked2);
		uiBuilder.registerProperty("m_checkBoxChecked3"   , m_checkBoxChecked3);
		uiBuilder.registerProperty("m_radioButtonChecked3", m_radioButtonChecked3);
		uiBuilder.registerProperty("m_checkBoxChecked4"   , m_checkBoxChecked4);
		uiBuilder.registerProperty("m_radioButtonChecked4", m_radioButtonChecked4);
		uiBuilder.registerProperty("m_sliderValue"		  , m_sliderValue);
		uiBuilder.registerProperty("m_comboValue"		  , m_comboValue);

		parser.parseXmlFile("C:\\temp\\CurrencyData\\TweakableProperties\\TestUI.xml", domTree);
		parser.parseXmlFile("C:\\temp\\CurrencyData\\TweakableProperties\\TestUI.xml", uiBuilder);
		domTree.printDomTree();

		connect(((Button*)uiBuilder.findWidget("but1").m_widget)->activated, this, &TestWindow::buttonPressed);

		//connect(m_checkBoxChecked1.valueChanged, &but1->isDefault, &Property<bool>::setValue);
		//makeExclusiveBoolPropertySet(&m_radioButtonChecked1, &m_radioButtonChecked2,
		//									&m_radioButtonChecked3, &m_radioButtonChecked4, NULL);

		m_labelText = "testing";

		VBox *vbox1 = new VBox(this);
		HBox *hbox = new HBox(vbox1);

		VBox *vbox = new VBox(hbox);
		RadioButton *rb1 = new RadioButton(vbox, m_radioButtonChecked1, "Hello World");
		RadioButton *rb2 = new RadioButton(vbox, m_radioButtonChecked2, "Hello World");
		RadioButton *rb3 = new RadioButton(vbox, m_radioButtonChecked3, "Hello World");
		RadioButton *rb4 = new RadioButton(vbox, m_radioButtonChecked4, "Hello World");
		Button *but1 = new Button(vbox, "Hello World");
		connect(but1->activated, this, &TestWindow::buttonPressed);
		Button *but2 = new Button(vbox, "Hello World");
		Button *but3 = new Button(vbox, "Hello World");
		Button *but4 = new Button(vbox, "Hello World");
		new VSpace(vbox);

		vbox = new VBox(hbox);
		CheckBox *cb1 = new CheckBox(vbox, m_checkBoxChecked1, "Hello World");
		CheckBox *cb2 = new CheckBox(vbox, m_checkBoxChecked2, "Hello World");
		CheckBox *cb3 = new CheckBox(vbox, m_checkBoxChecked3, "Hello World");		
		CheckBox *cb4 = new CheckBox(vbox, m_checkBoxChecked4, "Hello World");		
		Label *l1 = new Label(vbox, m_labelText);
		Label *l2 = new Label(vbox, m_labelText);
		Label *l3 = new Label(vbox, m_labelText);		
		Label *l4 = new Label(vbox, m_labelText);
		LineEdit *le1 = new LineEdit(vbox, m_labelText);
		new VSpace(vbox);
		new VSpace(vbox);

		vbox = new VBox(hbox);
		Slider *sl = new Slider(vbox, m_sliderValue);
		ComboBox *cb = new ComboBox(vbox, m_comboValue);
		GroupBox *gb = new GroupBox(vbox, m_labelText);
		new VSpace(vbox);

		CheckBox *cb5 = new CheckBox(gb, m_checkBoxChecked1, "Test");
		CheckBox *cb6 = new CheckBox(gb, m_checkBoxChecked2, "Test");
		new Label(gb, m_labelText);
		new LineEdit(gb, m_labelText);
		new Slider(gb, m_sliderValue);
		new VSpace(vbox);

		ProgressBar *pb = new ProgressBar(vbox1, m_sliderValue);
		new VSpace(vbox1);

		cb->addItem("blah item 1");
		cb->addItem("foo item 2");
		cb->addItem("bar item 3");

		rb2->disabled = true;
		but2->disabled = true;
		cb2->disabled = true;
		l2->disabled = true;

		rb3->isDefault = true;
		but3->isDefault = true;
		cb3->isDefault = true;

		rb4->hasFocus = true;
		but4->hasFocus = true;
		cb4->hasFocus = true;

		connect(m_checkBoxChecked1.valueChanged, &but1->isDefault, &Property<bool>::setValue);

		makeExclusiveBoolPropertySet(&m_radioButtonChecked1, &m_radioButtonChecked2,
											&m_radioButtonChecked3, &m_radioButtonChecked4, NULL);

/*
		VBox   *vbox = new VBox(this);
		VSpace *vspace0 = new VSpace(vbox);
		HBox  *hbox1 = new HBox(vbox);
		VSpace *vspace = new VSpace(vbox);
		HBox  *hbox3 = new HBox(vbox);

		HSpace *hsp1 = new HSpace(hbox1);
		m_labelText = "testing";
		Label  *lab1 = new Label(hbox1, m_labelText);
		HSpace *hsp2 = new HSpace(hbox1);

		HSpace *hsp3 = new HSpace(hbox3);
		Button *but1 = new Button(hbox3, "Hello World");
		HSpace *hsp4 = new HSpace(hbox3);

		VSpace *vspace2 = new VSpace(vbox);
*/

/*
		VBox* box1 = new VBox(this);
		TestBox* box2 = new TestBox(this);
		TestBox* box3 = new TestBox(this);
		TestBox* box4 = new TestBox(this);

		Button* button = new Button(box1, "Hello World");
		TestBox* box11 = new TestBox(box1);
		TestBox* box12 = new TestBox(box1);
		TestBox* box13 = new TestBox(box1);
		TestBox* box14 = new TestBox(box1);
*/
	}
	
	void paintEvent(PaintEvent& a_event)
	{
		Painter p(this);
		/*
		p.setBrush(0xff0000);
		p.drawRectangle(0, 0, width(), height());
		p.setBrush(0xff8888);
		p.drawRectangle(2, 2, width()-4, height()-4);
		*/
	}
};


#if 0


enum Recommendation
{
	StrongSell,
	Sell,
	Neutral,
	Buy,
	StrongBuy
};


class Currency
{
public:
	std::string    name;
	Recommendation recommendations[4];
};


Vector<Currency> currencies;


void parseCurrencyInfo(String a_data)
{
	std::string data = a_data.toUtf8();
	data = right(data, "<table");
	data = right(&data[5], "<table");
	data = left(data, "</table>");
	for (int c = 0; c < 6; c++)
	{
		Currency newCurrency;
		data = right(data, "\"color:#0059B0;\">");
		newCurrency.name = left(data, "</font>");
		//printf("Currency --%s-- contents: ", currency.c_str());		
		std::string currencyInfo = data;
		for (int i = 0; i < 4; i++)
		{
			currencyInfo = right(currencyInfo, "<B>");
			std::string recommendation = left(currencyInfo, "</B>");
			if (recommendation == "Strong Sell") newCurrency.recommendations[i] = StrongSell;
			if (recommendation == "Sell") newCurrency.recommendations[i] = Sell;
			if (recommendation == "Neutral") newCurrency.recommendations[i] = Neutral;
			if (recommendation == "Buy") newCurrency.recommendations[i] = Buy;
			if (recommendation == "Strong Buy") newCurrency.recommendations[i] = StrongBuy;
			//printf("--%s--", recommendation[i].c_str());
		}
		//printf("\n");
		currencies.push_back(newCurrency);
	}
}

/*

GMT:  9:21 pm  Monday, 17 November 2014
1416250028 unix time ->  Mon, 17 Nov 2014 18:47:08 GMT
1416259028 unix time ->  Mon, 17 Nov 2014 21:17:08 GMT

http://tvc.forexpros.com/b97f78924dcdc7607ea51eb823d9b1aa/1/1/1/8/history?symbol=49&resolution=1&from=1416258028&to=1416259028

*/

/*

rtmpt://110.5.111.62

http://www.d-addicts.com/forum/viewtopic_73546_0.htm


*/

#include <time.h>
#include <stdint.h>




std::map<int, std::string> g_symbolNameMap;
std::map<std::string, int> g_nameSymbolMap;

void addSymbol(int a_symbol, std::string a_name)
{
	g_symbolNameMap[a_symbol] = a_name;
	g_nameSymbolMap[a_name] = a_symbol;
}

void initSymbols(bool fast = true)
{
	if (!fast)
	{
		// This is how the symbol->name map was generated
		// so that it can be checked later or perhaps
		// retrieved each time instead
		for (int c = 1; c < 80; c++)
		{
			std::string data = Network::wget("http://tools.investing.com/technical_summary.php?pairs=" + to_string(c) + "&curr-name-color=%230059B0&fields=1w").toUtf8();
			data = right(data, "<table");
			data = right(&data[5], "<table");
			data = left(data, "</table>");
			data = right(data, "\"color:#0059B0;\">");
			data = left(data, "</font>");
			printf("	addSymbol(%i, \"%s\");\n", c, data.c_str());
			addSymbol(c , data.c_str());
		}
	}
	else
	{
		addSymbol(1 , "EUR/USD");
		addSymbol(2 , "GBP/USD");
		addSymbol(3 , "USD/JPY");
		addSymbol(4 , "USD/CHF");
		addSymbol(5 , "AUD/USD");
		addSymbol(6 , "EUR/GBP");
		addSymbol(7 , "USD/CAD");
		addSymbol(8 , "NZD/USD");
		addSymbol(9 , "EUR/JPY");
		addSymbol(10, "EUR/CHF");
		addSymbol(11, "GBP/JPY");
		addSymbol(12, "GBP/CHF");
		addSymbol(13, "CHF/JPY");
		addSymbol(14, "CAD/CHF");
		addSymbol(15, "EUR/AUD");
		addSymbol(16, "EUR/CAD");
		addSymbol(17, "USD/ZAR");
		addSymbol(18, "USD/TRY");
		addSymbol(21, "BTC/USD");
		addSymbol(22, "BTC/EUR");
		addSymbol(23, "BTC/JPY");
		addSymbol(24, "BTC/CAD");
		addSymbol(25, "BTC/GBP");
		addSymbol(26, "BTC/CHF");
		addSymbol(27, "FTSE 100");
		addSymbol(29, "BTC/AUD");
		addSymbol(32, "BTC/HKD");
		addSymbol(34, "BTC/CNY");
		addSymbol(35, "BTC/SGD");
		addSymbol(37, "EUR/NOK");
		addSymbol(38, "BTC/NZD");
		addSymbol(39, "USD/MXN");
		addSymbol(40, "USD/PLN");
		addSymbol(41, "USD/SEK");
		addSymbol(42, "USD/SGD");
		addSymbol(43, "USD/DKK");
		addSymbol(44, "EUR/DKK");
		addSymbol(46, "EUR/PLN");
		addSymbol(47, "AUD/CAD");
		addSymbol(48, "AUD/CHF");
		addSymbol(49, "AUD/JPY");
		addSymbol(50, "AUD/NZD");
		addSymbol(51, "CAD/JPY");
		addSymbol(52, "EUR/NZD");
		addSymbol(53, "GBP/AUD");
		addSymbol(54, "GBP/CAD");
		addSymbol(55, "GBP/NZD");
		addSymbol(56, "NZD/CAD");
		addSymbol(57, "NZD/CHF");
		addSymbol(58, "NZD/JPY");
		addSymbol(59, "USD/NOK");
		addSymbol(60, "GBP/SGD");
		addSymbol(61, "EUR/SEK");
		addSymbol(63, "USD/ILS");
		addSymbol(64, "EUR/ILS");
		addSymbol(65, "GBP/ILS");
		addSymbol(66, "EUR/TRY");
		addSymbol(68, "XAU/USD");
		addSymbol(69, "XAG/USD");
		addSymbol(72, "NZD/DKK");
		addSymbol(73, "NOK/JPY");
		addSymbol(74, "PLN/JPY");
		addSymbol(75, "TRY/JPY");
		addSymbol(76, "THB/JPY");
		addSymbol(77, "DKK/HUF");
		addSymbol(78, "ZAR/JPY");
		addSymbol(79, "MXN/JPY");
	}
}


#include "Threads.h"


class BackgroundWget : public Thread
{
public:
	BackgroundWget(std::string url) : m_url(url) {}
	virtual int Run()
	{
		printf("Running BG thread: --%s--\n", m_url.data());
		Network::wget(m_url);
		return 0;
	}
	std::string m_url;
};


#endif


int main(int argc, char* argv[])
{

#if !defined(NDEBUG)

#	if defined(_MSC_VER)
		_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
		//_CrtSetBreakAlloc(1027);
		//_CrtSetBreakAlloc(1091);
		//_CrtSetBreakAlloc(998);
		//_CrtSetBreakAlloc(1202);
		//_CrtSetBreakAlloc(14301);
		
#	endif

	runUnitTests(0);
#endif

	Application app;

	TestWindow testWin("Test Window");
	//MyWindow win("Test", argv[1]);

	app.exec();

	return 0;

#if 0
	
	initSymbols();
	time_t currentTime;
	currentTime = time(&currentTime);
	

	int symbol = 1;     // 1 -> eur/usd
	int resolution = 1; // 1 min


    // http://www.investing.com/charts/forex-streaming-charts
	std::string entryPageHost = "www.investing.com";
	std::string entryResponse = Network::wget(entryPageHost + "/charts/forex-streaming-charts").toUtf8();
	//printf( "entryResponse: --%s--\n", entryResponse.c_str() );

	entryResponse = right(entryResponse, "id=\"tvc_frame\"");
	std::string liveDataCarrier = right(entryResponse, "carrier=");
	liveDataCarrier = left(liveDataCarrier, "&");	
	std::string currentNetworkTime = right(entryResponse, "time=");
	currentNetworkTime = left(currentNetworkTime, "&");

	//printf( "entryResponse: --%s--\n", entryResponse.c_str() );
	printf( "liveDataCarrier: --%s--  currentNetworkTime: --%s-- \n", liveDataCarrier.c_str(), currentNetworkTime.c_str() );
	
	std::string liveDataHost = "tvc.forexpros.com";
	//std::string liveDataCarrier = "69b34bed94e93dde75093c765b421e1d";
	std::string currentTimeStr = to_string((uint32_t)currentTime);
	currentTimeStr = currentNetworkTime;

	std::string initUrl = liveDataHost + "/init.php?carrier=" + liveDataCarrier + "&time=" + currentTimeStr +
			"&domain_ID=1" "&lang_ID=1" "&timezone_ID=8" "&pair_ID=0" "&interval=300" "&refresh=8" "&session=24x7";
	std::string initResponse = Network::wget(initUrl).toUtf8();
	//printf( "initResponse: --%s--\n", initResponse.c_str() );
	
	initResponse = right(initResponse, "iframe src=\"http://");
	initResponse = left(initResponse, "\"");
	std::string initResponseHost = left(initResponse, "/");
	std::string initResponsePath = "/" + right(initResponse, "/");

	/*
	BackgroundWget bgWget(initResponseHost, initResponsePath);
	bgWget.Start();
	Sleep(100);
	*/
	
	/*
	std::string dataInit = Network::wget(initResponseHost.c_str(), 80, initResponsePath.c_str());
	printf( "wget: --%s--%s-\n", initResponseHost.c_str(), initResponsePath.c_str() );
	printf( "dataInit: --%s--\n", dataInit.c_str() );
	return 0;
	*/
	
	// "/69b34bed94e93dde75093c765b421e1d/1416709561/1/1/8"; //
	std::string liveDataKey = liveDataCarrier + "/" + currentTimeStr + "/1/1/8";
	std::string fromTime = 	to_string((uint32_t)currentTime - 350000 ); // "1416258028";
	std::string toTime = to_string((uint32_t)currentTime);//"1416259028";
	std::string symbolStr = to_string((uint32_t)symbol);//"1416259028";
	std::string resolutionStr = to_string((uint32_t)resolution);//"1416259028";
	std::string urlPath = "/" + liveDataKey + "/history?symbol=" + symbolStr + "&resolution=" + resolutionStr + "&from=" + fromTime + "&to=" + toTime;
	std::string data = Network::wget(liveDataHost + urlPath).toUtf8();
	data = right(data, "\r\n\r\n"); // Skip HTTP headers
	
	/*
	printf( "\n" );
	printf( "wget: --%s--\n", urlPath.c_str() );
	printf( "data: --%s--\n", data.c_str() );
	printf( "time stamps: --%s--\n", left(right(data, "\"t\":["), "]").c_str() );
	*/
	
	Vector<std::string> timeStampList  = split(left(right(data, "\"t\":["), "]"), ",");
	Vector<std::string> openPriceList  = split(left(right(data, "\"o\":["), "]"), ",");
	Vector<std::string> closePriceList = split(left(right(data, "\"c\":["), "]"), ",");
	Vector<std::string> highPriceList  = split(left(right(data, "\"h\":["), "]"), ",");
	Vector<std::string> lowPriceList   = split(left(right(data, "\"l\":["), "]"), ",");
	
	printf("List lengths:  %i %i %i %i %i\n", timeStampList.size(), openPriceList.size(), closePriceList.size(), highPriceList.size(), lowPriceList.size());
	// TODO : validate they are all the same length
	
	for (int i = 0; i < 3; i++)
		printf("symbol: %s   time: %s   open: %s   close: %s   high: %s   low: %s\n", g_symbolNameMap[symbol].c_str(), 
							timeStampList[i].c_str(), openPriceList[i].c_str(), closePriceList[i].c_str(), highPriceList[i].c_str(), lowPriceList[i].c_str());
	
	//printf("data: ---%s---\n", data.c_str());
	// "t" -> time    "o" -> open   "c" -> close   "h" ->high  "l" -> low   "s" -> status   "v" -> volume
	
	return 0;

	//http://www.investing.com/common/refresher_new/refresher_v13.2.php?pulse=224&refresher_version=v1.7.0&session_uniq_id=3988a93c4c3de672d4d04b29c19e43ab&sideblock_recent_quotes=1&sideblock_quotes_exists=1&quotes_bar_exists=1&economicCalendar_exists=0&markets_page_exists=0&technical_summary_box_exists=0&smlID=1&fpcharts%5B%5D=%255B%25228839%2522%252C%252260%2522%252C1004%252C%2522S%2526P%2520500%2522%255D&sideblock_quotes_selected=QBS_2&quotes_bar_selected=1&PortfolioSideBoxTime=1416573961&RQSideBoxTime=1416574011&MyPortfolioTime=1416573961
	
	// std::string data = wget("http://tools.investing.com/technical_summary.php?pairs=1,2,3,4,5,6&curr-name-color=%230059B0&fields=5m,15m,1h,1d");
	
	parseCurrencyInfo(Network::wget("tools.investing.com/technical_summary.php?pairs=1,2,3,4,5,6&curr-name-color=%230059B0&fields=5m,15m,1h,1d"));
	parseCurrencyInfo(Network::wget("tools.investing.com/technical_summary.php?pairs=7,8,9,10,11,12&curr-name-color=%230059B0&fields=5m,15m,1h,1d"));
	parseCurrencyInfo(Network::wget("tools.investing.com/technical_summary.php?pairs=13,14,15,16,17,18&curr-name-color=%230059B0&fields=5m,15m,1h,1d"));
	parseCurrencyInfo(Network::wget("tools.investing.com/technical_summary.php?pairs=19,20,21,22,23,24&curr-name-color=%230059B0&fields=5m,15m,1h,1d"));

	for (uint32_t i = 0; i < currencies.size(); i++)
	{
		printf("Currency: --%s-- Contents: ", currencies[i].name.c_str());
		for (int j = 0; j < 4; j++)
		{
			switch (currencies[i].recommendations[j])
			{
				case StrongSell:  printf(" SS "); break;
				case Sell:        printf(" S  "); break;
				case Neutral:     printf(" N  "); break;
				case Buy:         printf(" B  "); break;
				case StrongBuy:   printf(" SB "); break;
			}
		}
		printf("\n");
	}
	
#endif

}