"""
* Copyright (c) 2009 Stanford University, School of Medicine All rights reserved. 
* 
* STANFORD ACADEMIC SOFTWARE LICENSE AGREEMENT 
* FOR AngioLocalize SOURCE CODE: 
* 
* 1.  This is a legal agreement between you, RECIPIENT, and STANFORD UNIVERSITY.  
*       By accepting, receiving, and using AngioLocalize.including any accompanying information, materials or 
*       manuals (Program), you are agreeing to be bound by the terms of this Agreement.  
*       If you do not agree to the terms of this Agreement, promptly return the Program to the STANFORD.

* 2.  STANFORD grants to RECIPIENT a royalty-free, nonexclusive, and nontransferable license to use the Program 
*       and accompanying source code furnished hereunder, upon the terms and conditions set out below. 
*       documentation and/or other materials provided with the distribution. 
* 3.  RECIPIENT acknowledges that the Program is a research tool still in the development stage and that 
*       it is being supplied as is, without any accompanying services, support or improvements from STANFORD.
* 4.  RECIPIENT agrees to use the Program solely for internal non-commercial purposes. 
* 5.  RECIPIENT may create derivatives and further transfer the Program under the following terms and conditions: 
*        A) Recipient agrees to not commercially exploit the Program and agrees all uses will be for non-commercial purposes; and,
*        B) Recipient may not mark any derivatives with the title of Program and may not to use iPad mark for any derivatives; and,
*        C) Recipient agrees to mark and acknowledge all derivatives as follows: "This is a derivative work based on AngioLocalize:
*           Frameless AVM localization with 2D Digital Subtraction Angiography (DSA) and 3D Rotational Angiography (DRA) Images developed
*           by Dimitre Hristov, Lina Liu.
*        D) Recipient agrees to make all improvements, enhancements and derivatives available under 
*           similar terms and conditions to the research community. 
* 6.   RECIPIENT warrants that RECIPIENT will not remove or export any part of the software or Program from the United 
*       States except in full compliance with all United States and other applicable laws and regulations.
* 7.  RECIPIENT will use the Program in compliance with all applicable laws, policies and regulations including, but not 
*       limited to, any approvals, informed consent and patient confidentiality principles.
* 8.   RECIPIENT will indemnify, hold harmless, and defend Stanford against any claim of any kind arising out of or
*       related to the exercise of any rights granted under this Agreement or the breach of this Agreement by RECIPIENT.
* 9.  Title and copyright to the Program and any associated documentation shall at all times remain with STANFORD, 
*       and RECIPIENT agrees to preserve same.
""" 
#----------------------------------------------------------------------------------
#! Macro module Localization
#/*!
# \file    Localization.py
# \author  dimitre
# \date    2009-02-17
#
# 
#*/
#----------------------------------------------------------------------------------


from mevis import *
from PythonQt import *
from linear import *


## Global variables
wind = None;
proj_matrix1=matrix();
postProjAffine1=matrix();
proj_matrix2=matrix();
postProjAffine2=matrix();

## send a query to the Database and return the result set
def sendQuery(query):
  ctx.field("DBConn.Statement").setValue(query);
  dbModule = ctx.module("DBConn");
  result = dbModule.call("sendQuery");
  if (result == -1):
    MLAB.logError("The following query to database failed. \n" + query + "\n.");
  dbModule.call("close");
  return result;

## this function is used to init projection Matrix1 and affineMatrix1
def initProjection1():
  global proj_matrix1; 
  global postProjAffine1;
  
  proj_matrix1=matrix.fromSeq(proj_matrix1,ctx.field("projectionMatrix1").value);
  postProjAffine1=postProjAffine1.fromSeq(ctx.field("AffinePostProjMatrix1").value);

## This function is used to init projectMatrix2 and affineMatrix2 parameter
def initProjection2():
  global proj_matrix2;
  global postProjAffine2;
  
  proj_matrix2=matrix.fromSeq(proj_matrix2,ctx.field("projectionMatrix2").value);
  postProjAffine2=postProjAffine2.fromSeq(ctx.field("AffinePostProjMatrix2").value);

