/*

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include <QDebug>
#include <QtGui>

#include "wire.h"
#include <math.h>

const qreal Pi = 3.14;

//constructor. A start and an endpoint is needed for each wire
Wire::Wire(LogicUnit *startUnit, LogicUnit *endUnit,
          QGraphicsItem *parent, QGraphicsScene *scene):QGraphicsLineItem(parent, scene)
{
    myStartUnit = startUnit;
    myEndUnit = endUnit;
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    //set default color to black, can later be used to highlight selected items
    myColor = Qt::black;
    mySafeColor = Qt::black;

    //The values for an turned on and turned off wire
   // wireOff = QColor(0,0,255);
    wireOn = QColor(255,0,0);

    //penwidth can be used to show "active" wires after simulation
    myPenwidth = 3;

    setPen(QPen(myColor,myPenwidth,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    //myNumber is always set by the logic block wich creates it. 0 is default until setNumber is called
    myNumber=0;
    myMaxNumber = 0;
    //output position which is needed for hord blocks
    myOutPinNumber = 1;
    myOutPinMax = 1;

    //module position params
    myNumberModule = 0;
    myMaxNumberModule = 0;
    myOutPinNumberModule = 1;
    myOutPinMaxModule = 1;

    //activity estimation
    activity = 0;

    hasStartModule = false;
    hasEndModule = false;
}

/*---------------------------------------------------------------------------------------------
 * (function: type)
 *-------------------------------------------------------------------------------------------*/
int Wire::type() const
{
    return Type;
}

/*---------------------------------------------------------------------------------------------
 * (function: boundingRect)
 *-------------------------------------------------------------------------------------------*/
//calculate the bounding rect to tell the graphics view where to update
QRectF Wire::boundingRect() const
{
    qreal extra = (pen().width()+20)/2.0;

    return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(),
                                      line().p2().y() - line().p1().y()))
        .normalized()
        .adjusted(-extra, -extra, extra, extra);
}
/*---------------------------------------------------------------------------------------------
 * (function: shape)
 *-------------------------------------------------------------------------------------------*/
QPainterPath Wire::shape() const
{
//    QPainterPath path = QGraphicsLineItem::shape();
//    return path;

    QLineF myLine = line();
    QPainterPath path;
    qreal x1, x2, y1,y2;
    x1 = myLine.p1().x();
    x2=myLine.p2().x();
    y1=myLine.p1().y();
    y2=myLine.p2().y();

    //define corner points for rectangular connections
    path.moveTo(x1,y1);
    path.lineTo(x1+(x2-x1)/2,y1);
    path.moveTo(x1+(x2-x1)/2,y1);
    path.lineTo(x1+(x2-x1)/2,y2);
    path.moveTo(x1+(x2-x1)/2,y2);
    path.lineTo(x2,y2);

    return path;
}

/*---------------------------------------------------------------------------------------------
 * (function: setColor)
 *-------------------------------------------------------------------------------------------*/
//changes the color of the wire
void Wire::setColor(const QColor &color)
{
    myColor = color;
    mySafeColor = color;
}

/*---------------------------------------------------------------------------------------------
 * (function: startUnit)
 *-------------------------------------------------------------------------------------------*/
LogicUnit * Wire::startUnit() const
{
    return myStartUnit;
}

/*---------------------------------------------------------------------------------------------
 * (function: endUnit)
 *-------------------------------------------------------------------------------------------*/
LogicUnit * Wire::endUnit() const
{
    return myEndUnit;
}
/*---------------------------------------------------------------------------------------------

 * (function: updatePosition)
 *-------------------------------------------------------------------------------------------*/
void Wire::updatePosition()
{

    if(!myStartUnit->isVisible() && !startFromModule()){
        setVisible(false);
    }else if(!myEndUnit->isVisible() && !endOnModule()){
        setVisible(false);
    }else{
        setVisible(true);
    }

    LogicUnit* start;
    LogicUnit* end;
    int number, maxnumber, outnumber, outmaxnumber;
    if(endOnModule()){
        number = myNumberModule;
        maxnumber = myEndModule->getMaxNumber();
        end = myEndModule;
    } else {
        number = myNumber;
        maxnumber = myMaxNumber;
        end = myEndUnit;
    }

    if(startFromModule()){
        outnumber = myOutPinNumberModule;
        outmaxnumber = myStartModule->getMaxOutNumber();
        start = myStartModule;
    }else{
        outnumber = myOutPinNumber;
        outmaxnumber = myOutPinMax;
        start = myStartUnit;
    }

    //draw line according to start and end positions
    double inputPosition = ((float)number)/(maxnumber+1);
    inputPosition = inputPosition*100;
    double outputPosition = ((float)outnumber)/(outmaxnumber+1);
    outputPosition = outputPosition*100;
    QLineF line(mapFromItem(start,50,outputPosition-50),mapFromItem(end,-50,inputPosition-50));
    setLine(line);

    update();
//    QLineF line(mapFromItem(myStartUnit,50,0),mapFromItem(myEndUnit,-50,0));
//    setLine(line);
}

/*---------------------------------------------------------------------------------------------
 * (function: paint)
 *-------------------------------------------------------------------------------------------*/
