/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com

Copyright (c) 2011 I-maginer

This program 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; either version 2 of the License, or (at your option) any later
version.

This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
-----------------------------------------------------------------------------
*/

#include "embeddedWebNavigatorManager.h"
#include "embeddedWebNavigator.h"

namespace Scol
{
  namespace EmbeddedWebNavigator
  {

// Instanciate static member
WebNavigatorManager* WebNavigatorManager::thisInstance = 0;

WebNavigatorManager::WebNavigatorManager(const ScolWindowHandle& scolMainWindow, std::string cacheDirectory) : scolMainWindowHandle(scolMainWindow)
{
  // Initialise singleton first
	assert(!WebNavigatorManager::thisInstance);
  WebNavigatorManager::thisInstance = this;
  nextUniqueId = 1; // 0 is reserved id

  // Specify a cache path value.
  CefSettings settings;
  std::replace(cacheDirectory.begin(), cacheDirectory.end(), '/', '\\');
  CefString(&settings.cache_path).FromString(cacheDirectory);
  CefString(&settings.log_file).FromString(cacheDirectory + "\\CefDebug.log");

  // Use the Chinese language locale.
  // CefString(&settings.locale).FromASCII("zh-cn");

#ifdef NDEBUG
  // Only log error messages and higher in release build.
  settings.log_severity = LOGSEVERITY_ERROR;
#endif

  // processed using a separate UI thread.
  settings.multi_threaded_message_loop = true;

  // Init CEF.
  CefInitialize(settings, 0);
}

WebNavigatorManager::WebNavigatorManager() : scolMainWindowHandle(0)
{
  // Forbiden
}

WebNavigatorManager::~WebNavigatorManager()
{
  // Destroy all the remaining WebNavigator instances
  WebNavigatorList webNavigatorListCopy = webNavigatorList;
  WebNavigatorList::iterator iWebNavigator = webNavigatorListCopy.begin();
  if(iWebNavigator != webNavigatorListCopy.end())
  {
    DestroyNavigator(iWebNavigator->second);
    iWebNavigator++;
  }

  // Shut down CEF.
  CefShutdown();

  // Reset singleton
	assert(WebNavigatorManager::thisInstance);
	WebNavigatorManager::thisInstance = 0;
}

WebNavigatorManager& WebNavigatorManager::GetSingleton()
{
  assert(WebNavigatorManager::thisInstance);
  return *WebNavigatorManager::thisInstance;
}

WebNavigatorManager* WebNavigatorManager::GetSingletonPtr()
{
  return WebNavigatorManager::thisInstance;
}

WebNavigator* WebNavigatorManager::CreateNavigator(const ScolWindowHandle& parentWindowHandle, int xPosition, int yPosition, int width, int height, std::string url)
{
  // Create it.
  WebNavigator* newWebNavigator = new WebNavigator(nextUniqueId, scolMainWindowHandle, parentWindowHandle, xPosition, yPosition, width, height, url);
  
  // Store a reference to the newly created web navigator.
  webNavigatorList.insert(WebNavigatorList::value_type(nextUniqueId, newWebNavigator));
  nextUniqueId++;
  return newWebNavigator;
}

WebNavigator* WebNavigatorManager::CreateNavigator(const ScolWindowHandle& parentWindowHandle, int width, int height, std::string url, bool transparency)
{
  // Create it.
  WebNavigator* newWebNavigator = new WebNavigator(nextUniqueId, scolMainWindowHandle, parentWindowHandle, width, height, url, transparency);
  
  // Store a reference to the newly created web navigator.
  webNavigatorList.insert(WebNavigatorList::value_type(nextUniqueId, newWebNavigator));
  nextUniqueId++;
  return newWebNavigator;
}

void WebNavigatorManager::DestroyNavigator(WebNavigator* webNavigator)
{
  if(webNavigator)
  {
    // Check if a web navigator instance with this parent window exist.
    WebNavigatorList::iterator iWebNavigatorSearched = webNavigatorList.find(webNavigator->GetUniqueId());
    if(iWebNavigatorSearched != webNavigatorList.end())
    {
      // Erase from first list
      WebNavigator* webNavigator = iWebNavigatorSearched->second;
      webNavigatorList.erase(iWebNavigatorSearched);

      // Delete web navigator instance
      delete(webNavigator);
    }
  }
}

WebNavigator* WebNavigatorManager::GetNavigator(unsigned long uniqueId)
{
  WebNavigatorList::iterator iSearchedNavigator = webNavigatorList.find(uniqueId);
  if(iSearchedNavigator != webNavigatorList.end())
    return iSearchedNavigator->second;
  else
    return 0;
}

  }
}