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

  \author Satofumi KAMIMURA

  $Id: SwitchSurface.cpp 1811 2010-04-30 16:12: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::setRotateAngle(const Angle& angle)
{
    (void)angle;
    // !!!
}


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_;
}