## poject the cursor from 3D to 2D image 
def projectCursor():
  global proj_matrix1; 
  global postProjAffine1;
  cursor=vec3(ctx.field("TargetView3D.worldPosition").value);
  projcursor=proj_matrix1.multMatrixVec(cursor);
  z=projcursor.__getitem__(2);
  projcursor=projcursor.__div__(z);
  projcursor=postProjAffine1.multMatrixVec(projcursor);
  ctx.field("SoView2DPosition1.worldPosition").setValue(projcursor[0],projcursor[1],projcursor[2]);
  global proj_matrix2; 
  global postProjAffine2;
  cursor=vec3(ctx.field("TargetView3D.worldPosition").value);
  projcursor=proj_matrix2.multMatrixVec(cursor);
  z=projcursor.__getitem__(2);
  projcursor=projcursor.__div__(z);
  projcursor=postProjAffine2.multMatrixVec(projcursor);
  ctx.field("SoView2DPosition2.worldPosition").setValue(projcursor[0],projcursor[1],projcursor[2]);   

## display the CSO
def structureDisplay():
# Toggles Structure (CSO) drawing
  selection=ctx.field("StructureToggleSelection.lastSelectedId").value;
  if selection == 'CSO_on':
    ctx.field("StructureEditToggle.i01showItem").value=False;
    ctx.field("StructureEditToggle.i02showItem").value=True;
    ctx.field("CSO3DEditor.editingOn").value = False;
    ctx.field("CSO3DEditor.editingOn").value = False;
  elif selection == 'CSO_off':
    ctx.field("StructureEditToggle.i02showItem").value=False;
    ctx.field("StructureEditToggle.i01showItem").value=True;
    ctx.field("CSO3DEditor.editingOn").value = True ;
    ctx.field("CSO3DEditor.editingOn").value = True ;
    
def update3DOverlay():
# Update the overlay since there is a new registration matrix.
# The matrix should be changed after the corresponding image is loaded
# A proper message should be logged
  print "update 3D Overaly"

## display the CSOManager panel
def showCSOManager():
  global wind;
  if (ctx.field("showCSOM").value == True):
    wind = ctx.module("StructureManager").showWindow();
  else:
    if (wind != None):
       wind.close();

## save CSO to a file
def saveCSOToFile():
  ctx.connectField("StructureSave.inCSOList", "StructureManager.outCSOList");
  targetImage = ctx.parent().field("ImgLoad3DTarget.filename").value;
  dirIndex = targetImage.rfind("\\");
  fileName = targetImage[dirIndex + 1: len(targetImage)-4] + ".cso"; 
  CSOName = getCSODir(ctx.parent().field("PatientID").value, fileName);
  ctx.field("StructureSave.fileName").setValue(CSOName);
  ctx.field("StructureSave.apply").touch();
  MLAB.log("Structure :" + fileName + " has been saved.");
  return CSOName;

## save CSO to file and database
def saveCSO():
  CSOName = saveCSOToFile();
  CSOName = CSOName.replace("\\","/");
  newID = saveCSOToDB(CSOName);
  saveApprovalStatus(0, newID);
  ctx.disconnectField("StructureSave.inCSOList");
  ctx.field("updateCSOList").touch();

## check if CSO Structure exists or not
def ApprovalSExist(objID):
   ID = 0;
   dbM = ctx.module("DBConn");
   query = "select userID from approvals where objID = " + str(objID) + " and objType = 1;";
   result = sendQuery(query);
   if (result == "()"):
     return ID;
   for item in result:
     ID = item["userid"];
   return ID;

## save the approval status of a CSO
def saveApprovalStatus(approvalS, objID):
  if(ApprovalSExist(objID) == 0):
    query = "INSERT INTO approvals(userID, objID, patientID, approvalStatus, objType) values(1, " + str(objID) + ","+ getPatientRecordID(ctx.parent().field("PatientID").value) + "," + str(approvalS) + ", 1);";
  else:
    query = "Update approvals set approvalStatus = " + str(approvalS) + " where objID = " + str(objID) + " and objType = 1; ";
  result = sendQuery(query);

## check if a CSO Exist or not
def CSOExist(refImage):
  num = 0;
  query = "select CSOId from CSOlist where srcImage = " + str(refImage) + ";";
  result = sendQuery(query);
  if (result == "()"):
    return num;
  for item in result:
    num = item["csoid"];
  return num;

## save CSO to the database.
def saveCSOToDB(CSOName):
  PatientRecID = getPatientRecordID(ctx.parent().field("PatientID").value);
  refImage = ctx.parent().field("TargetImgID").value;
  CSOExistVar = False;
  if (CSOExist(refImage) == 0):  
    query = "INSERT INTO CSOLIST (filename, patientID, srcImage) VALUES('" + CSOName + "'," + str(PatientRecID) + "," + refImage + ");";
  else:
    CSOExistVar = True; 
    query = "Update CSOList set filename = '" + CSOName + "' WHERE srcImage = " + refImage + ";";
  result = sendQuery(query);
  if (result == -1):
    return;
  query = "select CSOId as newID from CSOList where srcImage = " + refImage + ";";
  result = sendQuery(query);
  if (result == "()"):
    return;
  MLAB.log("Structure " + CSOName + " has been saved.");
  return result[0]["newid"];

