/***************************************************************************
 *   Copyright (C) 2007 by Håvard Frøiland                                 *
 *   havard@student.unsw.edu.au                                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#include "ktouchtextlinewidget.h"
#include "ktouchtextlinewidget.moc"

#include "prefs.h"

#include <QPainter>

KTouchTextLineWidget::KTouchTextLineWidget(QWidget *parent)
  : QGraphicsView( parent )
{
    scene = new QGraphicsScene(parent);

    teacher = new QGraphicsSimpleTextItem();
    teacherRect = new QGraphicsPathItem();
    teacherRect->setZValue(-1);

    scene->addItem(teacher);
    scene->addItem(teacherRect);

    student = new QGraphicsSimpleTextItem();
    studentRect = new QGraphicsPathItem();
    studentRect->setZValue(-1);

    scene->addItem(student);
    scene->addItem(studentRect);

    cursor = new QGraphicsLineItem();
    cursor->setZValue(1);
    cursor->setPen(QPen(QBrush(Qt::black), 2));
    scene->addItem(cursor);

    animationTimer = new QTimer(this);

    cursorTimer = new QTimer(this);
    cursorTimer->setInterval(500);

    setScene(scene);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setRenderHint(QPainter::Antialiasing);

    setBackgroundBrush(palette().brush(QPalette::Window));
    setFrameStyle(QFrame::NoFrame);

    connect(animationTimer, SIGNAL(timeout()), this, SLOT(recalculatePosition()));
    connect(cursorTimer, SIGNAL(timeout()), this, SLOT(toggleCursor()));

    direction = parent->layoutDirection();

    applyPreferences();
}

KTouchTextLineWidget::~KTouchTextLineWidget() {
}

void KTouchTextLineWidget::applyPreferences() {
    setMaximumHeight(Prefs::maxSlidingWidgetHeight());

    if (Prefs::overrideLectureFont())
        font = Prefs::font();

    updateColor();

    animationTimer->setInterval(100 - Prefs::slidingSpeed());

    recalculateSize();
}


void KTouchTextLineWidget::setTeacherText(const QString& text) {
    direction = text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight;
    setLayoutDirection( direction );
    teacher->setText(text);
    recalculateSize();
    setStudentText("");
}


void KTouchTextLineWidget::setStudentText(const QString& text) {
    student->setText(text);
    double studentTextWidth = student->boundingRect().width();
    double teacherTextWidth = teacher->boundingRect().width();

    if(direction == Qt::LeftToRight)
        cursor->setPos(studentTextWidth, 0);
    else
    {
        cursor->setPos(teacherTextWidth - studentTextWidth, 0);
        student->setPos(teacherTextWidth - studentTextWidth, teacher->boundingRect().height() + 5);
    }

    updateColor();
    animationTimer->start();
}

void KTouchTextLineWidget::updateColor() {

   if (Prefs::commonTypingLineColors()) {
        teacher->setBrush(QBrush(Prefs::teacherTextColor()));
        teacherRect->setBrush(QBrush(Prefs::teacherBackgroundColor()));

        if(Prefs::colorOnError() && !teacher->text().startsWith(student->text())){
            studentRect->setBrush(QBrush(Prefs::errorBackgroundColor()));
            student->setBrush(QBrush(Prefs::errorTextColor()));
        }
        else{
            studentRect->setBrush(QBrush(Prefs::studentBackgroundColor()));
            student->setBrush(QBrush(Prefs::studentTextColor()));
        }
    }
    else {
        teacher->setBrush(QBrush(Qt::black));
        teacherRect->setBrush(QBrush(Qt::white));

        if(Prefs::colorOnError() && !teacher->text().startsWith(student->text())){
            studentRect->setBrush(QBrush(Prefs::errorBackgroundColor()));
            student->setBrush(QBrush(Prefs::errorTextColor()));
        }
        else{
            studentRect->setBrush(QBrush(Qt::white));
            student->setBrush(QBrush(Qt::blue));
        }
    }
}

void KTouchTextLineWidget::setFont(const QFont& f) {
    if (Prefs::overrideLectureFont())
        font = Prefs::font();
    else
        font= f;
}

void KTouchTextLineWidget::recalculateSize(){
    font.setPointSize(height()/4);
    teacher->setFont(font);

    QRectF rect = teacher->boundingRect();

    student->setFont(font);

    studentRect->setPath(roundedRectPathFactory(rect.x()-5, rect.y(), rect.width()+10, rect.height(), qMin(rect.height(), rect.width())/2));
    teacherRect->setPath(roundedRectPathFactory(rect.x()-5, rect.y(), rect.width()+10, rect.height(), qMin(rect.height(), rect.width())/2));

    if(direction == Qt::LeftToRight){
        cursor->setLine(2,rect.height() + 5  + 5, 2,rect.height() * 2 + 5 - 10);
        cursor->setPos(student->boundingRect().width(), 0);
        student->setPos(0, rect.height() + 5);
    }
    else{
        cursor->setLine(-2,rect.height() + 5  + 5, -2,rect.height() * 2 + 5 - 10);
        cursor->setPos(teacher->boundingRect().width() - student->boundingRect().width(), 0);
        student->setPos(teacher->boundingRect().width() - student->boundingRect().width(), rect.height() + 5);
    }

    studentRect->setPos(0, rect.height() + 5);

    animationTimer->start();
}

void KTouchTextLineWidget::recalculatePosition() {
    double padding = 40;
    double maxPos = teacher->boundingRect().width();

    double studentWidth = student->boundingRect().width();

    double ration = studentWidth/maxPos;
    double diff = maxPos - width();

    double wantedPos;
    if(diff < -padding){
        wantedPos = diff/2;
    }
    else{
        if(direction == Qt::LeftToRight)
            wantedPos = diff * ration - (padding * (1 - (2*ration)));
        else
            wantedPos = diff - (diff * ration - (padding * (1 - (2*ration))));
    }
    pos = pos + (wantedPos - pos) / 5;

    setSceneRect(pos, 0 , width(), height());

    if(qAbs(wantedPos - pos)<1)
        animationTimer->stop();
}

void KTouchTextLineWidget::setActive(bool active){
    if(active)
        cursorTimer->start();
    else
    {
        cursorTimer->stop();
        cursor->setVisible(true);
    }
}

void KTouchTextLineWidget::toggleCursor(){
    cursor->setVisible(!cursor->isVisible());
}

QPainterPath KTouchTextLineWidget::roundedRectPathFactory(double x, double y, double width, double height, double rounded){
    QPainterPath roundRectPath;
    roundRectPath.moveTo(width+x, y+rounded/2);
    roundRectPath.arcTo(width+x-rounded, y, rounded, rounded, 0.0, 90.0);
    roundRectPath.lineTo(x+rounded/2, y);
    roundRectPath.arcTo(x, y, rounded, rounded, 90.0, 90.0);
    roundRectPath.lineTo(x, height+y-rounded/2);
    roundRectPath.arcTo(x, height+y-rounded, rounded, rounded, 180.0, 90.0);
    roundRectPath.lineTo(width+x-rounded/2, height+y);
    roundRectPath.arcTo(width+x-rounded, height+y-rounded, rounded, rounded, 270.0, 90.0);
    roundRectPath.closeSubpath();
    return roundRectPath;
}
