'''
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 Oct 21, 2013

@author: mandy
'''
import re
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from Ui_TypeUserAssignDlg import Ui_TypeUserAssignDlg
from commonFunction import Functions
from TypeNode import TypeNode
from UserNode import UserNode
from ClearanceNode import ClearanceNode

try:
    _fromUtf8 = QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class TypeUserAssignDialog(QDialog):

    def __init__(self, scene):
        QDialog.__init__(self)
        self.type = False
        self.scene = scene
        self.ui = Ui_TypeUserAssignDlg()      
        self.ui.setupUi(self)
        self.setLayout(self.ui.verticalLayout)
        self.ui.labAssign = QLabel(self.ui.verticalLayoutWidget)
        self.ui.labAssign.setGeometry(QRect(10,10,130,20))
        self.ui.labAssign.setObjectName(_fromUtf8("labAssign"))
        self.ui.verticalLayout.addWidget(self.ui.labAssign)
        self.ui.leDir = QLineEdit(self.ui.verticalLayoutWidget)
        self.ui.leDir.setGeometry(QRect(10, 40, 130, 20))
        self.ui.leDir.setObjectName(_fromUtf8("leDir"))
        self.ui.verticalLayout.addWidget(self.ui.leDir)
        self.setFixedHeight(120)

        self.ui.btnOK = QPushButton('OK', self.ui.verticalLayoutWidget)
        self.ui.btnOK.setDefault(True)
        self.ui.btnOK.setGeometry(QRect(10, 70, 130, 20))
        self.ui.btnOK.setObjectName(_fromUtf8("btnOK"))
        self.ui.verticalLayout.addWidget(self.ui.btnOK)
        self.ui.btnOK.clicked.connect(self.confirm)
        
        flags = Qt.Dialog | Qt.WindowStaysOnTopHint
        self.setWindowFlags(flags)
    
    def updateUsrAssignSpec(self):
        self.scene.usrAssign = ''
        for u in self.scene.main.ioHelper.userNodes:
            clrname = u.clrNode.clearance+':'+':'.join(u.clrNode.category)
            self.scene.usrAssign += 'users '+clrname+' '+u.name+'\n'
        
    def updateTypeAssginSpec(self):
        self.scene.typeAssign = ''
        for t in self.scene.main.ioHelper.typeNodes:
            typeSpec = 'assign '+t.clearance+':'
            next = ''
            for c in t.category:
                next += c
                if c != t.category[-1]:
                    next+=':'
            next += ' '+Functions.flag2Option(t.flag)+' '
            for d in t.dir:
                next += d
                if d != t.dir[-1]:
                    next+=','
            typeSpec+=next+'\n'
            self.scene.typeAssign += typeSpec
     
    def assignType(self):
        self.type = True
        dir = ''
        self.ui.labAssign.setText('Assign Directory:')
        for t in self.scene.main.ioHelper.typeNodes:
            if t.clearance == self.scene.rightClickedItem.clearance and t.category == self.scene.rightClickedItem.category:
                dir = Functions.flag2Option(t.flag)
                if dir != '':
                    dir += ' '
                dir += ','.join(map(str, t.dir))+';'
                break
        self.ui.leDir.setText(dir)
        self.show()
        
    def assignUsers(self):
        if not isinstance(self.scene.rightClickedItem, ClearanceNode):
            return
        self.type = False
        self.ui.labAssign.setText('Assign Users:')
        if self.scene.rightClickedItem.relatedUsers == 'None':
            self.ui.leDir.setText('')
        else:
            self.ui.leDir.setText(self.scene.rightClickedItem.relatedUsers)
        self.show()

    def addTypeNode(self, assigned):
        assigned = str(assigned)
        assigned = assigned.replace(' ', '')
        assigned = assigned.replace('\t', '')
        clr = self.scene.rightClickedItem.clearance
        cate = self.scene.rightClickedItem.category
        for t in self.scene.main.ioHelper.typeNodes:
            if t.clearance == clr and t.category == cate:
                for f in self.scene.main.ioHelper.add2Scene.fileNodes:
                    if f.type == t:
                        if assigned.find(f.name)==-1:
                            f.parent.children.remove(f)
