  #include "TestFramework.h"
#include "API/WebCore.h"
#include <windows.h>

#define WIDTH	600
#define HEIGHT	600
#define LENGTH_SEC	1

class Test_RenderSync : public Test, public Awesomium::WebViewListener
{
	Awesomium::WebView* webView;
  bool _hasLoaded;

public:
	Test_RenderSync() : Test("RenderSync")
    , _hasLoaded(false)
	{
		webView = Awesomium::WebCore::Get().createWebView(WIDTH, HEIGHT);
    webView->setListener(this);
		webView->loadFile("tests/RenderTest.html");
    while (!_hasLoaded)
    {
      Awesomium::WebCore::Get().update();
      ::Sleep(10);
    }
	}

	~Test_RenderSync()
	{
		webView->destroy();
	}

	bool run()
	{
		log("Running");

		unsigned char* buffer = new unsigned char[WIDTH * HEIGHT * 4];

		timer t;
		t.start();
		int loopCount = 0;
		int renderCount = 0;

 		while(t.elapsed_time() < LENGTH_SEC)
		{
      /*
      {
	      Awesomium::FutureJSValue futureVal;
        webView->syncExecuteJavascript("set_bgcolor_to_blue();");

        if (!webView->isDirty())
        {
			    log("Test failed, webview should be dirty to paint in blue.");
          std::cout << "loopCount " << loopCount << std::endl;
			    return false;
        }

			  renderCount++;
			  webView->render(buffer, WIDTH * 4, 4);

        unsigned char pixel_b = buffer[0];
        unsigned char pixel_g = buffer[1];
        unsigned char pixel_r = buffer[2];

        if (! (pixel_r == 0 && pixel_g == 0 && pixel_b == 255))
        {
			    log("Test failed, incorrect pixel color (expected blue)");
			    return false;
        }
      }
      {
        webView->syncExecuteJavascript("set_bgcolor_to_red();");

        if (!webView->isDirty())
        {
			    log("Test failed, webview should be dirty to paint in red.");
          std::cout << "loopCount " << loopCount << std::endl;
			    return false;
        }

			  renderCount++;
			  webView->render(buffer, WIDTH * 4, 4);

        unsigned char pixel_b = buffer[0];
        unsigned char pixel_g = buffer[1];
        unsigned char pixel_r = buffer[2];

        if (! (pixel_r == 255 && pixel_g == 0 && pixel_b == 0))
        {
			    log("Test failed, incorrect pixel color (expected red)");
			    return false;
        }
      }
      */
      {
        webView->executeJavascript("create_green_layer();");
        webView->syncLayout();

       if (!webView->isDirty())
       {
          log("Test failed, webview should be dirty to paint in green.");
          std::cout << "loopCount " << loopCount << std::endl;
          return false;
       }

			  renderCount++;
			  webView->render(buffer);

        unsigned char pixel_b = buffer[0];
        unsigned char pixel_g = buffer[1];
        unsigned char pixel_r = buffer[2];

        if (! (pixel_r == 0 && pixel_g == 255 && pixel_b == 0))
        {
			    log("Test failed, incorrect pixel color (expected green)");
			    return false;
        }

        webView->syncLayout();

        if (webView->isDirty())
         {
            log("Test failed, webview should not be dirty, we've just painted it.");
            std::cout << "loopCount " << loopCount << std::endl;
            return false;
         }
      }
      {
        webView->syncExecuteJavascript("delete_layer();");

        if (!webView->isDirty())
        {
			    log("Test failed, webview should be dirty to paint in red.");
          std::cout << "loopCount " << loopCount << std::endl;
			    return false;
        }

			  renderCount++;
			  webView->render(buffer);

        unsigned char pixel_b = buffer[0];
        unsigned char pixel_g = buffer[1];
        unsigned char pixel_r = buffer[2];

        if (! (pixel_r == 255 && pixel_g == 0 && pixel_b == 0))
        {
			    log("Test failed, incorrect pixel color (expected red)");
			    return false;
        }
      }

      loopCount++;
			Sleep(1);
		}

		delete[] buffer;

		logTestValue("RenderSync_LoopCount", loopCount / (double)LENGTH_SEC);
		logTestValue("RenderSync_RenderCount", renderCount / (double)LENGTH_SEC);

		return true;
	}

  void onBeginNavigation(const std::string& url, const std::wstring& frameName) {}
	void onBeginLoading(const std::string& url, const std::wstring& frameName, int statusCode, const std::wstring& mimeType) {}
	void onFinishLoading() { _hasLoaded = true; }
	void onCallback(const std::string& name, const Awesomium::JSArguments& args) {}
	void onReceiveTitle(const std::wstring& title, const std::wstring& frameName) {}
	void onChangeTooltip(const std::wstring& tooltip) {}
#if defined(_WIN32)
	void onChangeCursor(HCURSOR cursor) {}
#endif
	void onChangeKeyboardFocus(bool isFocused) {}
	void onChangeTargetURL(const std::string& url) {}
	void onCreateNewWebView() {};
};