/*!
  \file
  \brief 表示内容を交換できるサーフェス

  \author Satofumi KAMIMURA

  $Id: SwitchSurface.cpp 857 2009-05-11 12:59:05Z satofumi $
*/

#include "SwitchSurface.h"
#include <boost/bind.hpp>
#include <algorithm>
#include <map>

using namespace qrk;
using namespace boost;
using namespace std;


namespace
{
  typedef map<size_t, Surface*> Surfaces;
}


struct SwitchSurface::pImpl
{
  Surfaces surfaces_;
  size_t current_id_;
  float alpha_;


  pImpl(void) : current_id_(0), alpha_(1.0)
  {
  }


  Surface* currentSurface(void)
  {
    return surfaces_[current_id_];
  }


  void setAlpha(float alpha)
  {
    alpha_ = alpha;

    // 登録済みのサーフェスに適用
    for (Surfaces::iterator it = surfaces_.begin();
         it != surfaces_.end(); ++it) {
      it->second->setAlpha(alpha);
    }
  }


  void draw(const Rect<long>* src, const Rect<long>* dest)
  {
    if (surfaces_.empty()) {
      return;
    }

    currentSurface()->draw(src, dest);
  }
};


SwitchSurface::SwitchSurface(void) : pimpl(new pImpl)
{
}


SwitchSurface::~SwitchSurface(void)
{
}


bool SwitchSurface::isValid(void) const
{
  if (pimpl->surfaces_.empty()) {
    return false;

  } else {
    return pimpl->currentSurface()->isValid();
  }
}


Rect<long> SwitchSurface::rect(void) const
{
  if (pimpl->surfaces_.empty()) {
    Rect<long> dummy;
    return dummy;

  } else {
    return pimpl->currentSurface()->rect();
  }
}


void SwitchSurface::setAlpha(float alpha)
{
  pimpl->setAlpha(alpha);
}


float SwitchSurface::alpha(void) const
{
  return pimpl->alpha_;
}


void SwitchSurface::draw(const Rect<long>* src, const Rect<long>* dest)
{
  pimpl->draw(src, dest);
}


void SwitchSurface::addSurface(Surface& surface, size_t id)
{
  surface.setAlpha(pimpl->alpha_);
  pimpl->surfaces_[id] = &surface;

  if (pimpl->surfaces_.empty()) {
    pimpl->current_id_ = id;
  }
}


void SwitchSurface::removeSurface(size_t id)
{
  pimpl->surfaces_.erase(id);
}


void SwitchSurface::setDrawSurface(size_t id)
{
  if (pimpl->surfaces_.find(id) == pimpl->surfaces_.end()) {
    return;
  }

  pimpl->current_id_ = id;
}


size_t SwitchSurface::currentSurfaceId(void)
{
  return pimpl->current_id_;
}