#                            for child in f.children:
#                                child.parent
                            self.scene.main.ioHelper.add2Scene.fileNodes.remove(f)
                            self.scene.removeItem(f)
                        else:
                            f.type = None
                self.scene.main.ioHelper.typeNodes.remove(t)
                self.scene.removeItem(t)
        clrNode = clr+':'
        for c in cate:
            clrNode+=c+':'
        clrNode = clrNode[:-1]

        if assigned.find('-') != -1:
            type = assigned[assigned.find('-'):assigned.find('/')]
        else:
            type = 0
        dir = assigned[assigned.find('/'):assigned.find(';')]
        dirList = dir.split(',')
    
        typeNode = TypeNode(self.scene.clearances, clr, cate)
        self.scene.main.ioHelper.getAssignedFlag(type, typeNode)
        typeNode.dir = dirList
        for d in dirList:
            typeNode.name = typeNode.clearance+',set(['
            for i in xrange(0, len(typeNode.category)):
                typeNode.name += "'" + typeNode.category[i] + "'"
                if i != len(typeNode.category)-1:
                    typeNode.name +=','
            typeNode.name += '])'
        self.scene.main.ioHelper.typeNodes.append(typeNode)
        self.scene.update()
        return typeNode
            
    def confirm(self):
        assigned = self.ui.leDir.text()
        if self.type:
            if len(assigned) == 0:
                QMessageBox.warning(self, '', 'Please input directories', buttons = QMessageBox.Close)
            else:
                if Functions.strDirsAssign(assigned):
                    v = self.addTypeNode(assigned)
                    self.scene.main.ioHelper.addTypeNode2Scene()
                    self.scene.main.ioHelper.createFileNodes(v)
                    self.scene.main.ioHelper.generateFileNodeParentChildren()
                    self.scene.main.ioHelper.buildFileNodeHierarchy()
                    self.updateTypeAssginSpec()
                    self.close()
                else:
                    QMessageBox.warning(self.scene.main, 'Error', 
                                     '[[-s|-r|-r -s] path1,...,pathN;]*', buttons = QMessageBox.Close)
        else:
            node = self.scene.rightClickedItem
            if node.relatedUsers!= 'None':
                node.userIcon = None
                for u in node.relatedUsers.split(','):
                    del self.scene.main.ioHelper.individualUserNode[u]
                for u in self.scene.main.ioHelper.userNodes:
                    if u[0] == node.relatedUsers:
                        self.scene.main.ioHelper.userNodes.remove(u)
                node.highlighted = False
                node.relatedUsers = 'None'
            if len(str(assigned)) != 0:
                if Functions.strNames(assigned):
                    nodeSecurityInfo = node.clearance+':'
                    for c in node.category:
                        nodeSecurityInfo+=c
                        if c != node.category[-1]:
                            nodeSecurityInfo+=':'
                    users = str(assigned).split(',')
                    usergroup = ''
                    for u in users:
                        if u in self.scene.main.ioHelper.individualUserNode.keys():
                            QMessageBox.warning(self,'Error', 'The user '+u+' already has a clearance level', buttons = QMessageBox.Close)
                        else:
                            usergroup += u+','
                            self.scene.main.ioHelper.individualUserNode.update({u:nodeSecurityInfo})
                            unode = UserNode(u, node, self.scene)
                            node.userNodes.add(unode)
                            self.scene.main.ioHelper.userNodes.append(unode)
                            self.scene.main.resizeEvent(None)
                    if usergroup!='':
                        Functions.connectUser2ClrNode(str(assigned), node)
                        self.updateUsrAssignSpec() 
                        self.close()             
                else:
                    QMessageBox.warning(self, 'Error', 'Please input a name that only contains letters and numbers', buttons = QMessageBox.Close)
            else:
                self.updateUsrAssignSpec() 
                self.close()
                self.scene.main.viewModeChanged(self.scene.main.ui.actionGeneral_Graph)
    
