#include <mof/widget/Container.hpp>
#include "mof/mofGraphics.hpp"
#include "mof/utilities.hpp"
#include "mof/widgets.hpp"
#include "mof/streams.hpp"
#include <vector>
#include <algorithm>
#include <memory>
   
using std::auto_ptr;

namespace mof
{
namespace widget
{
//{{{ struct Impl
    struct Container::Impl
    {
        std::vector< std::shared_ptr<WidgetView> > children;
        auto_ptr<Layout> pLayout;
        
    
        Impl() : pLayout(NULL){}
        ~Impl(){}
    
    };
//}}}
//{{{ constructor
    Container::Container
    (
        const std::shared_ptr<WidgetView>& front ,
        const std::shared_ptr<WidgetView>& back ,
        const FactoryMethod<Layout>& layout
    )
    : 
        m_pImpl( new Impl( ) ) 
    {
        
        int length = (&back - &front) +1;
        for(int i = 0 ; i < length ; i++)
        {
            m_pImpl->children.push_back( (&front)[i] );
        }

        m_pImpl->pLayout = auto_ptr<Layout>( layout() );
        foreach(std::shared_ptr<WidgetView> pView, m_pImpl->children)
        {
            m_pImpl->pLayout->add(pView);
        }
        m_sizeStream << m_pImpl->pLayout->getPreferredSize();
        m_pImpl->pLayout->connect(this);

        for(int i = 0 ; i < length ; i++)
        {
            m_pImpl->children[i]->getColorStream() << getColorStream(); 
        }
    }
//}}}
//{{{ destructor
    Container::~Container()
    {
    }
//}}}
//{{{ update
    void Container::update( )
    {
        m_positionStream.update( );
        m_sizeStream.update( );
        m_colorStream.update( );
        foreach(std::shared_ptr<WidgetView> value , m_pImpl->children)
        {
            value->update();
        }
    }
//}}}
//{{{ draw
    void Container::draw( ) const
    {
        foreach(std::shared_ptr<WidgetView> value , m_pImpl->children)
        {
            value->draw();
        }

    }
//}}}
//{{{ setVisible
    void Container::setVisible(bool visible)
    {
        foreach(std::shared_ptr<WidgetView> value , m_pImpl->children)
        {
            value->setVisible(visible);
        }
    }
//}}}
//{{{ show
    FrameNumber Container::show(bool imidiately) 
    {
        unsigned int maxFrame = 0;
        foreach(std::shared_ptr<WidgetView> value , m_pImpl->children)
        {
            maxFrame = max(value->show(imidiately) , maxFrame);
        }
        return maxFrame;
    }
//}}}
//{{{ hide
    FrameNumber Container::hide(bool imidiately)
    {
        unsigned int maxFrame = 0;
        foreach(std::shared_ptr<WidgetView> value , m_pImpl->children)
        {
            maxFrame = max(value->hide(imidiately) , maxFrame);
        }
        return maxFrame;

    }
//}}}
//{{{ focus
    FrameNumber Container::focus(bool) 
    {
        return 0;
    }
//}}}
//{{{ blur
    FrameNumber Container::blur(bool)
    {
        return 0;
    }
//}}}
//{{{ click
    FrameNumber Container::click(bool)
    {
        return 0;
    }
//}}}
//{{{ getPreferredSize
	mof::Vector2D Container::getPreferredSize() const
    {
        return m_pImpl->pLayout->getPreferredSize();
    }
//}}}
//{{{ getAt
	std::shared_ptr<WidgetView> Container::getAt(int index) const
    {
        return m_pImpl->children[index];
    }
//}}}
//{{{ getLength
    int Container::getLength() const
    {
        return m_pImpl->children.size();
    }
//}}}
//{{{ getAdjacentAsUp
    int Container::getAdjacencyAsUp(int index) const
    {
        return m_pImpl->pLayout->getAdjacencyAsUp(index);
    }
//}}}
//{{{ getAdjacentAsDown
    int Container::getAdjacencyAsDown(int index) const
    {
        return m_pImpl->pLayout->getAdjacencyAsDown(index);
    }
//}}}
//{{{ getAdjacentAsLeft
    int Container::getAdjacencyAsLeft(int index) const
    {
        return m_pImpl->pLayout->getAdjacencyAsLeft(index);
    }
//}}}
//{{{ getAdjacentAsRight
    int Container::getAdjacencyAsRight(int index) const
    {
        return m_pImpl->pLayout->getAdjacencyAsRight(index);
    }
//}}}
//{{{ add
    void Container::add(std::shared_ptr<WidgetView> pView)
    {
        //children.push_back( pView ); 
        //m_pImpl->pLayout = adaptWidgetViewAndLayout( m_pImpl->children.begin( ) , m_pImpl->children.end( ) , layout);
    }
//}}}

}
} // namespace mof
