#include <mof/widget/ClippingView.hpp>
#include <mof/GraphicsDevice.hpp>
#include <mof/ConsoleIO.hpp>
    
namespace mof
{
namespace widget
{
//{{{ struct Impl
    struct ClippingView::Impl
    {
        std::shared_ptr<WidgetView> pBody_; 
		mof::Vector2D preferredSize_;

        Impl(std::shared_ptr<WidgetView> pBody)
        : pBody_(pBody)
        {
        }
    
        ~Impl()
        {
        }
    
    };
//}}}
//{{{ constructor
    ClippingView::ClippingView(std::shared_ptr<WidgetView> pBody)
    : 
        pImpl_(new Impl(pBody)) 
    {
        pImpl_->pBody_->getPositionStream() << getPositionStream(); 
        pImpl_->pBody_->getColorStream()    << getColorStream(); 
		pImpl_->preferredSize_ = pImpl_->pBody_->getPreferredSize();// the initial scale depends on the body.
        getSizeStream() << pImpl_->preferredSize_;
        pImpl_->pBody_->getSizeStream() << getSizeStream() << mof::makeConstantHandler(-pImpl_->preferredSize_); 
    }
//}}}
//{{{ destructor
    ClippingView::~ClippingView()
    {
    }
//}}}
//{{{ update
    void ClippingView::update( )
    {
        m_positionStream.update( );
        m_sizeStream.update( );
        m_colorStream.update( );
        pImpl_->pBody_->update();
    }
//}}}
//{{{ draw
    void ClippingView::draw( ) const
    {
		int width = mof::GraphicsDevice::getViewportWidth();
		int height = mof::GraphicsDevice::getViewportHeight();
		mof::Vector2D position = m_positionStream.value();
		mof::Vector2D scale = m_sizeStream.value();
		if (0 == scale.x || 0 == scale.y) return;// prevent the area of viewport from vanishing. 
		mof::GraphicsDevice::setViewport(mof::Rectangle<mof::real>(position.x, position.y, position.x + scale.x, position.y + scale.y));
        pImpl_->pBody_->draw( );
		mof::GraphicsDevice::setViewport(mof::Rectangle<mof::real>(0, 0, width, height));// restore the viewport.
    }
//}}}
//{{{ setVisible
    void ClippingView::setVisible(bool visible)
    {
		pImpl_->pBody_->setVisible(visible);
    }
//}}}
//{{{ show
    FrameNumber ClippingView::show(bool immediately) 
    {
        return pImpl_->pBody_->show(immediately);
    }
//}}}
//{{{ hide
    FrameNumber ClippingView::hide(bool immediately)
    {
        return pImpl_->pBody_->hide(immediately);
    }
//}}}
//{{{ focus
    FrameNumber ClippingView::focus(bool immediately) 
    {
        return pImpl_->pBody_->focus(immediately);
    }
//}}}
//{{{ blur
    FrameNumber ClippingView::blur(bool immediately)
    {
        return pImpl_->pBody_->blur(immediately);
    }
//}}}
//{{{ click
    FrameNumber ClippingView::click(bool immediately)
    {
        return pImpl_->pBody_->click(immediately);
    }
//}}}
//{{{ getPreferredSize
	mof::Vector2D ClippingView::getPreferredSize() const
    {
        return pImpl_->preferredSize_;
    }
//}}}
}
} // namespace mof