//the most important function, which draws the wire
void Wire::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    //if the modules collide, do not paint a connection
    if(myStartUnit->collidesWithItem(myEndUnit))
    {
        return;
    }

    //if connection can be drawn
    QPen myPen = pen();
    myPen.setColor(myColor);
    myPen.setWidthF(myPenwidth);
    painter->setPen(myPen);
    painter->setBrush(myColor);

    //draw
    //painter->drawLine(line());
    if(isSelected())
    {
        painter->setPen(QPen(myColor,1,Qt::DashLine));
    }

    //line consists of multiple lines

    QPainterPath path;
    path = shape();


    //diagonal line
//    QLineF myLine = line();
//    painter->drawLine(myLine);

    //rectangular lines (have to be improved)
    painter->drawPath(path);


}

/*---------------------------------------------------------------------------------------------
 * (function: setNumber)
 *-------------------------------------------------------------------------------------------*/
void Wire::setNumber(int number)
{
    myNumber = number;
    updatePosition();
}

/*---------------------------------------------------------------------------------------------
 * (function: setMaxNumber)
 *-------------------------------------------------------------------------------------------*/
void Wire::setMaxNumber(int maxnumber)
{
    //if max number was adjusted, adjust your parameters and the position
    myMaxNumber = maxnumber;
    updatePosition();
}

/*---------------------------------------------------------------------------------------------
 * (function: undateWireStatus)
 *-------------------------------------------------------------------------------------------*/
/* Updates the width of the Wire according to the output the Wire is connected to*/
void Wire::updateWireStatus()
{
    int status;
    status = myStartUnit->getOutValue(myOutPinNumber);

    if(status==0){
        //myPenwidth = wireOff;
        myColor = mySafeColor;
    } else if(status == 1){
        myColor = QColor(wireOn.red(),mySafeColor.green(),mySafeColor.blue());;
        //myColor = mySafeColor;
    }else{
        //myPenwidth = wireOn;
        myColor = QColor(mySafeColor.red(),255,mySafeColor.blue());
    }
    update();

}

/*---------------------------------------------------------------------------------------------
 * (function: getMyCount)
 *-------------------------------------------------------------------------------------------*/
int Wire::getMyCount()
{
    return myNumber;
}

/*---------------------------------------------------------------------------------------------
 * (function: getMaxCount)
 *-------------------------------------------------------------------------------------------*/
int Wire::getMaxCount()
{
    return myMaxNumber;
}

/*---------------------------------------------------------------------------------------------
 * (function: getMyOutputPinNumber)
 *-------------------------------------------------------------------------------------------*/
int Wire::getMyOutputPinNumber()
{
    return myOutPinNumber;
}

/*---------------------------------------------------------------------------------------------
 * (function: getMaxOutputPinNumber)
 *-------------------------------------------------------------------------------------------*/
int Wire::getMaxOutputPinNumber()
{
    return myOutPinMax;
}

/*---------------------------------------------------------------------------------------------
 * (function: setMyOutputPinNumber)
 *-------------------------------------------------------------------------------------------*/
void Wire::setMyOutputPinNumber(int number)
{
    myOutPinNumber = number;
    updatePosition();
}

/*---------------------------------------------------------------------------------------------
 * (function: setMaxOutputPinNumber)
 *-------------------------------------------------------------------------------------------*/
void Wire::setMaxOutputPinNumber(int number)
{
    myOutPinMax = number;
    updatePosition();
}

/*---------------------------------------------------------------------------------------------
 * (function: getMyInputPosition)
 *-------------------------------------------------------------------------------------------*/
QPointF Wire::getMyInputPosition()
{
    double i = ((float)myNumber)/(myMaxNumber+1);
    i = i*100;
    //QLineF line(mapFromItem(myStartUnit,50,0),mapFromItem(myEndUnit,-50,i-50));
    return QPointF(-50,i-50);
}

int Wire::getActivity()
{
    return activity;
}

void Wire::setActivity(int value)
{
    activity = value;
}

void Wire::showActivity()
{
    myColor = QColor(activity,255-activity,0);
}

void Wire::setStartModule(LogicUnit *start)
{
    myStartModule = start;
    hasStartModule = true;
}

void Wire::setEndModule(LogicUnit *end)
{
    myEndModule = end;
    hasEndModule = true;
}

LogicUnit * Wire::getStartModule()
{
    return myStartModule;
}

LogicUnit * Wire::getEndModule()
{
    return myEndModule;
}

bool Wire::startFromModule(){
    if(!startUnit()->isVisible() && hasStartModule){
        if(myStartModule->isVisible()){
            return true;
        }
    }

    return false;
}

bool Wire::endOnModule(){
    bool c1 = !endUnit()->isVisible();
    bool c2 = hasEndModule;
    if(!endUnit()->isVisible() && hasEndModule){
        if(myEndModule->isVisible()){
            return true;
        }
    }

    return false;
}

void Wire::setNumberModule(int number)
{
    myNumberModule = number;
}

void Wire::setMaxNumberModule(int maxnumber)
{
    myMaxNumberModule = maxnumber;
}

int Wire::getMyCountModule()
{
    return myNumberModule;
}

int Wire::getMaxCountModule()
{
    return myMaxNumberModule;
}

int Wire::getMyOutputPinNumberModule()
{
    return myOutPinNumberModule;
}

int Wire::getMaxOutputPinNumberModule()
{
    return myOutPinMaxModule;
}

void Wire::setMyOutputPinNumberModule(int number)
{
    myOutPinNumberModule = number;
}

void Wire::setMaxOutputPinNumberModule(int number)
{
    myOutPinMaxModule = number;
}
