'''
Accessible Access Control 1.0
2012-2104 Michigan Technological University
Supported in part by NSF grants: DUE-1140512, DUE-1245310 and IIS-1319363
Developer: Man Wang
Advisors:Dr. Steve Carr, Dr. Jean Mayo, Dr. Ching-Kuang Shene and Dr. Chaoli Wang
'''
'''
Created on Dec 20, 2011

@author: yifli
'''

from PyQt4.QtGui import QGraphicsLineItem, QMessageBox, QPen, QBrush, QInputDialog, QGraphicsItem, \
                        QPolygonF, QPainter, QPainterPath, QColor, QFontMetricsF
from PyQt4.QtCore import Qt,QLineF, QPointF
from ClearanceNode import ClearanceNode
from TypeNode import TypeNode
from UserNode import UserNode
import math
import re
import string

class EdgeItem(QGraphicsLineItem):
    CLR_CONN = 0
    USER_CONN = 1
    TYPE_CONN = 2
    FILE_CONN = 3
    GRUP_CONN = 4
    
    def __init__(self, type, start, end):
        QGraphicsLineItem.__init__(self)
        self.arrowSize = 15
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.type = type
        self.startItem = start
        self.endItem = end
        self.description = ''
        self.setZValue((-1000.0))
        self.highlighted = False
        self.highlightedWrite = False
        self.setVisible(False)
        self.lineWidth = 1.0
        self.color = QColor(180,180,180,255)
        self.arrowHead = QPolygonF()
        
    def shape(self):
        angle = self.line().angle()
        if angle < 0:
            angle += 360
        angle -= 90
        angle = math.pi * angle / 180.0
        xTrans = 4 * math.cos(angle)
        yTrans = 4 * math.sin(angle)
        lower_line = self.line().translated(-xTrans,-yTrans)
        upper_line = self.line().translated(xTrans, yTrans)
        path = QPainterPath(upper_line.p1())
        path.lineTo(lower_line.p1())
        path.lineTo(lower_line.p2())
        path.lineTo(upper_line.p2())
        path.lineTo(upper_line.p1())
        path.addPolygon(self.arrowHead)
        '''
        if isinstance(self.endItem, UserNode):
            return path
        else:
            path.addPolygon(self.arrowHead)
            return path
        '''
        return path
    
    def paint(self, painter, option, widget=None):
        if self.type != self.USER_CONN:
            self.setVisible(True)
            
        painter.setRenderHint(QPainter.HighQualityAntialiasing)
        
        '''
        if self.type == self.AUTO_CONN or self.type == self.TYPE_CONN or self.type == self.FILE_CONN:
            pen = QPen(Qt.SolidLine)
            if self.type == self.AUTO_CONN:
                pen.setWidth(2.0)
        else:
        '''
        
        pen = QPen(Qt.SolidLine)
        pen = QPen(self.color)
        pen.setWidth(self.lineWidth)
            
        if self.highlighted:
            #pen.setStyle(Qt.DashLine)
            #pen.setColor(QColor(0, 0, 255))
            pen.setColor(QColor(255, 153, 102))
            #pen.setColor(QColor(0, 0, 0))
            pen.setWidth(3.0*self.lineWidth)
        
        if self.highlightedWrite:
            #pen.setStyle(Qt.DotLine)
            #pen.setColor(QColor(255, 0, 0))
            pen.setColor(QColor(0, 204, 255))
            pen.setWidth(3.0*self.lineWidth)

        painter.setPen(pen)
        painter.setBrush(QBrush(self.color))
        #painter.setBrush(QBrush(Qt.black))
        
        if isinstance(self.endItem, ClearanceNode) and self.type != self.GRUP_CONN:#isinstance(self.endItem, TypeNode):
            centerline = QLineF(self.startItem.pos(), self.endItem.pos())
            startRect = self.endItem.boundingRect()
            endRect = self.endItem.boundingRect()
            
            # test the intersection between centerline and startRect
            p1 = startRect.topLeft() + self.startItem.pos()
            p2 = startRect.bottomLeft() + self.startItem.pos()
            intersection1 = QPointF()
            intersectType = QLineF(p1,p2).intersect(centerline, intersection1)
            if intersectType != QLineF.BoundedIntersection:
                p1 = p2
                p2 = startRect.bottomRight() + self.startItem.pos()
                intersectType = QLineF(p1,p2).intersect(centerline, intersection1)
                if intersectType != QLineF.BoundedIntersection:
                    p1 = p2
                    p2 = startRect.topRight() + self.startItem.pos()
                    intersectType = QLineF(p1, p2).intersect(centerline, intersection1)
                    if intersectType != QLineF.BoundedIntersection:
                        p1 = p2
                        p2 = startRect.topLeft() + self.startItem.pos()
                        intersectType = QLineF(p1, p2).intersect(centerline, intersection1)
                        if intersectType != QLineF.BoundedIntersection:
                            return
             
            intersection1 = (p1+p2) / 2.0  

            # test the intersection between centerline and endRect
            p1 = endRect.topLeft() + self.endItem.pos()
            p2 = endRect.bottomLeft() + self.endItem.pos()
            intersection2 = QPointF()
            intersectType = QLineF(p1,p2).intersect(centerline, intersection2)
            if intersectType != QLineF.BoundedIntersection:
                p1 = p2
                p2 = endRect.bottomRight() + self.endItem.pos()
                intersectType = QLineF(p1,p2).intersect(centerline, intersection2)
                if intersectType != QLineF.BoundedIntersection:
                    p1 = p2
                    p2 = endRect.topRight() + self.endItem.pos()
                    intersectType = QLineF(p1, p2).intersect(centerline, intersection2)
                    if intersectType != QLineF.BoundedIntersection:
                        p1 = p2
                        p2 = endRect.topLeft() + self.endItem.pos()
                        intersectType = QLineF(p1, p2).intersect(centerline, intersection2)
                        if intersectType != QLineF.BoundedIntersection:
                            return
            
            intersection2 = (p1+p2) / 2.0  
            self.setLine(QLineF(self.startItem.pos(), intersection2))
            
            
            #if isinstance(self.endItem, ClearanceNode):
            verts = []
            verts.append(intersection2)
            angle = math.acos(self.line().dx() / self.line().length())
            if self.line().dy() >= 0:
                angle = 2*math.pi - angle
                
            verts.append( self.line().p2() +   QPointF(-math.cos(angle + math.pi / 12) * self.arrowSize,
                                                     math.sin(angle + math.pi / 12) * self.arrowSize)
                         )
            verts.append( self.line().p2() + QPointF(-math.cos(angle - math.pi / 12) * self.arrowSize,
                                                     math.sin(angle - math.pi / 12) * self.arrowSize)
                         )
            
            self.arrowHead = QPolygonF(verts)
            painter.drawPolygon(self.arrowHead)        
        else:
            self.setLine(QLineF(self.startItem.pos(), self.endItem.pos()))
        # drawing
        painter.drawLine(self.line())
    
        
    def updatePosition(self):
        line = QLineF(self.mapFromItem(self.startItem, QPointF(0, 0)), self.mapFromItem(self.endItem, QPointF(0, 0)))
        self.setLine(line)
        
        