#include <QDebug>
#include <QScrollBar>
#include <QApplication>
#include <QPainter>

#include "globals/UBGlobals.h"
#include "UBWidgetList.h"

UBWidgetList::UBWidgetList(QWidget* parent, eWidgetListOrientation orientation, const char* name):QScrollArea(parent)
  , mCanRemove(true)
  , mpLayout(NULL)
  , mpContainer(NULL)
  , mMargin(10)
  , mListElementsSpacing(10)
  , mpEmptyLabel(NULL)
  , mpCurrentWidget(NULL)
{
   setObjectName(name);
   mOrientation = orientation;
   mpContainer = new QWidget(this);
   mpEmptyLabel = new QLabel(this);
   mpEmptyLabel->setObjectName("emptyString");
   mpEmptyLabel->setWordWrap(true);
   mpEmptyLabel->setAlignment(Qt::AlignCenter);

   if(eWidgetListOrientation_Vertical == orientation){
       setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
       setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       mpLayout = new QVBoxLayout(mpContainer);
   }
   else{
       setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
       setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       mpLayout = new QHBoxLayout(mpContainer);
   }
   mpLayout->setContentsMargins(margin(), margin(), margin(), margin());
   mpContainer->setLayout(mpLayout);
   setWidget(mpContainer);
}

UBWidgetList::~UBWidgetList()
{
    DELETEPTR(mpEmptyLabel);
    DELETEPTR(mpLayout);
    DELETEPTR(mpContainer);
}

void UBWidgetList::addWidget(QWidget *widget)
{
    if(NULL != mpLayout && NULL != widget){
        widget->setParent(mpContainer);
        mpEmptyLabel->setVisible(false);
        mWidgetInfo[widget] = widget->size();
        updateView(size());
        mpLayout->addWidget(widget);

        // This call is used only to refresh the size of the widgets
        updateSizes();
    }
}

void UBWidgetList::removeWidget(QWidget *widget)
{
    if(NULL != mpLayout && NULL != widget){
        mpLayout->removeWidget(widget);
        mWidgetInfo.remove(widget);
        widget->setVisible(false);
        updateView(size());
        if(0 == mpLayout->count()){
            mpEmptyLabel->setVisible(true);
        }
        if(mpCurrentWidget == widget){
            mpCurrentWidget = NULL;
        }
    }
}


int UBWidgetList::scaleWidgets(QSize pSize)
{
    // to remove the first spacing that shouldn't be there.
    int result = -mListElementsSpacing;
    foreach(QWidget* eachWidget, mWidgetInfo.keys()){
        qreal scaleFactor = 0;
        int newWidgetWidth =  pSize.width();
        int newWidgetHeight = pSize.height();
        if(eWidgetListOrientation_Vertical == mOrientation){
            scaleFactor = (float)mWidgetInfo[eachWidget].width() / (float)pSize.width();
            newWidgetHeight = mWidgetInfo[eachWidget].height()/scaleFactor;
            result += newWidgetHeight;
            eachWidget->setMinimumHeight(newWidgetHeight- 1);
            eachWidget->setMaximumHeight(newWidgetHeight);
        }
        else{
            scaleFactor = (float)mWidgetInfo[eachWidget].height() / (float)pSize.height();
            newWidgetWidth = mWidgetInfo[eachWidget].width()/scaleFactor;
            result += newWidgetWidth;
            eachWidget->setMinimumWidth(newWidgetWidth - 1);
            eachWidget->setMaximumWidth(newWidgetWidth);
        }
        //Adding a vertical/horizontal space between each element of the list
        result += mListElementsSpacing;
    }
    return result;
}

void UBWidgetList::scaleContainer(QSize pSize, int updateValue)
{
    if(eWidgetListOrientation_Vertical == mOrientation)
        mpContainer->resize(pSize.width(), updateValue);
    else
        mpContainer->resize(updateValue, pSize.height());
}


void UBWidgetList::updateView(QSize pSize)
{
    // Widgets on list are resized automatically to fit the mpcontainer.
    // so if you want to keep the aspect ratio you have to calculate
    // the sum of the new widget height and give it to the mpContainer.
    // The container resize will trig the widgets resize and the good
    // height permits to respect the aspect ratio.
    int updatedValue = scaleWidgets(pSize);
    scaleContainer(pSize,updatedValue);
}



void UBWidgetList::resizeEvent(QResizeEvent *ev)
{
    Q_UNUSED(ev);
    mpEmptyLabel->setGeometry((width() - mpEmptyLabel->width()) / 2,
                              (height() - mpEmptyLabel->height()) /2,
                              mpEmptyLabel->width(),
                              mpEmptyLabel->height());
    updateView(size());
    updateSizes();
}

void UBWidgetList::mousePressEvent(QMouseEvent *ev)
{
    Q_UNUSED(ev);
    if(mCanRemove){
        QWidget* pWAt = widgetAt(ev->pos());
        if(NULL != mpCurrentWidget){
            if(pWAt != mpCurrentWidget){
                mpCurrentWidget->setActionsVisible(false);
                update();
            }
        }
        mpCurrentWidget = dynamic_cast<UBActionableWidget*>(pWAt);
        if(NULL != mpCurrentWidget){
            mpCurrentWidget->setActionsVisible(true);
            update();
        }
    }
    update();
}

QWidget* UBWidgetList::widgetAt(QPoint p)
{
    QWidget* pW = NULL;
    pW = childAt(p);
    if(NULL != pW){
        do{
            if( "UBTeacherStudentAction" == pW->objectName() ||
                "UBUrlWidget" == pW->objectName() ||
                "UBTBMediaPicture" == pW->objectName() ||
                "UBMediaWidget" == pW->objectName()){
                return pW;
            }else{
                pW = pW->parentWidget();
            }
        }while(NULL != pW && this != pW);
    }

    return pW;
}

void UBWidgetList::updateSizes()
{
    // Resize all the widgets
    foreach(QWidget* eachWidget, mWidgetInfo.keys()){
        if(NULL != eachWidget){
            QSize originalSize = mWidgetInfo[eachWidget];
            int currentWidth = mpContainer->width();
            int currentHeight = mpContainer->height();
            if(eWidgetListOrientation_Vertical == mOrientation){
                if(verticalScrollBar()->isVisible()){
                    currentWidth -= verticalScrollBar()->width();
                    eachWidget->setStyleSheet(QString("margin-right:%0;").arg(verticalScrollBar()->width()));
                }
                float scaleFactor = (float)currentWidth/(float)originalSize.width();
                currentHeight = originalSize.height()*scaleFactor;
            }else{
                if(horizontalScrollBar()->isVisible()){
                    currentHeight -= horizontalScrollBar()->height();
                    eachWidget->setStyleSheet(QString("padding-bottom:%0;").arg(horizontalScrollBar()->height()));
                }
                float scaleFactor = (float)currentHeight/(float)originalSize.height();
                currentWidth = originalSize.width()*scaleFactor;
            }

            eachWidget->resize(currentWidth, currentHeight);
        }
    }
}

void UBWidgetList::setMargin(int margin)
{
    mMargin = margin;
}

int UBWidgetList::margin()
{
    return mMargin;
}

void UBWidgetList::setEmptyText(const QString &text)
{
    if(NULL != mpEmptyLabel){
        mpEmptyLabel->setText(text);
    }
}

bool UBWidgetList::empty()
{
    return mWidgetInfo.empty();
}