## get the patient Record ID with given MRO 
def getPatientRecordID(MRO):
  query = "SELECT PatientID from Patients where MRO = '" + MRO + "';";
  result = sendQuery(query);
  patientID = 0;
  if (result == "()"):
    return str(patientID);
  for item in result:
    patientID = item["patientid"];
  return str(patientID);

## save and approve the CSO
def saveAndApproval():
  CSOName = saveCSOToFile();
  CSOName = CSOName.replace("\\","/");
  newID = saveCSOToDB(CSOName);
  saveApprovalStatus(1, newID);
  ctx.disconnectField("StructureSave.inCSOList");
  closePanel();

## close the panel
def closePanel():
  ctx.field("StructureManager.removeAllCSOsAndGroups").touch();
  ctx.field("updateCSOList").touch();
  ctx.field("closeP").touch();

## trigger the showSelection field
def selection():
  ctx.field("showSelection").touch();

## hide or show the 3D target
def hide3DTarget():
  hideTgt = ctx.field("hideTarget").value;
  if (hideTgt):
    ctx.field("showTarget").setValue(False);
  else:
    ctx.field("showTarget").setValue(True);
  ctx.field("showTarget").touch();

## hide or show 3D source
def hide3DSource():
  hideSrc = ctx.field("hideSource").value;
  if(hideSrc):
    ctx.field("showSource").setValue(False);
  else:
    ctx.field("showSource").setValue(True);
  ctx.field("showSource").touch();

## combine the source and target 
def combineSrcTgt():
  combine = ctx.field("combineSrcTgt").value;
  if(combine):
    ctx.field("showSource").setValue(False);
    ctx.field("showSource").touch();
    ctx.connectField("TargetView3D.inInvPreLUT", "SourceOverlay3D.outScene");
    ctx.field("showTarget").setValue(True);
    ctx.field("showTarget").touch();
    ctx.field("showTargetSrc").setValue(True);
  else:
    ctx.disconnectField("TargetView3D.inInvPreLUT");
    ctx.field("showTargetSrc").setValue(False);
    hide3DSource();
    hide3DTarget();

## toggle the drawing on Image2D1
def toggleDrawingonImage2D1():
  CSOName = saveCSOToFile();
  newID = saveCSOToDB(CSOName);
  saveApprovalStatus(0, newID);
  ctx.disconnectField("StructureSave.inCSOList");
  ctx.field("StructureLoad.fileName").setValue(CSOName);
  ctx.connectField("StructureManager.inCSOList", "StructureLoad.outCSOList");
  ctx.field("StructureLoad.apply").touch();
  toggle = ctx.field("image1Check").value;
  if(toggle):
    ctx.field("SoView2DCSOEditor1.drawingOn").setValue(False);
  else:
    ctx.field("SoView2DCSOEditor1.drawingOn").setValue(True);

## toggle the drawing on Image2D2
def toggleDrawingonImage2D2():
  CSOName = saveCSOToFile();
  newID = saveCSOToDB(CSOName);
  saveApprovalStatus(0, newID);
  ctx.disconnectField("StructureSave.inCSOList");
  ctx.field("StructureLoad.fileName").setValue(CSOName);
  ctx.connectField("StructureManager.inCSOList", "StructureLoad.outCSOList");
  ctx.field("StructureLoad.apply").touch();
  
  toggle = ctx.field("image2Check").value;
  if(toggle):
    ctx.field("SoView2DCSOEditor2.drawingOn").setValue(False);
  else:
    ctx.field("SoView2DCSOEditor2.drawingOn").setValue(True);

## show help for the module
def help():
  ctx.showHtmlHelp();

#//# MeVis signature v1
#//# key: MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBANEfsmYse2e1dRhkQ9AQbreCq9uxwzWLoGom13MNYmyfwoJqQOEXljLFAgw2eEjaT12G4CdqKWhRxh9ANP6n7GMCARE=:VI/mB8bT4u+mRtf/ru8yUQi8BzpaS3UeL2x62YxsUYnVqCWuLrVNLiukIIjnJMKQXlc8ezmgOIcVAV7pgvgKpQ==
#//# owner: MeVis
#//# date: 2009-06-10T04:12:25
#//# hash: vHSfj+Qt8xrIkDVP4W0Rep0YH6a3+MySa0+Cs+AoqEK/IbB+f5szwmyVTENOjzz/JEgm2t31FtHmUUMFcQg5VQ==
#//# MeVis end

