'''
Created on May 31, 2014

@author: mandy
'''
from PyQt4.QtGui import QGraphicsTextItem, QGraphicsItem, QGraphicsEllipseItem, QColor, QBrush, QPen, QPainter, QFont
from PyQt4.QtCore import QObject, Qt, QRectF, QRect, QPointF
import math
import MyFunctions

class DirNode(QGraphicsEllipseItem):
    NODESIZE = 20
    NODE_BOUNDARY_SIZE = 20
    def __init__(self, directory, scene):
        QGraphicsEllipseItem.__init__(self)
        self.relativeX, self.relativeY = 0, 0
        self.rectContent = QRectF(-0.5*self.NODESIZE, -0.5*self.NODESIZE, self.NODESIZE, self.NODESIZE)
        self.rectbound = QRectF(-0.5*self.NODE_BOUNDARY_SIZE, -0.5*self.NODE_BOUNDARY_SIZE, self.NODE_BOUNDARY_SIZE, self.NODE_BOUNDARY_SIZE)
        self.setRect(self.rectContent)
        self.dir = directory
        self.scene = scene
        self.main = scene.main
        self.name = self.dir[self.dir.rfind('/'):]
        self.allparents = set()
        self.allchildren = set()
        self.parent = []
        self.children = []
        self.users = []
        self.roleNodes = []
        self.highlighted = False
        self.recursive = False
        self.color = QColor(255, 127, 127)
        self.penColor = QColor(127, 0, 0)
        self.labelColor = Qt.black
        self.recursiveColor = QColor(255, 0, 255)
        self.font = QFont("Calibri")
        self.font.setPixelSize(self.main.FONT_SIZE)
        '''border'''
        self.inheritHighlight = False
        self.boderColor = Qt.red
        self.inheritColor = Qt.darkBlue
        self.pen = QPen(self.boderColor)
        self.pen.setWidth(3.0)
        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        
    def paint(self, painter, option, widget=None):
        if self.main.mode == self.main.HIGHLIGHT_MODE:
            if self.highlighted:
#                 if self.recursive:
#                     self.color = self.recursiveColor
#                 else:
                self.color = QColor(255, 127, 127)
                self.penColor = QColor(127, 0, 0)
                self.labelColor = Qt.black
            else:
                self.color = Qt.gray
                self.penColor = Qt.darkGray
                self.labelColor = Qt.gray
        else:
            self.color = QColor(255, 127, 127)
            self.penColor = QColor(127, 0, 0)
            self.labelColor = Qt.black
        '''draw border'''
        self.paintBorder(painter)
        '''draw outline'''
        self.pen.setColor(self.penColor)
        self.pen.setWidth(3.0)
        self.setPen(self.pen)
        self.setBrush(self.color)
        painter.setRenderHint(QPainter.Antialiasing, True)
        QGraphicsEllipseItem.paint(self, painter, option, widget)
        '''display name as label'''
        self.pen.setColor(self.labelColor)
        painter.setPen(self.pen)
        painter.setFont(self.font)
        self.labelRect = painter.fontMetrics().boundingRect(self.name)
        self.labelRect = QRect(self.labelRect.x(), self.labelRect.y(), self.labelRect.width()+3, self.labelRect.height())
        x, y = self.computeLabelPos()
        self.paintLabel(painter, self.brush, x-5, y)
    
    def paintBorder(self, painter):
        if self.main.clickedNode == self or self in self.main.clickedRelatedNodes:
            if self.inheritHighlight:
                self.pen.setColor(self.inheritColor)
            else:
                self.pen.setColor(self.boderColor)
            painter.setPen(self.pen)
            r = self.boundingRect()
            painter.drawRect(QRect(r.x()-0.12*r.width(), r.y()-0.12*r.height(), 1.2*r.width(), 1.2*r.height()))
    
    def computeLabelPos(self):
        x = int(self.rect().bottomLeft().x()-(self.labelRect.width()))
        if self.children == []:
            y = int(self.rect().bottomLeft().y()-0.5*self.labelRect.height())
        else:
            y = int(self.rect().topLeft().y()-0.5*self.labelRect.height())
        return x, y
    
    def paintLabel(self, painter, oldbrush, x, y):
        rect = self.labelRect
        rect.moveTo(x, y)
        painter.drawText(rect, Qt.AlignLeft, self.name)
        
    '''mouse callback'''
    def toggleUserNodes(self):
        for r in self.roleNodes:
            for u in r.userNodes:
                if r.highlighted:
                    u.highlighted = True
                    if self.main.mode == self.main.HIGHLIGHT_MODE:
                        radius = r.extendUserRadius
                    else:
                        radius = self.main.roleUserNodeRadius
                else:
                    u.highlighted = False
                    radius = self.main.roleUserNodeRadius
                u.setPos(r.pos().x()+radius*math.cos(u.angle2Rolenode), r.pos().y()+radius*math.sin(u.angle2Rolenode))
    
    def highlightRoleNodes(self):
        for r in self.main.roleCompactNodes:
            r.highlighted = False
            for d in r.dirNodes:
                if d.highlighted:
                    r.highlighted = True
                    break
                          
    def mousePressEvent(self, event):
        if self.main.nodeMove and self.isSelected:
            for item in self.main.dirNodes:
                if item != self:
                    item.setSelected(False)
        if event.button() == Qt.LeftButton and (not self.main.nodeMove):
            for d in self.main.dirNodes:
                d.highlighted = False
                d.recursive = False
            self.main.toolBox.ui.noRHierRBtn.setEnabled(False)
            self.main.toolBox.ui.noRHierRBtn.setChecked(False)
            self.main.toolBox.ui.withRHierRBtn.setEnabled(False)
            self.main.toolBox.ui.withRHierRBtn.setChecked(True)
            self.main.toolBox.ui.roleHighlightSchemeGroupBox.setEnabled(False)
            self.main.toolBox.ui.roleParentHighlightRBtn.setChecked(True)
            QGraphicsEllipseItem.mousePressEvent(self, event)
            self.main.initiateItemsHightlightState()
            if self.main.mode == self.main.HIGHLIGHT_MODE:
                if self.highlighted:
                    '''highlight with no border'''
                    if self.main.clickedNode and (self.main.clickedNode == self or self.main.clickedNode not in self.main.dirNodes):
                        self.highlighted = False
                        self.main.clickedNode = None
                        self.main.clickedRelatedNodes = []
                    else:
                        '''highlight with border'''
                        self.main.policyManager.highlightNodeWithBorderDirNode(self)
                else:
                    '''if not highlighted, turn highlight on with border'''
                    self.main.policyManager.highlightNodeWithBorderDirNode(self)
                #self.highlightRoleNodes()
                self.main.policyManager.setUnclickedNodesGrey()
                self.main.updateAllUserNodes()
                self.main.setPermInfoInRoleHierView()
                self.main.checkMainMode()
            '''Collect user operation data'''
            if self.highlighted:
                message = "HView: Object("+ self.dir+ "): Clicked: Apply highlighting\n"
            else:
                message = "HView: Object("+ self.dir+ "): Clicked: Remove highlighting\n"
            self.main.writeToFile(self.main.logFile, self.main.getCurrentTimeString()+message)
            if self.main.specDialog.isVisible():
                self.main.specDialog.reGenerateSpec()
            self.main.showHintContent()
                
    def mouseReleaseEvent(self, event):
        QGraphicsEllipseItem.mouseReleaseEvent(self, event)
        self.relativeX = (self.pos().x()-self.main.scene.sceneRect().width())/self.main.sceneRight.sceneRect().width()
        self.relativeY = self.pos().y()/self.main.sceneRight.sceneRect().height()
        self.main.updateAllScenes()
        