var myCmiWindow;
var statusText;
var cmiCanvas;
var toolTip;
var leftAssemblyBrowser;
var leftBomBrowser;
var rightAssemblyBrowser;
var cmpCtxMenu=null;
var multiCmpCtxMenu=null;
var mainModelCtxtMenu=null;
var annCtxtMenu=null;
var bomContextMenu=null;
var bomPropContextMenu=null;
var chatContextMenu=null;
var leftBrowserContextMenu=null;

var currentHighlightedEntity=null;
var currentCutDirection="Left";

var layerBrowser;
var leftModel=null;
var rightModel=null;
var currentModel=null;
var compareMode = false;

var measDlgVisible=false;
var mouseMode = "rotate";
var pickPoints = new Array();
var modelDisplayed = false;

var modelAnimations = new Array();

var currentMaterialSetRef = null;
var currentMaterialSetCopy = null;
var missingTextures = new Array();
var interactionMode = "";
var selectedEntity = null;
var reverseCompareColor = false;
var isMated = false;
var deltaMateOrigin = null;
var deltaMateAngle = null;
var videoElement;
var videoStream;

var isDeviceTrackingActive = false;
var deviceMode = "";
var viewingMode = "3d";
var prevHeadAngles = new Array(0.0,0.0,0.0);
var headAngles = new Array(0.0,0.0,0.0);
var savedHeadAngles = new Array(0.0,0.0,0.0);

var explosionAnimationLeft = null;
var explosionAnimationRight = null;
var mateAnimation=null;
var viewAnimation=null;
var locatorAnimation=null;
var currentModelAnimation = null;
var lastStartedAnimation = "";
var instructionAnimation = null;
var sensorAnimation = null;
var locateAnimation = null;
var currentHighlightedComponents = null;

var currentImageTexture = null;
var currentAnnotationName = "";

var currentPageNr = 1;
var multiPageDocument = null;
var multiPageTifArray = null;
var multiPageType = "";
var measurementScale = 1.0;
var pageCount = 0;
var pdfOutlineCheck = 0;
var pdfResolutionTimer = null;

var isModelRotationPoint = true;
var modelNameFromZip = "";

var toolTipDistance = 20;
var docToOpenUrl = "";
var portalSettings = null;
var vertexLocator = null;
var vertexSelected = false;

var nacl=null;


function cmiWindowStart()
{
  var bgColor3D = [87,97,107];
  var cmpColor3D = [255,255,0,77];

  var queryString = decodeURIComponent(window.location.search);
  queryString = queryString.substring(1);
  var queries = queryString.split("&");
  var qValue="";
  var langFromCaller = false;
  var docToOpenUrl = "";
  var fileToOpenUrl = "";
  var docAccessKey = "";
  var dbIdToOpen = "";
  var dbAccessUrl = "";
  var isEmbedded = false;
  var hostOrigin = "";

  statusText = document.getElementById("StatusText");
  cmiCanvas = document.getElementById("CmiCanvas");
  toolTip = document.getElementById("ToolTippText");
  videoElement = document.getElementById("VideoElement");
  videoStream = null;

  poi3dConnector.registerCallback("updateModelAnnotations",updateModelAnnotations);
  poi3dConnector.registerCallback("updateModelInstructions",updateModelInstructions);
  poi3dConnector.registerCallback("updateModelSensors",updateModelSensors);
  poi3dConnector.registerCallback("updateModelLocations",updateModelLocations);
  poi3dConnector.registerCallback("updateModelMaterialSets",updateModelMaterialSets);
  poi3dConnector.registerCallback("updateModelFileAttachments",updateModelFileAttachments);
  poi3dConnector.registerCallback("updateBomStructures",updateBomStructures);
  poi3dConnector.registerCallback("showDialog",showDialog);
  poi3dConnector.registerCallback("updatePortalUi",updatePortalUi);
  poi3dConnector.registerCallback("resetViewer",resetViewer);
  poi3dConnector.registerCallback("setStatusText",setStatusText);
  poi3dConnector.registerCallback("externalDocumentLoaded",externalDocumentLoaded);

  portalSettings = poi3dConnector.getPortalConfiguration();

  //load user setting
  poi3dConnector.getUserSettingsFromLocalStorage();

  //handle parameters
  for (var i = 0; i < queries.length; i++)
  {
    qValue = queries[i].split("=");
    if(qValue[0]=="lang")
    {
      poi3dConnector.getUserSettings().uiLanguage = qValue[1];
      langFromCaller = true;
    }
    else if(qValue[0]=="skin")
    {
      let colScheme = qValue[1];

      var el = document.querySelector('body');

      if(colScheme == "light")
        el.setAttribute('data-theme', 'light');
      else if(colScheme == "dark")
        el.setAttribute('data-theme','dark');
      else if(colScheme == "gray")
        el.setAttribute('data-theme','gray');

      poi3dConnector.getUserSettings().colorScheme = colScheme;
    }
    else if(qValue[0]=="accessKey")
      docAccessKey = qValue[1];
    else if(qValue[0]=="docUrl")
      docToOpenUrl = qValue[1];
    else if(qValue[0]=="fileUrl")
      fileToOpenUrl = qValue[1];
    else if(qValue[0]=="dbId")
      dbIdToOpen = qValue[1];
    else if(qValue[0]=="embedded")
      isEmbedded=true;
    else if(qValue[0]=="hostOrigin")
      hostOrigin = qValue[1];
    else if(qValue[0]=="dbAccess")
      dbAccessUrl = qValue[1];
  }//for (var i = 0; i < queries.length; i++)

  //override language settings from system language
  if(langFromCaller == false)
  {
    let userLang = (navigator.language) ? navigator.language : navigator.userLanguage;
    let langId = userLang.split('-')[0];
    poi3dConnector.getUserSettings().uiLanguage=langId;
  }

  //initialize webGL window
  myCmiWindow = new CmiWindow("CmiCanvas");
  if(myCmiWindow.isUsable)
  {
    if(myCmiWindow.checkWebGlUsage() < 0)
    {
      setStatusText(myCmiWindow.getLastError().message);
      Poi3dHelpers.setDisplayStyle("bodyContainer","block");
      return;
    }
    poi3dConnector.setCmiWindowReference(myCmiWindow);

    myCmiWindow.setBgColorRGB(bgColor3D[0],bgColor3D[1],bgColor3D[2]);
    myCmiWindow.setCompareColorRGB(cmpColor3D[0],cmpColor3D[1],cmpColor3D[2]);
    myCmiWindow.setCompareTransparency(cmpColor3D[3]/255);
    myCmiWindow.setBgText(portalSettings.bgTxt);
    myCmiWindow.colGradient =false;
    myCmiWindow.useTransparentBackground = true;

    myCmiWindow.setBgTextScale(0.4);
    myCmiWindow.useMinimumStartupImageLoad = true;
    myCmiWindow.handleDeviceAngles = true;
    myCmiWindow.longTouchDuration = 700;

    mainModelCtxtMenu = document.getElementById("mainModelCtxtMenuArea");
    cmpCtxMenu = document.getElementById("cmpCtxMenuArea");
    multiCmpCtxMenu = document.getElementById("multiCmpCtxMenuArea");
    annCtxtMenu = document.getElementById("annCtxtMenuArea");
    bomContextMenu = document.getElementById("bomContextMenuArea");
    bomPropContextMenu = document.getElementById("doBoPropContextMenuArea");
    chatContextMenu = document.getElementById("chatContextMenuArea");
    leftBrowserContextMenu = document.getElementById("leftAsmBrContextMenuArea");

    if(myCmiWindow.initWebGlWindow() < 0)
    {
      setStatusText(myCmiWindow.getLastError().message);
      Poi3dHelpers.setDisplayStyle("bodyContainer","block");
      return;
    }

    myCmiWindow.useTransparentBackground = false;
    myCmiWindow.useSkyBoxBackground = false;
    myCmiWindow.setEyeDistance4StereoRendering(0.1);

    myCmiWindow.setNotificationHandler(onCmiNotification);
    myCmiWindow.handleArrowKeys = false;
    myCmiWindow.createComponentInfoCallback = setComponentInfo;
    myCmiWindow.minSizeForBoxDisplay = 20;

    myCmiWindow.locatorPointSize = 15;
    myCmiWindow.setLocatorBitmapName("./Poi3d/Images/sphere.png");
    myCmiWindow.initDepthRendering();
    myCmiWindow.initSelectionRendering();
    handleSelectionSettings();
    myCmiWindow.currentCommand = "";

    myCmiWindow.switchToOrtho(true);
    myCmiWindow.setMouseModeToRotation();
    myCmiWindow.setFixedLightPos4FirstPersonView(true);
    //myCmiWindow.ownColor = false;
    myCmiWindow.clipPlaneActive = false;
    //myCmiWindow.useModelDirectoryForBitmapLocation = false;

    currentModel = myCmiWindow.getCmiModel();

    leftAssemblyBrowser = new CmiAssemblyBrowser("leftAssemblyBrowser","leftAssemblyTable");
    leftAssemblyBrowser.setCollectSameNamesFlag(false);
    leftAssemblyBrowser.setUseModelAsTopNodeFlag(2);
    leftAssemblyBrowser.setInteractiveBrowserFlag(false);
    leftAssemblyBrowser.setSortFlag("p");
    leftAssemblyBrowser.setShowPosNrFlag(true);

    rightAssemblyBrowser = new CmiAssemblyBrowser("rightAssemblyBrowser","rightAssemblyTable");
    rightAssemblyBrowser.setCollectSameNamesFlag(false);
    rightAssemblyBrowser.setUseModelAsTopNodeFlag(2);
    rightAssemblyBrowser.setInteractiveBrowserFlag(false);
    rightAssemblyBrowser.setSortFlag("p");
    rightAssemblyBrowser.setShowPosNrFlag(true);

    showRightTable(poi3dConnector.getUserSettings().showRightBrowser);
    showLeftTable(poi3dConnector.getUserSettings().showLeftBrowser);

    layerBrowser = new CmiLayerBrowser("layerBrowser","leftLayerTable");

    leftBomBrowser = new CmiAssemblyBrowser("leftBomBrowser","leftBomTable");
    leftBomBrowser.setCmiWindow(myCmiWindow);
    leftBomBrowser.setCollectSameNamesFlag(false);
    leftBomBrowser.setUseModelAsTopNodeFlag(2);
    leftBomBrowser.setInteractiveBrowserFlag(false);
    leftBomBrowser.setSortFlag("p");
    leftBomBrowser.setShowPosNrFlag(true);

    mateAnimation = new CmiAnimation(myCmiWindow,60);
    viewAnimation = new CmiAnimation(myCmiWindow,60);
    explosionAnimationLeft = new CmiAnimation(myCmiWindow, 60);
    explosionAnimationRight = new CmiAnimation(myCmiWindow, 60);
    locatorAnimation=new CmiAnimation(myCmiWindow,60);
    currentModelAnimation = new CmiAnimation(myCmiWindow,60);
    instructionAnimation =  new CmiAnimation(myCmiWindow,60);
    locateAnimation =  new CmiAnimation(myCmiWindow,60);
    sensorAnimation =  new CmiAnimation(myCmiWindow,60);

    document.addEventListener('keyup', handleKeyInput);
    document.addEventListener("contextmenu", handleConextMenuEvent);
    document.getElementById("CmiCanvas").addEventListener("click", handleKeyInput);
    document.getElementById("CmiCanvas").addEventListener("contextmenu", handleCenterContextMenuEvent);
    document.getElementById("propDlg_DoBoPropTab").addEventListener("contextmenu", handleBomPropContextMenuEvent);
    document.getElementById("propDlg_DoBoPropTab").addEventListener("touchstart", Poi3dHelpers.touchDown);
    document.getElementById("propDlg_DoBoPropTab").addEventListener("touchend", Poi3dHelpers.touchUp);
    document.getElementById("commDlg_chatContent").addEventListener("contextmenu", handleChatContextMenuEvent);
    document.getElementById("commDlg_chatContent").addEventListener("touchstart", Poi3dHelpers.touchDown);
    document.getElementById("commDlg_chatContent").addEventListener("touchend", Poi3dHelpers.touchUp);
    document.getElementById("leftTableContent").addEventListener("contextmenu", handleLeftBrowserContextMenuEvent);
    document.getElementById("leftTableContent").addEventListener("touchstart", Poi3dHelpers.touchDown);
    document.getElementById("leftTableContent").addEventListener("touchend", Poi3dHelpers.touchUp);
    document.getElementById("leftBomTableContent").addEventListener("contextmenu", handleBomContextMenuEvent);
    document.getElementById("leftBomTableContent").addEventListener("touchstart", Poi3dHelpers.touchDown);
    document.getElementById("leftBomTableContent").addEventListener("touchend", Poi3dHelpers.touchUp);

    if(myCmiWindow.isMobileEnvironment == true)
    {
      toolTipDistance = 80;
      cmiCanvas.addEventListener('dblclick', handleDoubleClick);

      //no download on mobile devices
      var mnuElements = document.querySelectorAll("#DownloadConverterMenu");
      for(let i=0; i<mnuElements.length; i++)
        mnuElements[i].style.display = "none";
    }

    Poi3dHelpers.setDisplayStyle("dragArea","none");
    initBrowserDragbars();

    if(poi3dConnector.isPoi3dEnv() == false)
    {
      let uiTxtElements = document.querySelectorAll("#GetAuthorRightsMenu");
      for (i=0; i<uiTxtElements.length; i++)
        uiTxtElements[i].style.display = "none";
    }

    updatePortalUi();
    document.getElementById("backgroundArea").innerHTML = "";
    Poi3dHelpers.setDisplayStyle("bodyContainer","block");//Show UI

    resizeWindow(true);
    applySettings();
    poi3dConnector.initializeAccess();

    //post load additional ressources -------------------------

    //libs for document loading
    let modulePackage1 = new Array();
    modulePackage1.push({mLoc:"Poi3d/Scripts/Poi3dDocumentLoader.js",loadFct:function()
    {
      Poi3dDocumentLoader.setPoi3dAdapter(poi3dConnector);
      Poi3dDocumentLoader.setCmiWindow(myCmiWindow);
    }});
    modulePackage1.push({mLoc:"Poi3d/3rdParty/Zip/jszip.min.js",loadFct:null});
    modulePackage1.push({mLoc:"Poi3d/3rdParty/Zip/jszip-utils.min.js",loadFct:null});
    modulePackage1.push({mLoc:"Poi3d/3rdParty/pdfjs/build/pdf.mjs",loadFct:function()
    {
      var { pdfjsLib } = globalThis;
      pdfjsLib.GlobalWorkerOptions.workerSrc = 'Poi3d/3rdParty/pdfjs/build/pdf.worker.mjs';
    }});
    modulePackage1.push({mLoc:"Poi3d/3rdParty/Tiff/UTIF.js",loadFct:null});
    modulePackage1.push({mLoc:"Poi3d/3rdParty/exifr/full.umd.js",loadFct:null});
    modulePackage1.push({mLoc:"CmiScripts/CmiGeometryCreation.js",loadFct:null});
    modulePackage1.push({mLoc:"CmiScripts/CmiProductStructure.js",loadFct:null});

    loader1 = new Poi3dModuleLoader(modulePackage1);
    loader1.loadParallel = false;
    loader1.versionString = poi3dVersion;
    loader1.afterLoadFunction = function()
    {
      if(docToOpenUrl.length > 0)
        Poi3dDocumentLoader.openLeftDocumentFromExternalStorage(docToOpenUrl);
      else if(fileToOpenUrl.length > 0)
          Poi3dDocumentLoader.createLeftDocumentFromFileUrl(fileToOpenUrl);
      else if(dbIdToOpen.length > 0)
        Poi3dDocumentLoader.createLeftDocumentFromBrowserDbId(dbIdToOpen,dbAccessUrl);
      else if (docAccessKey.length > 0)
        Poi3dDocumentLoader.openLeftDocumentByAccessKey(docAccessKey);
    };
    loader1.loadModules();

    //other libs
    let modulePackage2 = new Array();
    modulePackage2.push({mLoc:"Poi3d/3rdParty/ImageGallery/swiper-bundle.min.css",loadFct:null});
    modulePackage2.push({mLoc:"Poi3d/3rdParty/ImageGallery/swiper-bundle.min.js",loadFct:null});
    modulePackage2.push({mLoc:"Poi3d/3rdParty/js-nacl-1.4.0/lib/nacl_factory.js",loadFct:function()
    {
      nacl_factory.instantiate( function(e) { nacl = e; } );
    }});

    loader2 = new Poi3dModuleLoader(modulePackage2);
    loader2.loadParallel = false;
    loader2.versionString = poi3dVersion;
    loader2.loadModules();

    if(isEmbedded == true)
    {
      var hostInterface = document.createElement('script');
      hostInterface.onload = function ()
      {
        Poi3dHostInterface.setHostOrigin(hostOrigin);
        Poi3dHostInterface.setPoi3dAdapter(poi3dConnector);
        Poi3dHostInterface.sendMessageToHost("PortalLoaded",poi3dConnector.getVersionString());
      }
      hostInterface.src = "Poi3d/Scripts/Poi3dHostInterface.js";
      document.head.appendChild(hostInterface);
    }

  }//if(myCmiWindow.isUsable)
}
function applySettings()
{
  myCmiWindow.useFrontAsTop = poi3dConnector.getUserSettings().useFrontAsTop;
  handleSelectionSettings();
  poi3dConnector.translate();

  document.querySelector('body').setAttribute('data-theme', poi3dConnector.getUserSettings().colorScheme);
  var cmpColor3D = getComputedStyle(document.querySelector('body')).getPropertyValue('--CmpCol3d').match(/\d+/g).map(Number);
  var bgColor3D = getComputedStyle(document.querySelector('body')).getPropertyValue('--MainBgCol').match(/\d+/g).map(Number);
  myCmiWindow.setBgColorRGB(bgColor3D[0],bgColor3D[1],bgColor3D[2]);
  myCmiWindow.setCompareColorRGB(cmpColor3D[0],cmpColor3D[1],cmpColor3D[2]);
  myCmiWindow.drawScene();
}

function handlePageReload()
{
  if(poi3dConnector.getPoi3dUser().isLoggedIn() == true)
    poi3dConnector.logOff();
}

function handleKeyInput(e)
{
  mainModelCtxtMenu.style.display = "none";
  cmpCtxMenu.style.display = "none";
  multiCmpCtxMenu.style.display = "none";
  annCtxtMenu.style.display = "none";
  bomContextMenu.style.display = "none";
  bomPropContextMenu.style.display = "none";
  leftBrowserContextMenu.style.display = "none";

  if((e.code == "PageDown")&&(multiPageDocument != null))
  {
    showPage("+");
  }
  else if((e.code == "PageUp")&&(multiPageDocument != null))
  {
    showPage("-");
  }
  else if(e.code == "Escape")
  {
    toolTip.style.display = "none";
    currentHighlightedEntity = null;

    switch(interactionMode)
    {
      case "snsPosPick":
      case "ipPick":
      case "ipPickEdit":
      case "crcPick":
      case "crcPickEdit":
      case "platePick":
      case "platePickEdit":
      case "areaPick":
      case "areaPickEdit":
      case "spherePick":
      case "spherePickEdit":
      case "taPick":
      case "taPickEdit":
      case "labPick":
      case "labPickEdit":
      case "tiPick":
      case "tiPickEdit":
      case "calPick":
      case "matPick":
      case "measureDist":
      case "measureAng":
      case "measureRad":
      case "selectInBrowser":
      case "selectToEdit":
      case "selectToDelete":
        interactionMode = "";
        handleSelectionSettings();
        switchMouseMode("rotate");
        setStatusText("");
        break;
    }
  }
}
function handleCenterContextMenuEvent(ev)
{
  var posX=0;
  var posY=0;

  if(ev.targetTouches)
  {
    posX = ev.changedTouches[0].clientX;
    posY = ev.changedTouches[0].clientY;
  }
  else
  {
    posX = ev.clientX;
    posY = ev.clientY;
  }
  handleCenterContextMenu(posX,posY);

  ev.preventDefault();
}

function handleCenterContextMenu(posX,posY)
{
  let attRights = poi3dConnector.getCurrentAttachmentRights();
  let hlCmps = myCmiWindow.getCmiModel().getHighlightedComponents();

  if(toolTip)
  {
    toolTip.style.display = "none";
    cmiCanvas.style.cursor = "default";
  }

  if(currentHighlightedEntity == null)//main model
  {
    mainModelCtxtMenu.style.left=posX-10+"px";
    mainModelCtxtMenu.style.top=posY-20+"px";
    mainModelCtxtMenu.style.display = "block";
    openMulti('MmContextMnu');
  }
  else if(hlCmps.length > 1)
  {
    multiCmpCtxMenu.style.left=posX-10+"px";
    multiCmpCtxMenu.style.top=posY-20+"px";
    multiCmpCtxMenu.style.display = "block";
    openMulti('MultiCmpContextMnu');
  }
  else if(currentHighlightedEntity.getClassName() == "cmiComponentObject")
  {
    cmpCtxMenu.style.left=posX-10+"px";
    cmpCtxMenu.style.top=posY-20+"px";
    cmpCtxMenu.style.display = "block";
    openMulti('CmpContextMnu');
  }
  else if
    (
    (isAnnotation(currentHighlightedEntity))&&
    (viewingMode.includes("AR") == false)&&
    (attRights[1] == "crud")
    )
  {
    annCtxtMenu.style.left=posX-10+"px";
    annCtxtMenu.style.top=posY-20+"px";
    annCtxtMenu.style.display = "block";
    openMulti('AnnContextMnu');
  }
}

function handleBomContextMenuEvent(ev)
{
  let attRights = poi3dConnector.getCurrentAttachmentRights();
  if(attRights[5] == "crud")
  {
    var posX=0;
    var posY=0;

    if(ev.targetTouches)
    {
      posX = ev.changedTouches[0].clientX;
      posY = ev.changedTouches[0].clientY;
    }
    else
    {
      posX = ev.clientX;
      posY = ev.clientY;
    }
    ev.preventDefault();

    var tableRow = ev.composedPath()[2];
    var comp = leftBomBrowser.getComponentFromTableRow(tableRow);
    if(comp == null)
      comp = leftBomBrowser.getComponentFromTableRow(getRowUnderClick(ev.target,posY));

    if(comp != null)
    {
      var cmpArray = new Array(comp);
      leftBomBrowser.highlightComponents(cmpArray);
    }

    var components = leftBomBrowser.getHighlightedComponents(true);
    if(components.length > 0)
    {
      bomContextMenu.style.left=posX-10+"px";
      bomContextMenu.style.top=posY-20+"px";
      bomContextMenu.style.display = "block";
      openMulti('BomContextMnu');
    }
  }
};

function handleBomPropContextMenuEvent(ev)
{
  let attRights = poi3dConnector.getCurrentAttachmentRights();
  if(attRights[5] == "crud")
  {
    var posX=0;
    var posY=0;

    if(ev.targetTouches)
    {
      posX = ev.changedTouches[0].clientX;
      posY = ev.changedTouches[0].clientY;
    }
    else
    {
      posX = ev.clientX;
      posY = ev.clientY;
    }

    ev.preventDefault();

    var cell = ev.target.closest('th');
    if (!cell)
      cell = ev.target.closest('td');
    if (cell)
    {
      propDlg.clickedBomCol = cell.cellIndex;
      propDlg.enableCellEdit = false;
    }

    bomPropContextMenu.style.left=posX-10+"px";
    bomPropContextMenu.style.top=posY-20+"px";
    bomPropContextMenu.style.display = "block";
    openMulti('DoBoPropContextMnu');
  }
}

function handleChatContextMenuEvent(ev)
{
  let attRights = poi3dConnector.getCurrentAttachmentRights();
  if(attRights[0] == "crud")
  {
    var posX=0;
    var posY=0;

    if(ev.targetTouches)
    {
      posX = ev.changedTouches[0].clientX;
      posY = ev.changedTouches[0].clientY;
    }
    else
    {
      posX = ev.clientX;
      posY = ev.clientY;
    }
    ev.preventDefault();

    var row = ev.target.closest('tr');
    if((row==null)||(row == undefined))
      row = getRowUnderClick(ev.target,posY)
      
    if (row)
    {
      commDlg.clickedChatRow = row.rowIndex;
    }

    chatContextMenu.style.left=posX-10+"px";
    chatContextMenu.style.top=posY-20+"px";
    chatContextMenu.style.display = "block";
    openMulti('ChatContextMnu');
  }
}
function getRowUnderClick(tbody, clickY)
{
  const tbodyRect = tbody.getBoundingClientRect();
  const rows = Array.from(tbody.querySelectorAll('tr'));

  for (let i = 0; i < rows.length; i++)
  {
    const row = rows[i];
    const rowRect = row.getBoundingClientRect();

    if (clickY >= rowRect.top && clickY <= rowRect.bottom) {
      return row;
    }
  }
  return null;
}

function handleLeftBrowserContextMenuEvent(ev)
{
  var posX=0;
  var posY=0;

  if(ev.targetTouches)
  {
    posX = ev.changedTouches[0].clientX;
    posY = ev.changedTouches[0].clientY;
  }
  else
  {
    posX = ev.clientX;
    posY = ev.clientY;
  }
  ev.preventDefault();

  var tableRow = ev.composedPath()[2];
  var comp = leftAssemblyBrowser.getComponentFromTableRow(tableRow);
  if(comp == null)
    comp = leftAssemblyBrowser.getComponentFromTableRow(getRowUnderClick(ev.target,posY));

  if(comp != null)
  {
    var cmpArray = new Array(comp);
    leftAssemblyBrowser.switchHighlightStateForAll(false);
    leftAssemblyBrowser.highlightComponents(cmpArray);
    currentHighlightedEntity = comp;
    myCmiWindow.drawScene();

    leftBrowserContextMenu.style.left=posX-10+"px";
    leftBrowserContextMenu.style.top=posY-20+"px";
    leftBrowserContextMenu.style.display = "block";
    openMulti('LAsmBrContextMnu');
  }
}
function handleLeftBrowserCtxCommand(cmd)
{
  switch(cmd)
  {
    case "LAsmBrCtxShowPropCmd":
      showPropDlg(null,[currentHighlightedEntity],"model",null);
      break;
    case "LAsmBrCtxSlInstCmd":
      if(currentHighlightedEntity != null)
      {
        let components = null;
        components = leftAssemblyBrowser.searchComponentInstances(currentHighlightedEntity);
        leftAssemblyBrowser.switchHighlightStateForAll(false);
        leftAssemblyBrowser.highlightComponents(components);

        components = leftBomBrowser.searchComponentInstances(currentHighlightedEntity);
        leftBomBrowser.switchHighlightStateForAll(false);
        leftBomBrowser.highlightComponents(components);

        myCmiWindow.drawScene();
      }
      break;
    case "LAsmBrCtxLocateCmd":
      let showColor = myCmiWindow.getHighlightColor();
      let components = leftAssemblyBrowser.getHighlightedComponents(true);
      if(components.length > 0)
        myCmiWindow.zoomToEntity(components[0]);

      runShowComponentAnimation(components,locateAnimation,"locateAnimation",5,showColor,0.2);
      break;
  }
}

function runShowComponentAnimation(components, animation, animationName, blinkCount, blinkColor, blinkPause)
{
  currentHighlightedComponents = leftAssemblyBrowser.getHighlightedComponents(true);

  leftAssemblyBrowser.switchHighlightStateForAll(false);
  leftBomBrowser.switchHighlightStateForAll(false);

  let entitiesToHide = leftModel.getEntitiesByType(["cmiGrepObject","cmiComponentObject"]);

  let componentsToBringInFront = new Array();
  let parentComponent=null;
  for ( let i =0; i< components.length; i++)
  {
    componentsToBringInFront.push(components[i]);
    parentComponent = components[i].getParentComponent();
    while(parentComponent != null)
    {
      if(componentsToBringInFront.some(item => item !== parentComponent))
      {
        componentsToBringInFront.push(parentComponent);
        parentComponent = parentComponent.getParentComponent();
      }
      else
        parentComponent=null;
    }
  }

  var hideColor3D = getComputedStyle(document.querySelector('body')).getPropertyValue('--CmpCol3d').match(/\d+/g).map(Number);
  hideColor3D[0]=hideColor3D[0]/255;
  hideColor3D[1]=hideColor3D[1]/255;
  hideColor3D[2]=hideColor3D[2]/255;
  hideColor3D[3]=hideColor3D[3]/255;

  var frontColor3D = getComputedStyle(document.querySelector('body')).getPropertyValue('--MainBgCol').match(/\d+/g).map(Number);
  frontColor3D[0]=1.0-frontColor3D[0]/255;
  frontColor3D[1]=1.0-frontColor3D[1]/255;
  frontColor3D[2]=1.0-frontColor3D[2]/255;
  frontColor3D[3]=0.3;

  myCmiWindow.selectionEnabled = false;
  leftAssemblyBrowser.switchHighlightStateForAll(false);
  leftBomBrowser.switchHighlightStateForAll(false);
  lastStartedAnimation = animationName;
  animation.clearAnimation(false,true);
  animation.addEntityColorSetting(entitiesToHide,[hideColor3D[0],hideColor3D[1],hideColor3D[2],hideColor3D[3]],"depthOff");
  animation.addEntityColorSetting(componentsToBringInFront,[frontColor3D[0],frontColor3D[1],frontColor3D[2],frontColor3D[3]],"depthOn");

  for ( var i =0; i< blinkCount; i++)
  {
    animation.addEntityColorSetting(components,[blinkColor[0],blinkColor[1],blinkColor[2],1.0]);
    animation.addPause(blinkPause*2);
    animation.addEntityColorSetting(components,[0.5,0.5,0.5]);
    animation.addPause(blinkPause*2);
  }
  animation.run(1);
}

function handleConextMenuEvent(ev)
{
  ev.preventDefault();
}
function handleSensorClick(sensorObj)
{
  let attRights = poi3dConnector.getCurrentAttachmentRights();
  if(attRights[6] == "crud")
    showDefSnsDlg(null,sensorObj);
}
function handleSensorHover(sensorObj)
{
  if(toolTip) toolTip.style.display = "none";
}
function handleDoubleClick(e)
{
  if(viewingMode.includes("VR"))
  {
    if(mouseMode == "move")
      switchMouseMode('zoom');
    else if(mouseMode == "zoom")
      switchMouseMode('move');
  }
}
function handleSelectionSettings()
{
  switch(myCmiWindow.getCurrentMouseMode())
  {
    case "select":
      myCmiWindow.makeAllTypesSelectable();
      myCmiWindow.selectionEnabled = true;

      if((interactionMode == "selectToEdit")||(interactionMode == "selectToDelete"))
        myCmiWindow.makeTypeInselectable("cmiComponentObject");
      return;
    case "pick":
      myCmiWindow.makeAllTypesSelectable();
      myCmiWindow.selectionEnabled = true;
      if((interactionMode == "selectToEdit")||(interactionMode == "selectToDelete"))
        myCmiWindow.makeTypeInselectable("cmiComponentObject");
      return;
  }

  if(viewingMode.includes("AR"))
  {
    myCmiWindow.selectionEnabled = false;
  }
  else if(viewingMode.includes("VR"))
  {
    myCmiWindow.selectionEnabled = true;

    if(poi3dConnector.getUserSettings().useDynamicVrSelection == true)
      myCmiWindow.makeAllTypesSelectable();
    else
      myCmiWindow.makeTypeInselectable("cmiComponentObject"); // only annotations are selectable
  }
  else
  {
    myCmiWindow.selectionEnabled = true;

    if(poi3dConnector.getUserSettings().useDynamicStdSelection == true)
      myCmiWindow.makeAllTypesSelectable();
    else
      myCmiWindow.makeTypeInselectable("cmiComponentObject"); // only annotations are selectable
  }
}

// ========================================== Callbacks ====================================
function showDialog(dlg,param1,param2)
{
  switch(dlg)
  {
    case "ModelSelectionDialog":
      showModSelDlg(null,param1);
      break;
    case "LoginDialog":
      showLoginDlg(null);
      break;
    case "MessageDialog":
      showMsgDlg(null,param1);
      break;
    case "YesNoDialog":
      showYesNoDlg(null,param1,param2);
      break;
    case "RegisterUserDialog":
      showRegUserDlg(null,param1);
      break;
  }
};

function externalDocumentLoaded(poi3dDocument)
{
  myCmiWindow.currentCommand = "OpenMod";
  Poi3dDocumentLoader.loadPrimaryDocument(myCmiWindow,poi3dDocument);
  poi3dConnector.setCurrentWgOrCatalog(null);
};
function isAnnotation (cmiEntity)
{
  if((cmiEntity != null)&&(cmiEntity.entityName != undefined)&&(cmiEntity.entityName.includes("ann")))
    return true;
  else
    return false;
};
function updatePortalUi()
{
  let attRights = poi3dConnector.getCurrentAttachmentRights();
  let usrRights = poi3dConnector.getCurrentUserRights();

  //user rights
  if(usrRights[0] == "0")//comparison
  {
    Poi3dHelpers.setDisplayStyle("#CompareMenu","none");
    Poi3dHelpers.setDisplayStyle("gCompareModeLabel","none");
    Poi3dHelpers.setDisplayStyle("LoadCmpModCmd","none");
    Poi3dHelpers.setDisplayStyle("LoadCmpModFromFileCmd","none");
    Poi3dHelpers.setDisplayStyle("ShCmpModStructCmd","none");
  }
  else
  {
    Poi3dHelpers.setDisplayStyle("#CompareMenu","");
    Poi3dHelpers.setDisplayStyle("gCompareModeLabel","");
    Poi3dHelpers.setDisplayStyle("LoadCmpModCmd","");
    Poi3dHelpers.setDisplayStyle("LoadCmpModFromFileCmd","");
    Poi3dHelpers.setDisplayStyle("ShCmpModStructCmd","");
  }

  if(usrRights[1] == "0")//user registration
  {
    Poi3dHelpers.setDisplayStyle("#RegisterUserCmd","none");
    Poi3dHelpers.setDisplayStyle("#ManageUsersCmd","none");
  }
  else
  {
    Poi3dHelpers.setDisplayStyle("#RegisterUserCmd","");
    Poi3dHelpers.setDisplayStyle("#ManageUsersCmd","");
  }

  if(usrRights[2] == "0")//portal configuration
    Poi3dHelpers.setDisplayStyle("#PortalSettingsCmd","none");
  else
    Poi3dHelpers.setDisplayStyle("#PortalSettingsCmd","");

  if(attRights[0] == "r")//chat
  {
    Poi3dHelpers.setDisplayStyle("commDlg_ChatInput","none");
  }
  else
  {
    Poi3dHelpers.setDisplayStyle("commDlg_ChatInput","");
  }

  //primary document rights
  let leftDoc = poi3dConnector.getLeftDocument();

  if(leftDoc != null)
  {
    switch(leftDoc.getDocLocation())
    {
      case 0: //from portal
        Poi3dHelpers.setDisplayStyle("#SaveModCmd","");
        break;
      case 1: //internal catalog
      case 2: //external catalog
      case 3: //sample
        Poi3dHelpers.setDisplayStyle("#SaveModCmd","none");
        break;
      case 4: //external url
      case 5: //from host
      case 7: //from browser DB
        if(poi3dConnector.getPoi3dUser().isDocHostedAndSaved(leftDoc))
          Poi3dHelpers.setDisplayStyle("#SaveModCmd","none");
        else
          Poi3dHelpers.setDisplayStyle("#SaveModCmd","");
        break;
      default:
        Poi3dHelpers.setDisplayStyle("#SaveModCmd","none");
        break;
    }
  }
  else
  {
    Poi3dHelpers.setDisplayStyle("#SaveModCmd","");
    Poi3dHelpers.setDisplayStyle("#CompareMenu","none");
    Poi3dHelpers.setDisplayStyle("gCompareModeLabel","none");
    Poi3dHelpers.setDisplayStyle("LoadCmpModCmd","none");
    Poi3dHelpers.setDisplayStyle("LoadCmpModFromFileCmd","none");
    Poi3dHelpers.setDisplayStyle("ShCmpModStructCmd","none");
  }

  //portal features
  if(attRights[1].length == 0)//annotations
    Poi3dHelpers.setDisplayStyle("#AnnMenu","none");
  else
  {
    Poi3dHelpers.setDisplayStyle("#AnnMenu","");
    if(attRights[1] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LockAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrSphereAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrCrcAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrPlateAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrAreaAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrInfoPntCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrTxtAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrImgAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#CrLabelAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#DelAllAnnCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveAnnCmd","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LockAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#CrSphereAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#CrCrcAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#CrPlateAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#CrAreaAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#CrInfoPntCmd","");
      Poi3dHelpers.setDisplayStyle("#CrTxtAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#CrImgAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#CrLabelAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#DelAllAnnCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveAnnCmd","");
    }
  }

  if(attRights[2].length == 0)//instructions
    Poi3dHelpers.setDisplayStyle("#InstrMenu","none");
  else
  {
    Poi3dHelpers.setDisplayStyle("#InstrMenu","");
    if(attRights[2] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LockInstructionsCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockInstructionsCmd","none");
      Poi3dHelpers.setDisplayStyle("#CreateInstructionCmd","none");
      Poi3dHelpers.setDisplayStyle("#DelAllInstructionsCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveInstructionsCmd","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LockInstructionsCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockInstructionsCmd","");
      Poi3dHelpers.setDisplayStyle("#CreateInstructionCmd","");
      Poi3dHelpers.setDisplayStyle("#DelAllInstructionsCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveInstructionsCmd","");
    }
  }

  if(attRights[3].length == 0)//material sets
  {
    Poi3dHelpers.setDisplayStyle("#MatMenu","none");
    Poi3dHelpers.setDisplayStyle("defMtlSetDlg_SetNameRow","none");
    Poi3dHelpers.setDisplayStyle("defMtlSetDlg_WriteRow","none");
  }
  else
  {
    Poi3dHelpers.setDisplayStyle("#MatMenu","");
    if(attRights[3] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LockMaterialDefsCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockMaterialDefsCmd","none");
      Poi3dHelpers.setDisplayStyle("#AssignMaterial","none");
      Poi3dHelpers.setDisplayStyle("#DeactivateMaterial","none");
      Poi3dHelpers.setDisplayStyle("#DelAllMaterialDefsCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveMaterialDefsCmd","none");
      Poi3dHelpers.setDisplayStyle("#CreateMaterialDefsCmd","none");
      Poi3dHelpers.setDisplayStyle("defMtlSetDlg_SetNameRow","none");
      Poi3dHelpers.setDisplayStyle("defMtlSetDlg_WriteRow","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LockMaterialDefsCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockMaterialDefsCmd","");
      Poi3dHelpers.setDisplayStyle("#AssignMaterial","");
      Poi3dHelpers.setDisplayStyle("#DeactivateMaterial","");
      Poi3dHelpers.setDisplayStyle("#DelAllMaterialDefsCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveMaterialDefsCmd","");
      Poi3dHelpers.setDisplayStyle("#CreateMaterialDefsCmd","");
      Poi3dHelpers.setDisplayStyle("defMtlSetDlg_SetNameRow","");
      Poi3dHelpers.setDisplayStyle("defMtlSetDlg_WriteRow","");
    }
  }

  if(attRights[4].length == 0)//file attachments
  {
    Poi3dHelpers.setDisplayStyle("#FattMenu","none");
    Poi3dHelpers.setDisplayStyle("CmpCtxFileAttShowCmd","none");
    Poi3dHelpers.setDisplayStyle("CmpCtxFileAttDefineCmd","none");
  }
  else
  {
    Poi3dHelpers.setDisplayStyle("#FattMenu","");
    if(attRights[4] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LockFileAttachmentsCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockFileAttachmentsCmd","none");
      Poi3dHelpers.setDisplayStyle("#UploadFileAttachmentCmd","none");
      Poi3dHelpers.setDisplayStyle("#DelAllFileAttachmentsCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveFileAttachmentsCmd","none");
      Poi3dHelpers.setDisplayStyle("CmpCtxFileAttDefineCmd","none");
      Poi3dHelpers.setDisplayStyle("hdlFattDlg_EditBut","none");
      Poi3dHelpers.setDisplayStyle("hdlFattDlg_DelBut","none");
      Poi3dHelpers.setDisplayStyle("hdlFattDlg_AccLogBut","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LockFileAttachmentsCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockFileAttachmentsCmd","");
      Poi3dHelpers.setDisplayStyle("#UploadFileAttachmentCmd","");
      Poi3dHelpers.setDisplayStyle("#DelAllFileAttachmentsCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveFileAttachmentsCmd","");
      Poi3dHelpers.setDisplayStyle("CmpCtxFileAttShowCmd","");
      Poi3dHelpers.setDisplayStyle("CmpCtxFileAttDefineCmd","");
      Poi3dHelpers.setDisplayStyle("hdlFattDlg_EditBut","");
      Poi3dHelpers.setDisplayStyle("hdlFattDlg_DelBut","");
      Poi3dHelpers.setDisplayStyle("hdlFattDlg_AccLogBut","");
    }
  }

  if(attRights[5].length == 0)//BOMs
  {
    Poi3dHelpers.setDisplayStyle("#BomMenu","none");
    Poi3dHelpers.setDisplayStyle("lbrBomSel","none");
  }
  else
  {
    Poi3dHelpers.setDisplayStyle("#BomMenu","");
    Poi3dHelpers.setDisplayStyle("lbrBomSel","");
    if(attRights[5] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LockBomsCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockBomsCmd","none");
      Poi3dHelpers.setDisplayStyle("#DelAllBomsCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveBomsCmd","none");
      Poi3dHelpers.setDisplayStyle("defBomDlg_NewBut","none");
      Poi3dHelpers.setDisplayStyle("defBomDlg_DelBut","none");
      Poi3dHelpers.setDisplayStyle("defBomDlg_NameEditRow","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LockBomsCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockBomsCmd","");
      Poi3dHelpers.setDisplayStyle("#DelAllBomsCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveBomsCmd","");
      Poi3dHelpers.setDisplayStyle("defBomDlg_NewBut","");
      Poi3dHelpers.setDisplayStyle("defBomDlg_DelBut","");
      Poi3dHelpers.setDisplayStyle("defBomDlg_NameEditRow","");
    }
  }

  if(attRights[6].length == 0)//sensors
    Poi3dHelpers.setDisplayStyle("#SensorMenu","none");
  else
  {
    Poi3dHelpers.setDisplayStyle("#SensorMenu","");
    if(attRights[6] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LockSensorsCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockSensorsCmd","none");
      Poi3dHelpers.setDisplayStyle("#CreateSensorCmd","none");
      Poi3dHelpers.setDisplayStyle("#DelAllSensorsCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveSensorsCmd","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LockSensorsCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockSensorsCmd","");
      Poi3dHelpers.setDisplayStyle("#CreateSensorCmd","");
      Poi3dHelpers.setDisplayStyle("#DelAllSensorsCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveSensorsCmd","");
    }
  }

  if(attRights[7].length == 0)//locations
    Poi3dHelpers.setDisplayStyle("#LocatorMenu","none");
  else
  {
    Poi3dHelpers.setDisplayStyle("#LocatorMenu","");
    if(attRights[7] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LoadViewLocCmd","none");
      Poi3dHelpers.setDisplayStyle("#LockViewLocCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockViewLocCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveCurrentViewerPositionCmd","none");
      Poi3dHelpers.setDisplayStyle("#DelAllViewLocCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveViewLocCmd","none");
      Poi3dHelpers.setDisplayStyle("hdlVlocDlg_DelBut","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LoadViewLocCmd","");
      Poi3dHelpers.setDisplayStyle("#LockViewLocCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockViewLocCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveCurrentViewerPositionCmd","");
      Poi3dHelpers.setDisplayStyle("#DelAllViewLocCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveViewLocCmd","");
      Poi3dHelpers.setDisplayStyle("hdlVlocDlg_DelBut","");
    }
  }

  if(attRights[8].length == 0)//document attributes
    Poi3dHelpers.setDisplayStyle("#DocAttrMenu","none");
  else
  {
    Poi3dHelpers.setDisplayStyle("#DocAttrMenu","");
    if(attRights[8] == "r")
    {
      Poi3dHelpers.setDisplayStyle("#LockDocAttrCmd","none");
      Poi3dHelpers.setDisplayStyle("#UnlockDocAttrCmd","none");
      Poi3dHelpers.setDisplayStyle("#CreateDocAttrCmd","none");
      Poi3dHelpers.setDisplayStyle("#DelAllDocAttrCmd","none");
      Poi3dHelpers.setDisplayStyle("#SaveDocAttrCmd","none");
    }
    else
    {
      Poi3dHelpers.setDisplayStyle("#LockDocAttrCmd","");
      Poi3dHelpers.setDisplayStyle("#UnlockDocAttrCmd","");
      Poi3dHelpers.setDisplayStyle("#CreateDocAttrCmd","");
      Poi3dHelpers.setDisplayStyle("#DelAllDocAttrCmd","");
      Poi3dHelpers.setDisplayStyle("#SaveDocAttrCmd","");
    }
  }
};

function setComponentInfo(cmpObject)
{
  cmpObject.setSelectionInfo(cmpObject.getModel().getModelName());
  cmpObject.setRepresentedType("document");
  cmpObject.setPosNrFixed(true);
}

function onCmiNotification (event)
{
  var txtParts = null;
  if(event.data.cmd != undefined)
    txtParts = event.data.cmd.split("|");
  else if(event.data.split != undefined)
    txtParts = event.data.split("|");
  else
    return;

  if(txtParts[0]=="CMI_ERROR")
  {
    setStatusText(txtParts[2]);
  }
  else if(txtParts[0]=="CMI_INFO")
  {
    switch(txtParts[1])
    {
      case "DbInfoFromStorage":
        if(event.data.value == null)
        {
          setStatusText(poi3dConnector.getStatusText(10));//"Error loading document"
          return;
        }
        else
        {
          let value = event.data.value;
          let docAttribs = JSON.parse(value.docAttributes);
          poi3dConnector.getLeftDocument().setDocAttributesFromDbLoad(docAttribs);

          switch(value.docType)
          {
            case "wpm":
              if(viewingMode == "2d") viewingMode = "3d";
              resizeWindow(false);
              myCmiWindow.getCmiModel().modelUrl = value.docFname;
              myCmiWindow.openModelFromJsonString(value.docData,false,true);
              break;
            case "jpg":
            case "jpeg":
            case "bmp":
            case "gif":
            case "svg":
            case "png":
            case "tif":
            case "tiff":
            case "pdf":
              if(viewingMode == "3d") viewingMode = "2d";
              resizeWindow(false);
              open2dImage(value.docData, value.docFname, value.docType, true);
              break;
            default:
              setStatusText(poi3dConnector.getStatusText(11));//"Unsupported extension""
              break;
          }//switch(value.docType)
        }//if(value != null)
        break;
      case "UpdateUi":
        applySettings();
        break;
      case "CreateFirstAdmin":
        showRegUserDlg(null,"AdminCreation");
        break;
      case "BrowserEntryClicked":
        let nodeData = JSON.parse(txtParts[2]);
        if((nodeData.pageNr != currentPageNr)&&(nodeData.pageNr > 0))
        {
          currentPageNr=nodeData.pageNr;
          openCurrentMultipageImage();
        }
        break;
      case "DeviceOrientationChanged":
        if(isDeviceTrackingActive == false)
        {
          if(window.innerHeight > window.innerWidth)
            deviceMode = "portrait";
          else
            deviceMode = "landscape";

          myCmiWindow.getHeadAnglesFromDeviceAngles(deviceMode,savedHeadAngles);

          prevHeadAngles[0]=savedHeadAngles[0];
          prevHeadAngles[1]=savedHeadAngles[1];

          isDeviceTrackingActive = true;
        }
        else
        {
          myCmiWindow.getHeadAnglesFromDeviceAngles(deviceMode,headAngles);

          if((Math.abs(headAngles[0]-prevHeadAngles[0]) < 0.2)&&(Math.abs(headAngles[1]-prevHeadAngles[1]) < 0.2))
            break;

          prevHeadAngles[0]=headAngles[0];
          prevHeadAngles[1]=headAngles[1];

          var dltaHeadLR = parseFloat(headAngles[0]-savedHeadAngles[0]);
          var dltaHeadUD = parseFloat(headAngles[1]-savedHeadAngles[1]);

          if((viewingMode != "2d")&&(viewingMode != "3d"))
          {
            //setStatusText("RotAng:"+headAngles[0].toFixed(2)+" HeadAng:"+headAngles[1].toFixed(2)+" SlopeAng:"+headAngles[2].toFixed(2));
            //setStatusText("RotAng:"+dltaHeadLR.toFixed(2)+" HeadAng:"+dltaHeadUD.toFixed(2));

            myCmiWindow.setHeadRotationAngle4FirstPersonView(dltaHeadLR);
            myCmiWindow.setHeadUpAngle4FirstPersonView(dltaHeadUD);
            myCmiWindow.drawScene();
          }
        }
        break;
      case "InvalidPositionPicked":
      case "PositionPicked":
        if(viewingMode == "2d")
          txtParts[4]=0.0;

        switch(interactionMode)
        {
          case "measureDist":
            if(pickPoints.length == 0)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText(poi3dConnector.getStatusText(1));//"select second measurement point"
            }
            else if(pickPoints.length == 1)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText("");
              showMeasDlg(null);
            }
            else
            {
              currentModel.removeLocatorsFromModelByNames(pickPoints);
              pickPoints = new Array();
              if(measDlgVisible == true)
              {
                setStatusText(poi3dConnector.getStatusText(0));//"select first measurement point"
              }
            }
            break;
          case "measureAng":
            if(pickPoints.length == 0)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText(poi3dConnector.getStatusText(0));//"select first measurement point"
            }
            else if(pickPoints.length == 1)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText(poi3dConnector.getStatusText(1));//"select second measurement point"
            }
            else if(pickPoints.length == 2)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText("");
              showMeasDlg(null);
            }
            else
            {
              currentModel.removeLocatorsFromModelByNames(pickPoints);
              pickPoints = new Array();
              if(measDlgVisible == true)
              {
                setStatusText(poi3dConnector.getStatusText(8));//"select center point"
              }
            }
            break;
          case "measureRad":
            if(pickPoints.length == 0)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText(poi3dConnector.getStatusText(1));//"select first measurement point"
            }
            else if(pickPoints.length == 1)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText(poi3dConnector.getStatusText(19));//"select third measurement point"
            }
            else if(pickPoints.length == 2)
            {
              var locName = "lc"+(pickPoints.length+1);
              leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
              pickPoints.push(locName);
              setStatusText("");
              showMeasDlg(null);
            }
            else
            {
              currentModel.removeLocatorsFromModelByNames(pickPoints);
              pickPoints = new Array();
              if(measDlgVisible == true)
              {
                setStatusText(poi3dConnector.getStatusText(0));//"select first measurement point"
              }
            }
            break;
          case "snsPosPick":
            if(leftModel == null) break;
            var locName = "lc"+(pickPoints.length+1);
            leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
            pickPoints.push(locName);
            setStatusText("");
            defSnsDlg.setPickPos();
            break;
          case "ipPickEdit":
          case "ipPick":
            if(leftModel == null) break;
            var locName = "lc"+(pickPoints.length+1);
            leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
            pickPoints.push(locName);
            setStatusText("");
            document.getElementById("infoPntDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "ipPick")
              showInfoPntDlg(null,null);
            else
              showInfoPntDlg(null,infoPntDlg.selectedEntity);
            break;
          case "crcPick":
          case "crcPickEdit":
            if(leftModel == null) break;
            var locName = "lc" + (pickPoints.length + 1);
            leftModel.addPositionLocatorToModel(locName, [txtParts[2], txtParts[3], 0.0]);
            pickPoints.push(locName);
            if (pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(9));//"select radius point"
              break;
            }
            setStatusText("");
            document.getElementById("areaAnnDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "crcPick")
              showAreaAnnDlg(null,"circle",null);
            else
              showAreaAnnDlg(null,"circle",areaAnnDlg.selectedEntity);
            break;
          case "platePick":
          case "platePickEdit":
            if(leftModel == null) break;
            var locName = "lc" + (pickPoints.length + 1);
            leftModel.addPositionLocatorToModel(locName, [txtParts[2], txtParts[3], 0.0]);
            pickPoints.push(locName);
            if (pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(9));//"select radius point"
              break;
            }
            setStatusText("");
            document.getElementById("areaAnnDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "platePick")
              showAreaAnnDlg(null,"plate",null);
            else
              showAreaAnnDlg(null,"plate",areaAnnDlg.selectedEntity);
            break;
          case "areaPick":
          case "areaPickEdit":
            if(leftModel == null) break;
            var locName = "lc" + (pickPoints.length + 1);
            leftModel.addPositionLocatorToModel(locName, [txtParts[2], txtParts[3], 0.0]);
            pickPoints.push(locName);
            if (pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(4));//"select second position"
              break;
            }
            setStatusText("");
            document.getElementById("areaAnnDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "areaPick")
              showAreaAnnDlg(null,"area",null);
            else
              showAreaAnnDlg(null,"area",areaAnnDlg.selectedEntity);
            break;
          case "spherePick":
          case "spherePickEdit":
            if(leftModel == null) break;
            var locName = "lc" + (pickPoints.length + 1);
            leftModel.addPositionLocatorToModel(locName, [txtParts[2], txtParts[3], txtParts[4]]);
            pickPoints.push(locName);
            if (pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(9));//"select radius point"
              break;
            }
            setStatusText("");
            document.getElementById("areaAnnDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "spherePick")
              showAreaAnnDlg(null,"sphere",null);
            else
              showAreaAnnDlg(null,"sphere",areaAnnDlg.selectedEntity);
            break;
          case "taPick":
          case "taPickEdit":
            if(leftModel == null) break;
            var locName = "lc"+(pickPoints.length+1);
            leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
            pickPoints.push(locName);
            if(pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(4));//"select second position"
              break;
            }
            setStatusText("");
            document.getElementById("txtAnnDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "taPick")
              showTxtAnnDlg(null,null);
            else
              showTxtAnnDlg(null,txtAnnDlg.selectedEntity);
            break;
          case "labPick":
          case "labPickEdit":
            if(leftModel == null) break;
            var locName = "lc"+(pickPoints.length+1);
            leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
            pickPoints.push(locName);
            if(pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(18));//"select upper right point"
              break;
            }
            setStatusText("");
            document.getElementById("labAnnDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "labPick")
              showLabAnnDlg(null,null);
            else
              showLabAnnDlg(null,labAnnDlg.selectedEntity);
            break;
          case "tiPick":
          case "tiPickEdit":
            if(leftModel == null) break;
            var locName = "lc"+(pickPoints.length+1);
            leftModel.addPositionLocatorToModel(locName,[txtParts[2],txtParts[3],txtParts[4]]);
            pickPoints.push(locName);
            if(pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(4));//"select second position"
              break;
            }
            setStatusText("");
            document.getElementById("imgAnnDlg_LayVal").value = poi3dConnector.getGroupName();
            if(interactionMode == "tiPick")
              showImgAnnDlg(null,null);
            else
              showImgAnnDlg(null,imgAnnDlg.selectedEntity);
            break;
          case "calPick":
            if(leftModel == null) break;
            var locName = "lc" + (pickPoints.length + 1);
            leftModel.addPositionLocatorToModel(locName, [txtParts[2], txtParts[3], 0.0]);
            pickPoints.push(locName);
            if (pickPoints.length == 1)
            {
              setStatusText(poi3dConnector.getStatusText(4));//"select second position"
              break;
            }
            setStatusText("");
            showClbMsmtDlg(null);
            break;
        }
        break;
      case "AnimationEnded":
        switch(lastStartedAnimation)
        {
          case "unmateAnimation":
            mateAnimation.resetEntites(true,false);
            break;
          case "viewAnimationFront": //wg. useFrontAsTop
            myCmiWindow.showOglStdView("Front");
            break;
          case "viewAnimationBack":
            myCmiWindow.showOglStdView("Back");
            break;
          case "viewAnimationLeft":
            myCmiWindow.showOglStdView("Left");
            break;
          case "viewAnimationRight":
            myCmiWindow.showOglStdView("Right");
            break;
          case "viewAnimationTop":
            myCmiWindow.showOglStdView("Top");
            break;
          case "viewAnimationBottom":
            myCmiWindow.showOglStdView("Bottom");
            break;
          case "viewAnimationIso":
            myCmiWindow.showOglStdView("ISO");
            break;
          case "instructionAnimation":
            instructionAnimation.resetEntites(false,false,true);
            if(currentHighlightedComponents != null)
            {
              leftAssemblyBrowser.highlightComponents(currentHighlightedComponents);
              leftBomBrowser.highlightComponents(currentHighlightedComponents);
            }

            handleSelectionSettings();
            myCmiWindow.drawScene();

            break;
          case "sensorAnimation":
            sensorAnimation.resetEntites(false,false,true);
            if(currentHighlightedComponents != null)
            {
              leftAssemblyBrowser.highlightComponents(currentHighlightedComponents);
              leftBomBrowser.highlightComponents(currentHighlightedComponents);
            }

            poi3dConnector.getLeftDocument().getSensorObject().restoreVisibility(currentPageNr);
            handleSelectionSettings();
            myCmiWindow.drawScene();

            break;
          case "locateAnimation":
            locateAnimation.resetEntites(false,false,true);
            if(currentHighlightedComponents != null)
            {
              leftAssemblyBrowser.highlightComponents(currentHighlightedComponents);
              leftBomBrowser.highlightComponents(currentHighlightedComponents);
            }

            handleSelectionSettings();
            myCmiWindow.drawScene();

            break;
        }
        if(leftModel != null) poi3dConnector.getLeftDocument().getSensorObject().updatePositions(myCmiWindow);
        break;
      case "BrowserViewUpdated":
        {
          let browserToCheck = null;
          let browserElement = null;
          let textElement = null;

          if(txtParts[2] == "leftAssemblyBrowser")
          {
            document.getElementById("leftTableContent").addEventListener("contextmenu", handleLeftBrowserContextMenuEvent);
            browserElement = document.getElementById("leftAssemblyContentArea");
            textElement = document.getElementById("lbrCompHdrTtl");
            if(browserElement.style.visibility == 'visible')
              browserToCheck = leftAssemblyBrowser;
          }
          else if(txtParts[2] == "rightAssemblyBrowser")
          {
            browserElement = document.getElementById("rightBrowserArea");
            textElement = document.getElementById("rbrCompHdrTtl");
            if(browserElement.style.visibility == 'visible')
              browserToCheck = rightAssemblyBrowser;
          }
          else if(txtParts[2] == "leftBomBrowser")
          {
            browserElement = document.getElementById("leftBomContentArea");
            textElement = document.getElementById("lbrBomHdrTtl");
            if(browserElement.style.visibility == 'visible')
              browserToCheck = leftBomBrowser;
          }

          if(browserToCheck != null)
          {
            let cmpCnt = browserToCheck.getNodeCount();
            let hlCnt = browserToCheck.getHlNodeCount();
            textElement.innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
          }

          if(modelDisplayed == true)
            resizeWindow(false);
        }
        break;
      case "ModelLoading":
        setStatusText(txtParts[2]);
        break;
      case "ModelOpened":
        setStatusText("");
        currentHighlightedEntity=null;
        if(myCmiWindow.currentCommand == "OpenMod")
        {
          open3dPrimaryModel();
        }
        else
        {
          open3dCompareModel();
        }
        vertexLocator = leftModel.addPositionLocatorToModel("vertexLocator",[0.0,0.0,0.0]);
        if(vertexLocator != null)
        {
          vertexLocator.color = new Array(0.0,1.0,0.0,1.0);
          vertexLocator.setVisibility(false);
        }

        var animIcon = document.getElementById("tbAnimImg");
        modelAnimations = currentModel.getAnimationCollection();
        if(modelAnimations.length > 0)
          animIcon.style.display = "inline";
        else
          animIcon.style.display = "none";

        switchBrowserPosition(poi3dConnector.getUserSettings().browserPositions);
        break;
      case "ModelDisplayed":
        if ((!myCmiWindow) || (!myCmiWindow.isUsable))
          return;
        modelDisplayed = true;

        resizeWindow(true);
        break;
      case "ModelTransformed":
        if(leftModel != null)
          poi3dConnector.getLeftDocument().getSensorObject().updatePositions(myCmiWindow);
        break;
      case "TextureLoaded":
        if((currentImageTexture != null)&&(txtParts[2] == currentImageTexture.textureName))
        {
          updateAnnotationVisibility();
        }
        break;
      case "TouchUp":
      case "MouseUp":
        if((isModelRotationPoint == false)&&(myCmiWindow.getFirstPersonViewState() == false))
        {
          myCmiWindow.setCurrentRotationPoint(currentModel.getModelCenterPoint());
          isModelRotationPoint = true;
        }
        break;
      case "TouchDown":
      {
        myCmiWindow.selectEntity(txtParts[2], txtParts[3], false);
        currentHighlightedEntity = myCmiWindow.highlightedEntity;
      }
      case "MouseDown":
        closeAllMenus();
        if((currentHighlightedEntity != null)&&(currentHighlightedEntity.getClassName() == "cmiComponentObject")&&(myCmiWindow.getFirstPersonViewState() == false))
        {
          myCmiWindow.setCurrentRotationPoint(currentHighlightedEntity.getGlobalOrigin());
          //myCmiWindow.setCurrentRotationPoint(currentHighlightedEntity.getCenterPoint());//ToDo template transformation einbeziehen -> ggf neuer Boudary point this.createBoundaryPoints
          isModelRotationPoint = false;
        }
        break;
      case "LongTouchDown":
        handleCenterContextMenu(parseInt(txtParts[2]),parseInt(txtParts[3]));
        break;
      case "VertexUnSelected":
        if(vertexLocator != null)
          vertexLocator.setVisibility(false);

        vertexSelected = false;
        break;
      case "VertexSelected":
        if(vertexLocator != null)
        {
          vertexLocator.setOrigin([parseFloat(txtParts[2]),parseFloat(txtParts[3]),parseFloat(txtParts[4])]);
          vertexLocator.setVisibility(true);
          vertexSelected = true;
        }
        break;
      case "LocatorHighlight":
      case "EntitySelectionHighlight":
      case "EntityUrlSelectionHighlight":
        var ent = null;
        ent=myCmiWindow.highlightedEntity;

        if ((toolTip)&&(txtParts[5].length > 0))
        {
          toolTip.style.left = (parseInt(txtParts[2]) + 10) + "px";
          toolTip.style.top = (parseInt(txtParts[3]) - toolTipDistance) + "px";
          toolTip.innerHTML = "&nbsp;" + txtParts[5] + "&nbsp;";
          toolTip.style.display = "block";

          if(txtParts[1]=="EntityUrlSelectionHighlight")
            cmiCanvas.style.cursor = "pointer";
          else
            cmiCanvas.style.cursor = "default";

        }
        if((ent.getClassName() != "cmiComponentObject")&&(isAnnotation(ent)==false))
        {
          ent.resetHighlight();
          ent.draw(false);
          currentHighlightedEntity = null;
        }
        else
          currentHighlightedEntity = ent;
        break;
      case "LocatorUnHighlight":
      case "EntitySelectionUnHighlight":
        if(toolTip)
        {
          toolTip.style.display = "none";
          cmiCanvas.style.cursor = "default";
        }
        if(
          (mainModelCtxtMenu.children[0].style.opacity == "0")&&
          (cmpCtxMenu.children[0].style.opacity == "0")&&
          (multiCmpCtxMenu.children[0].style.opacity == "0")&&
          (annCtxtMenu.children[0].style.opacity == "0")
          )
          currentHighlightedEntity = null;
        break;
      case "LocatorSelected":
        var cmiLocator = myCmiWindow.getCmiModel().getEntityByName(txtParts[4]);
        if(cmiLocator != null)
        {
          if(viewingMode == "VR")
          {
            var pinIcon = document.getElementById("gPinModel");
            pinIcon.checked = true;
            pinModelToEnv(pinIcon);
          }

          var org = cmiLocator.getGlobalOrigin();
          var ang = cmiLocator.getGlobalEulerAngles();
          myCmiWindow.moveViewerToModelPosition(org[0],org[1],org[2]);
          myCmiWindow.rotateViewerToModelAngles(ang[0],ang[1],ang[2]);
          myCmiWindow.drawScene();
        }
        break;
      case "EntitySelected":
      case "EntityUrlSelected":
        if(txtParts[1]=="EntityUrlSelected")
          selectedEntity = myCmiWindow.getCmiModel().getEntityByName(txtParts[5]);
        else
          selectedEntity = myCmiWindow.getCmiModel().getEntityByName(txtParts[4]);

        if(selectedEntity.getClassName() == "cmiComponentObject")
          currentHighlightedEntity = selectedEntity;

        switch(interactionMode)
        {
          case "matPick":
            if((matDlg != null)&&(selectedEntity != null)&&(selectedEntity.getClassName() == "cmiComponentObject"))
              matDlg.materialPicked(selectedEntity);

            setStatusText("");
            interactionMode = "";
            break;
          case "selectInBrowser":
            if((selectedEntity != null)&&(selectedEntity.getClassName() == "cmiComponentObject"))
            {
              if(myCmiWindow.getCmiModel() == leftModel)
              {
                leftAssemblyBrowser.switchHighlightStateOfComponent(selectedEntity,true);
                leftBomBrowser.switchHighlightStateOfComponentNode(selectedEntity,true);
              }
              else
                rightAssemblyBrowser.switchHighlightStateOfComponent(selectedEntity,true);

            }
            break;
          default:
            if(txtParts[1]=="EntityUrlSelected")
            {
              if(annCtxtMenu.style.display == 'none')
                poi3dConnector.handleInfoPointClick(txtParts[4]);
            }
            break;
        }//switch(interactionMode)
        break;
    }//switch(txtParts[1])
  }//else if(txtParts[0]=="CMI_INFO")

  if(event.stopPropagation !== undefined) event.stopPropagation();
  else if(event.cancelBubble !== undefined) event.cancelBubble = true;
  if(event.preventDefault !== undefined) event.preventDefault();
  return false;

}//function onCmiNotification (event)

// ==================================== Browser ============================

function showLeftTable(show)
{
  var leftBrowserArea = document.getElementById("leftBrowserArea");
  var leftAssemblyContentArea= document.getElementById("leftAssemblyContentArea");
  var leftLayerContentArea = document.getElementById("leftLayerContentArea");
  var leftBomContentArea = document.getElementById("leftBomContentArea");

  var layerViewMode = document.getElementById("layerView").checked;
  var bomViewMode = document.getElementById("bomView").checked;


  if(show == true)
  {
    leftBrowserArea.style.visibility = 'visible';
    if(layerViewMode)
    {
      leftAssemblyContentArea.style.visibility = 'hidden';
      leftLayerContentArea.style.visibility = 'visible';
      leftBomContentArea.style.visibility = 'hidden';
    }
    else if(bomViewMode)
    {
      leftAssemblyContentArea.style.visibility = 'hidden';
      leftLayerContentArea.style.visibility = 'hidden';
      leftBomContentArea.style.visibility = 'visible';
    }
    else
    {
      leftAssemblyContentArea.style.visibility = 'visible';
      leftLayerContentArea.style.visibility = 'hidden';
      leftBomContentArea.style.visibility = 'hidden';
    }
  }
  else
  {
    leftBrowserArea.style.visibility = 'hidden';
    leftAssemblyContentArea.style.visibility = 'hidden';
    leftLayerContentArea.style.visibility = 'hidden';
    leftBomContentArea.style.visibility = 'hidden';
  }
  resizeWindow(false);

  poi3dConnector.getUserSettings().showLeftBrowser = show;
  poi3dConnector.saveUserSettingsToLocalStorage();

}
function showRightTable(show)
{
  var rightBrowserArea = document.getElementById("rightBrowserArea");

  if(show == true)
  {
    rightBrowserArea.style.visibility = 'visible';
  }
  else
  {
    rightBrowserArea.style.visibility = 'hidden';
  }
  resizeWindow(false);

  poi3dConnector.getUserSettings().showRightBrowser = show;
  poi3dConnector.saveUserSettingsToLocalStorage();
}
function switchBrowserPosition(position)
{
  switch(position)
  {
    case "left":
      document.getElementById("leftBrowserPosLeft").checked = true;
      document.getElementById("rightBrowserPosLeft").checked = true;
      poi3dConnector.getUserSettings().browserPositions = "left";
      poi3dConnector.saveUserSettingsToLocalStorage();
      break;
    case "centered":
      document.getElementById("leftBrowserPosMiddle").checked = true;
      document.getElementById("rightBrowserPosMiddle").checked = true;
      poi3dConnector.getUserSettings().browserPositions = "centered";
      poi3dConnector.saveUserSettingsToLocalStorage();
      break;
    case "right":
      document.getElementById("leftBrowserPosRight").checked = true;
      document.getElementById("rightBrowserPosRight").checked = true;
      poi3dConnector.getUserSettings().browserPositions = "right";
      poi3dConnector.saveUserSettingsToLocalStorage();
      break;
    case "lhide":
      showLeftTable(false);
      break;
    case "rhide":
      showRightTable(false);
      break;
  }

  resizeWindow(false);
}
function switchBrowserFontSize(browserNameToUse,sizeMode)
{
  var tableToUse = null;

  if(browserNameToUse == "right")
  {
    if(rightModel == null)
      return;
    tableToUse = document.getElementById("rightAssemblyTable");
  }
  else
  {
    if(leftModel == null)
      return;

    tableToUse = document.getElementById("leftAssemblyTable");
  }

  var fSize = window.getComputedStyle(tableToUse.children[1], null).getPropertyValue('font-size');
  var currentSize = parseFloat(fSize);

  if(sizeMode == "+")
  {
    document.documentElement.style.setProperty("--BrowserFont", (currentSize + 2) + 'px');
  }
  else if(sizeMode == "-")
  {
    document.documentElement.style.setProperty("--BrowserFont", (currentSize - 2) + 'px');
  }
  resizeWindow(false);
}
function switchBrowserSortMode(browserNameToUse,sortMode)
{
  if(browserNameToUse == "right")
  {
    if(rightModel == null)
      return;

    if(sortMode == "pos")
      rightAssemblyBrowser.setSortFlag("p");
    else if(sortMode == "alpha")
      rightAssemblyBrowser.setSortFlag("a");

    rightAssemblyBrowser.saveTableLayout();
    rightAssemblyBrowser.buildAssemblyTree();
    rightAssemblyBrowser.restoreTableLayout();
    rightAssemblyBrowser.rebuildTreeViewTable();
  }
  else
  {
    if(leftModel == null)
      return;

    if(sortMode == "pos")
    {
      leftAssemblyBrowser.setSortFlag("p");
      leftBomBrowser.setSortFlag("p");
    }
    else if(sortMode == "alpha")
    {
      leftAssemblyBrowser.setSortFlag("a");
      leftBomBrowser.setSortFlag("a");
    }

    leftAssemblyBrowser.saveTableLayout();
    leftAssemblyBrowser.buildAssemblyTree();
    leftAssemblyBrowser.restoreTableLayout();
    leftAssemblyBrowser.rebuildTreeViewTable();

    leftBomBrowser.saveTableLayout();
    leftBomBrowser.buildProductStructureTree();
    leftBomBrowser.restoreTableLayout();
    leftBomBrowser.rebuildTreeViewTable();
  }
}//switchBrowserSortMode

function expandBrowserContent(browserNameToUse,expandMode)
{

  if(browserNameToUse == 'left')
  {
    if(leftModel == null)
      return;
    leftAssemblyBrowser.expandAllNodes(expandMode);
    leftBomBrowser.expandAllNodes(expandMode);
  }
  else
  {
    if(rightModel == null)
      return;
    rightAssemblyBrowser.expandAllNodes(expandMode);
  }

  resizeWindow(false);
}
function switchCollectMode(chkBox,browserNameToUse)
{
  if(browserNameToUse == "right")
  {
    if(rightModel == null)
      return;

    rightAssemblyBrowser.setCollectSameNamesFlag(chkBox.checked);
    rightAssemblyBrowser.saveTableLayout();
    rightAssemblyBrowser.buildAssemblyTree(null);
    rightAssemblyBrowser.restoreTableLayout();
    rightAssemblyBrowser.rebuildTreeViewTable();
  }
  else
  {
    if(leftModel == null)
      return;

    leftAssemblyBrowser.setCollectSameNamesFlag(chkBox.checked);
    leftAssemblyBrowser.saveTableLayout();
    leftAssemblyBrowser.buildAssemblyTree();
    leftAssemblyBrowser.restoreTableLayout();
    leftAssemblyBrowser.rebuildTreeViewTable();

    leftBomBrowser.setCollectSameNamesFlag(chkBox.checked);
    leftBomBrowser.saveTableLayout();
    leftBomBrowser.buildProductStructureTree();
    leftBomBrowser.restoreTableLayout();
    leftBomBrowser.rebuildTreeViewTable();
  }
}
function switchToLeftBrowser(showBrowser)
{
  var leftBrowserArea = document.getElementById("leftBrowserArea");

  if((showBrowser==true)&&(leftBrowserArea.style.visibility == 'hidden'))
  {
    leftBrowserArea.style.visibility = 'visible';
    resizeWindow(false);
  }

  if((leftModel == null)||(rightModel == null))
    return;
  if(compareMode == true)
    return;

  myCmiWindow.setCmiModel(leftModel);
  currentModel=leftModel;

  let sensorsObj = poi3dConnector.getLeftDocument().getSensorObject();
  sensorsObj.restoreVisibility(currentPageNr);
  sensorsObj.updatePositions(myCmiWindow);

  myCmiWindow.drawScene();

  document.getElementById("leftBrowserHeaderTableRow1").className = "activeBrowser iconBrowserBar";
  document.getElementById("lbrActivateBut").className = "activeBrowser iconBrowserBar";
  document.getElementById("rightBrowserHeaderTableRow1").className = "inActiveBrowser iconBrowserBar";
  document.getElementById("rbrActivateBut").className = "inActiveBrowser iconBrowserBar";
}
function switchToRightBrowser(showBrowser)
{
  var rightBrowserArea = document.getElementById("rightBrowserArea");

  if((showBrowser==true)&&(rightBrowserArea.style.visibility == 'hidden'))
  {
    rightBrowserArea.style.visibility = 'visible';
    resizeWindow(false);
  }

  if((leftModel == null)||(rightModel == null))
    return;

  if(compareMode == true)
    return;

  let sensorsObj = poi3dConnector.getLeftDocument().getSensorObject();
  sensorsObj.hideAll();

  myCmiWindow.setCmiModel(rightModel);
  currentModel=rightModel;

  myCmiWindow.drawScene();

  document.getElementById("leftBrowserHeaderTableRow1").className = "inActiveBrowser iconBrowserBar";
  document.getElementById("lbrActivateBut").className = "inActiveBrowser iconBrowserBar";
  document.getElementById("rightBrowserHeaderTableRow1").className = "activeBrowser iconBrowserBar";
  document.getElementById("rbrActivateBut").className = "activeBrowser iconBrowserBar";
}

// ========================================== Sizing ====================================
function resizeLeftBrowserRightBar(ev)
{
  var leftBrowserArea = document.getElementById("leftBrowserArea");

  if(ev.targetTouches)
  {
    leftBrowserArea.style.width=ev.targetTouches[0].clientX+"px";
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.cancelBubble) ev.cancelBubble=true;
  }
  else
  {
    leftBrowserArea.style.width=ev.x+"px";
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.preventDefault) ev.preventDefault();
    if(ev.cancelBubble) ev.cancelBubble=true;
    if(ev.returnValue) ev.returnValue=false;
  }

  resizeWindow(false);
}
function resizeLeftBrowserLeftBar(ev)
{
  var leftBrowserArea = document.getElementById("leftBrowserArea");
  var rightBrowserArea = document.getElementById("rightBrowserArea");
  var brSize = 0;

  if(ev.targetTouches)
  {
    brSize = window.innerWidth-ev.targetTouches[0].clientX;
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.cancelBubble) ev.cancelBubble=true;
  }
  else
  {
    brSize = window.innerWidth-ev.x;
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.preventDefault) ev.preventDefault();
    if(ev.cancelBubble) ev.cancelBubble=true;
    if(ev.returnValue) ev.returnValue=false;
  }

  if(rightBrowserArea.style.visibility == 'visible')
    brSize = brSize-rightBrowserArea.offsetWidth-20;

  leftBrowserArea.style.width=brSize+"px";
  resizeWindow(false);
}
function resizeRightBrowserRightBar(ev)
{
  var leftBrowserArea = document.getElementById("leftBrowserArea");
  var rightBrowserArea = document.getElementById("rightBrowserArea");

  var brSize = 0;

  if(ev.targetTouches)
  {
    brSize = ev.targetTouches[0].clientX;
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.cancelBubble) ev.cancelBubble=true;
  }
  else
  {
    brSize = ev.x;
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.preventDefault) ev.preventDefault();
    if(ev.cancelBubble) ev.cancelBubble=true;
    if(ev.returnValue) ev.returnValue=false;
  }

  if(leftBrowserArea.style.visibility == 'visible')
    brSize = brSize-leftBrowserArea.offsetWidth-20;

  rightBrowserArea.style.width=brSize+"px";
  resizeWindow(false);
}
function resizeRightBrowserLeftBar(ev)
{
  var rightBrowserArea = document.getElementById("rightBrowserArea");
  var brSize = window.innerWidth-ev.x;

  if(ev.targetTouches)
  {
    brSize = window.innerWidth-ev.targetTouches[0].clientX;
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.cancelBubble) ev.cancelBubble=true;
  }
  else
  {
    brSize = window.innerWidth-ev.x;
    if(ev.stopPropagation) ev.stopPropagation();
    if(ev.preventDefault) ev.preventDefault();
    if(ev.cancelBubble) ev.cancelBubble=true;
    if(ev.returnValue) ev.returnValue=false;
  }

  rightBrowserArea.style.width=brSize+"px";
  resizeWindow(false);

}
function initBrowserDragbars()
{
  var browserBar = document.getElementById("leftBrowserDragBarRight");
  browserBar.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeLeftBrowserRightBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeLeftBrowserRightBar, false);
      document.removeEventListener("mousemove", resizeLeftBrowserRightBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  var browserIcon = document.getElementById("leftBrowserDragIconRight");
  browserIcon.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeLeftBrowserRightBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeLeftBrowserRightBar, false);
      document.removeEventListener("mousemove", resizeLeftBrowserRightBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  if(myCmiWindow.isMobileEnvironment == true)
  {
    browserIcon.addEventListener("touchstart", function(e)
    {
      Poi3dHelpers.setDisplayStyle("dragArea","block");
      document.addEventListener("touchmove", resizeLeftBrowserRightBar, false);

      document.addEventListener("touchend", function()
      {
        Poi3dHelpers.setDisplayStyle("dragArea","none");
        document.removeEventListener("touchstart", resizeLeftBrowserRightBar, false);
        document.removeEventListener("touchmove", resizeLeftBrowserRightBar, false);
        resizeWindow(false);
      }, false);

      //e.preventDefault();
    }, false);
  }
  //--

  browserBar = document.getElementById("leftBrowserDragBarLeft");
  browserBar.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeLeftBrowserLeftBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeLeftBrowserLeftBar, false);
      document.removeEventListener("mousemove", resizeLeftBrowserLeftBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  browserIcon = document.getElementById("leftBrowserDragIconLeft");
  browserIcon.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeLeftBrowserLeftBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeLeftBrowserLeftBar, false);
      document.removeEventListener("mousemove", resizeLeftBrowserLeftBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  if(myCmiWindow.isMobileEnvironment == true)
  {
    browserIcon.addEventListener("touchstart", function(e)
    {
      Poi3dHelpers.setDisplayStyle("dragArea","block");
      document.addEventListener("touchmove", resizeLeftBrowserLeftBar, false);

      document.addEventListener("touchend", function()
      {
        Poi3dHelpers.setDisplayStyle("dragArea","none");
        document.removeEventListener("touchend", resizeLeftBrowserLeftBar, false);
        document.removeEventListener("touchmove", resizeLeftBrowserLeftBar, false);
        resizeWindow(false);
      }, false);

      //e.preventDefault();
    }, false);
  }

  //--

  browserBar = document.getElementById("rightBrowserDragBarRight");
  browserBar.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeRightBrowserRightBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeRightBrowserRightBar, false);
      document.removeEventListener("mousemove", resizeRightBrowserRightBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  browserIcon = document.getElementById("rightBrowserDragIconRight");
  browserIcon.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeRightBrowserRightBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeRightBrowserRightBar, false);
      document.removeEventListener("mousemove", resizeRightBrowserRightBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  if(myCmiWindow.isMobileEnvironment == true)
  {
    browserIcon.addEventListener("touchstart", function(e)
    {
      Poi3dHelpers.setDisplayStyle("dragArea","block");
      document.addEventListener("touchmove", resizeRightBrowserRightBar, false);

      document.addEventListener("touchend", function()
      {
        Poi3dHelpers.setDisplayStyle("dragArea","none");
        document.removeEventListener("touchend", resizeRightBrowserRightBar, false);
        document.removeEventListener("touchmove", resizeRightBrowserRightBar, false);
        resizeWindow(false);
      }, false);

      //e.preventDefault();
    }, false);
  }
  //--
  browserBar = document.getElementById("rightBrowserDragBarLeft");
  browserBar.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeRightBrowserLeftBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeRightBrowserLeftBar, false);
      document.removeEventListener("mousemove", resizeRightBrowserLeftBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  browserIcon = document.getElementById("rightBrowserDragIconLeft");
  browserIcon.addEventListener("mousedown", function(e)
  {
    Poi3dHelpers.setDisplayStyle("dragArea","block");
    document.addEventListener("mousemove", resizeRightBrowserLeftBar, false);

    document.addEventListener("mouseup", function()
    {
      Poi3dHelpers.setDisplayStyle("dragArea","none");
      document.removeEventListener("mouseup", resizeRightBrowserLeftBar, false);
      document.removeEventListener("mousemove", resizeRightBrowserLeftBar, false);
      resizeWindow(false);
    }, false);
  }, false);

  if(myCmiWindow.isMobileEnvironment == true)
  {
    browserIcon.addEventListener("touchstart", function(e)
    {
      Poi3dHelpers.setDisplayStyle("dragArea","block");
      document.addEventListener("touchmove", resizeRightBrowserLeftBar, false);

      document.addEventListener("touchend", function()
      {
        Poi3dHelpers.setDisplayStyle("dragArea","none");
        document.removeEventListener("touchend", resizeRightBrowserLeftBar, false);
        document.removeEventListener("touchmove", resizeRightBrowserLeftBar, false);
        resizeWindow(false);
      }, false);

      //e.preventDefault();
    }, false);
  }
}
function resizeWindow(updateGraphics)
{
  var winSizeX = window.innerWidth;
  var winSizeY = window.innerHeight;
  var MainToolbar3d = document.getElementById("MainToolbar3d");
  var MainToolbar2d = document.getElementById("MainToolbar2d");
  var MainToolbarAr = document.getElementById("MainToolbarAr");
  var MainToolbarVr = document.getElementById("MainToolbarVr");
  var borderRadius = parseInt(parseInt(window.getComputedStyle(document.querySelector('body')).getPropertyValue('--LargeRadius'),10)*0.9);

  if(cmiCanvas == undefined) return;

  if(updateGraphics == true)
  {
    cmiCanvas.left=0;
    cmiCanvas.top=0;
    cmiCanvas.width=winSizeX-1;
    cmiCanvas.height=winSizeY-1;

    if((myCmiWindow)&&(myCmiWindow.isUsable))
    {
      var canvas = myCmiWindow.getCanvas();
      myCmiWindow.resizeContext(canvas.width,canvas.height);
    }
  }

  //left browser
  var leftBrowserArea = document.getElementById("leftBrowserArea");

  var leftAssemblyContentArea = document.getElementById("leftAssemblyContentArea");
  var leftAssemblyTable = document.getElementById("leftAssemblyTable");

  var leftBomContentArea = document.getElementById("leftBomContentArea");
  var leftBomTable = document.getElementById("leftBomTable");

  var leftLayerContentArea = document.getElementById("leftLayerContentArea");
  var leftLayerTable = document.getElementById("leftLayerTable");

  var leftBrowserHeaderTable = document.getElementById("leftBrowserHeaderTable");
  var layerViewMode = document.getElementById("layerView").checked;
  var bomViewMode = document.getElementById("bomView").checked;

  var leftBrowserDragBarRight = document.getElementById("leftBrowserDragBarRight");
  var leftBrowserDragBarLeft = document.getElementById("leftBrowserDragBarLeft");
  var leftBrowserDragIconRight = document.getElementById("leftBrowserDragIconRight");
  var leftBrowserDragIconLeft = document.getElementById("leftBrowserDragIconLeft");

  var rightBrowserDragBarRight = document.getElementById("rightBrowserDragBarRight");
  var rightBrowserDragBarLeft = document.getElementById("rightBrowserDragBarLeft");
  var rightBrowserDragIconRight = document.getElementById("rightBrowserDragIconRight");
  var rightBrowserDragIconLeft = document.getElementById("rightBrowserDragIconLeft");

  var posY = 0;

  if(viewingMode.includes("AR"))
    posY = (MainToolbarAr.offsetHeight)+10;
  else if(viewingMode.includes("VR"))
    posY = (MainToolbarVr.offsetHeight)+10;
  else if(viewingMode.includes("2d"))
    posY = (MainToolbar2d.offsetHeight)+10;
  else
    posY = (MainToolbar3d.offsetHeight)+10;

  var browserHeight = winSizeY-posY-15;

  leftBrowserArea.style.top = posY+"px";
  leftBrowserArea.style.height = browserHeight+"px";

  if(layerViewMode)
  {
    if(leftLayerTable.offsetHeight > leftBrowserArea.offsetHeight-leftBrowserHeaderTable.offsetHeight) //clip area
      leftLayerContentArea.style.height = leftBrowserArea.offsetHeight - leftBrowserHeaderTable.offsetHeight+1+"px";
    else
      leftLayerContentArea.style.height = leftLayerTable.offsetHeight+1+"px";

    leftBrowserDragBarRight.style.height=parseInt(leftLayerContentArea.style.height,10)-borderRadius+"px";
    leftBrowserDragBarLeft.style.height=parseInt(leftLayerContentArea.style.height,10)-borderRadius+"px";

    leftBrowserDragIconRight.style.top = leftLayerContentArea.offsetTop + leftLayerContentArea.offsetHeight-16+"px";
    leftBrowserDragIconRight.style.left = leftBrowserArea.offsetWidth-16+"px";
    leftBrowserDragIconLeft.style.top = leftLayerContentArea.style.top;
    leftBrowserDragIconLeft.style.left = leftBrowserArea.offsetLeft+"px"

  }
  else if(bomViewMode)
  {
    if(leftBomTable.offsetHeight > leftBrowserArea.offsetHeight-leftBrowserHeaderTable.offsetHeight) //clip area
      leftBomContentArea.style.height = leftBrowserArea.offsetHeight - leftBrowserHeaderTable.offsetHeight+1+"px";
    else
      leftBomContentArea.style.height = leftBomTable.offsetHeight+1+"px";

    leftBrowserDragBarRight.style.height=parseInt(leftBomContentArea.style.height,10)-borderRadius+"px";
    leftBrowserDragBarLeft.style.height=parseInt(leftBomContentArea.style.height,10)-borderRadius+"px";

    leftBrowserDragIconRight.style.top = leftBomContentArea.offsetTop + leftBomContentArea.offsetHeight-16+"px";
    leftBrowserDragIconRight.style.left = leftBrowserArea.offsetWidth-16+"px";
    leftBrowserDragIconLeft.style.top = leftBrowserDragIconRight.style.top;
    leftBrowserDragIconLeft.style.left = "0px";

  }
  else
  {
    if(leftAssemblyTable.offsetHeight > leftBrowserArea.offsetHeight-leftBrowserHeaderTable.offsetHeight) //clip area
      leftAssemblyContentArea.style.height = leftBrowserArea.offsetHeight - leftBrowserHeaderTable.offsetHeight+1+"px";
    else
      leftAssemblyContentArea.style.height = leftAssemblyTable.offsetHeight+1+"px";

    leftBrowserDragBarRight.style.height=parseInt(leftAssemblyContentArea.style.height,10)-borderRadius+"px";
    leftBrowserDragBarLeft.style.height=parseInt(leftAssemblyContentArea.style.height,10)-borderRadius+"px";

    leftBrowserDragIconRight.style.top = leftAssemblyContentArea.offsetTop + leftAssemblyContentArea.offsetHeight-16+"px";
    leftBrowserDragIconRight.style.left = leftBrowserArea.offsetWidth-16+"px";
    leftBrowserDragIconLeft.style.top = leftBrowserDragIconRight.style.top;
    leftBrowserDragIconLeft.style.left = "0px";

  }

  leftAssemblyContentArea.style.width=leftBrowserArea.offsetWidth-6+"px";
  leftLayerContentArea.style.width=leftBrowserArea.offsetWidth-6+"px";
  leftBomContentArea.style.width=leftBrowserArea.offsetWidth-6+"px";

  //right browser
  var rightBrowserArea = document.getElementById("rightBrowserArea");
  var rightAssemblyContentArea = document.getElementById("rightAssemblyContentArea");
  var rightAssemblyTable = document.getElementById("rightAssemblyTable");

  var rightLayerContentArea = document.getElementById("rightLayerContentArea");
  var rightLayerTable = document.getElementById("rightLayerTable");

  var rightBrowserHeaderTable = document.getElementById("rightBrowserHeaderTable");
  var layerViewMode = document.getElementById("layerView").checked;

  rightBrowserArea.style.top = posY+"px";
  rightBrowserArea.style.height = browserHeight+"px";

  if(rightAssemblyTable.offsetHeight > rightBrowserArea.offsetHeight-rightBrowserHeaderTable.offsetHeight) //clip area
    rightAssemblyContentArea.style.height = rightBrowserArea.offsetHeight - rightBrowserHeaderTable.offsetHeight+1+"px";
  else
    rightAssemblyContentArea.style.height = rightAssemblyTable.offsetHeight+1+"px";

  rightBrowserDragBarRight.style.height=parseInt(rightAssemblyContentArea.style.height,10)-borderRadius+"px";
  rightBrowserDragBarLeft.style.height=parseInt(rightAssemblyContentArea.style.height,10)-borderRadius+"px";

  rightAssemblyContentArea.style.width=rightBrowserArea.offsetWidth-6+"px"

  rightBrowserDragIconRight.style.top = rightAssemblyContentArea.offsetTop + rightAssemblyContentArea.offsetHeight-16+"px";
  rightBrowserDragIconRight.style.left = rightBrowserArea.offsetWidth-16+"px";
  rightBrowserDragIconLeft.style.top = rightBrowserDragIconRight.style.top;
  rightBrowserDragIconLeft.style.left = "0px";

  switch(poi3dConnector.getUserSettings().browserPositions)
  {
    case "right":
      if(rightBrowserArea.style.visibility == 'visible')
        leftBrowserArea.style.right=rightBrowserArea.offsetWidth+20+"px";
      else
        leftBrowserArea.style.right=8+"px";

      leftBrowserArea.style.left=("auto");
      rightBrowserArea.style.right=("10px");
      rightBrowserArea.style.left=("auto");

      leftBrowserDragBarLeft.style.backgroundColor = "var(--BrwsDragBarBgCol)";
      leftBrowserDragBarLeft.style.pointerEvents = "auto";
      leftBrowserDragBarRight.style.backgroundColor = "var(--BrwsContentBgCol)";
      leftBrowserDragBarRight.style.pointerEvents = "none";

      rightBrowserDragBarLeft.style.backgroundColor = "var(--BrwsDragBarBgCol)";
      rightBrowserDragBarLeft.style.pointerEvents = "auto";
      rightBrowserDragBarRight.style.backgroundColor = "var(--BrwsContentBgCol)";
      rightBrowserDragBarRight.style.pointerEvents = "none";

      if(myCmiWindow.isMobileEnvironment == true)
      {
        leftBrowserDragIconLeft.style.display = "block";
        leftBrowserDragIconLeft.style.pointerEvents = "auto";
        leftBrowserDragIconRight.style.display = "none";
        leftBrowserDragIconRight.style.pointerEvents = "none";

        rightBrowserDragIconLeft.style.display = "block";
        rightBrowserDragIconLeft.style.pointerEvents = "auto";
        rightBrowserDragIconRight.style.display = "none";
        rightBrowserDragIconRight.style.pointerEvents = "none";
      }
      break;
    case "left":
      leftBrowserArea.style.left=("10px");
      leftBrowserArea.style.right=("auto");
      if(leftBrowserArea.style.visibility == 'visible')
        rightBrowserArea.style.left=leftBrowserArea.offsetWidth+20+"px";
      else
        rightBrowserArea.style.left=8+"px";

      rightBrowserArea.style.right=("auto");

      leftBrowserDragBarLeft.style.backgroundColor = "var(--BrwsContentBgCol)";
      leftBrowserDragBarLeft.style.pointerEvents = "none";
      leftBrowserDragBarRight.style.backgroundColor = "var(--BrwsDragBarBgCol)";
      leftBrowserDragBarRight.style.pointerEvents = "auto";

      rightBrowserDragBarLeft.style.backgroundColor = "var(--BrwsContentBgCol)";
      rightBrowserDragBarLeft.style.pointerEvents = "none";
      rightBrowserDragBarRight.style.backgroundColor = "var(--BrwsDragBarBgCol)";
      rightBrowserDragBarRight.style.pointerEvents = "auto";

      if(myCmiWindow.isMobileEnvironment == true)
      {
        leftBrowserDragIconLeft.style.display = "none";
        leftBrowserDragIconLeft.style.pointerEvents = "none";
        leftBrowserDragIconRight.style.display = "block";
        leftBrowserDragIconRight.style.pointerEvents = "auto";

        rightBrowserDragIconLeft.style.display = "none";
        rightBrowserDragIconLeft.style.pointerEvents = "none";
        rightBrowserDragIconRight.style.display = "block";
        rightBrowserDragIconRight.style.pointerEvents = "auto";
      }
      break;
    case "centered":
    default:
      leftBrowserArea.style.left=("10px");
      leftBrowserArea.style.right=("auto");
      rightBrowserArea.style.right=("10px");
      rightBrowserArea.style.left=("auto");

      leftBrowserDragBarLeft.style.backgroundColor = "var(--BrwsContentBgCol)";
      leftBrowserDragBarLeft.style.pointerEvents = "none";
      leftBrowserDragBarRight.style.backgroundColor = "var(--BrwsDragBarBgCol)";
      leftBrowserDragBarRight.style.pointerEvents = "auto";

      rightBrowserDragBarLeft.style.backgroundColor = "var(--BrwsDragBarBgCol)";
      rightBrowserDragBarLeft.style.pointerEvents = "auto";
      rightBrowserDragBarRight.style.backgroundColor = "var(--BrwsContentBgCol)";
      rightBrowserDragBarRight.style.pointerEvents = "none";

      if(myCmiWindow.isMobileEnvironment == true)
      {
        leftBrowserDragIconLeft.style.display = "none";
        leftBrowserDragIconLeft.style.pointerEvents = "none";
        leftBrowserDragIconRight.style.display = "block";
        leftBrowserDragIconRight.style.pointerEvents = "auto";

        rightBrowserDragIconLeft.style.display = "block";
        rightBrowserDragIconLeft.style.pointerEvents = "auto";
        rightBrowserDragIconRight.style.display = "none";
        rightBrowserDragIconRight.style.pointerEvents = "none";
      }
      break;
  }
  return;
}

// ========================================== Viewing ====================================
function showPage(direction)
{
  if(multiPageDocument == null)
    return;

  switch(direction)
  {
    case "<":
      if(currentPageNr > 1)
      {
        currentPageNr=1;
        openCurrentMultipageImage();
      }
      break;
    case "-":
      if(currentPageNr > 1)
      {
        currentPageNr--;
        openCurrentMultipageImage();
      }
      break;
    case "+":
      if(currentPageNr < pageCount)
      {
        currentPageNr++;
        openCurrentMultipageImage();
      }
      break;
    case ">":
      if(currentPageNr < pageCount)
      {
        currentPageNr=pageCount;
        openCurrentMultipageImage();
      }
      break;
  }
}
function updateAnnotationVisibility()
{
  let annotations = poi3dConnector.getLeftDocument().getAnnotations();

  if(annotations.length > 0)
  {
    var annNameArray = new Array();
    var annObjectArray = new Array();

    for (var i = 0; i < annotations.length; i++)
    {
      annNameArray.push(annotations[i].eNm);
    }

    annObjectArray = leftModel.getEntitiesByNames(annNameArray);

    var pageRef;

    for (var i = 0; i < annObjectArray.length; i++)
    {
      pageRef = annObjectArray[i].getPropertyValue("pageRef");

      if(pageRef != undefined)
      {
        if(pageRef != currentPageNr)
          annObjectArray[i].setVisibility(false);
        else
          annObjectArray[i].setVisibility(true);
      }
      else
      {
        annObjectArray[i].setVisibility(true);
      }
    }//for (var i = 0; i < annotations.length; i++)
    myCmiWindow.drawScene();
  }//if(annotations.length > 0)
}
function resetViewer(resetDialogs)//called by windows client
{
  var radExpl = document.getElementById("g3dExplodeMode");
  if((radExpl!= null)&&(radExpl.checked == true))
  {
    radExpl.checked == false;
    switchExplodeMode(radExpl);
  }

  let userRights = poi3dConnector.getCurrentUserRights();
  if(userRights[0] != "0")
  {
    var radCmp = document.getElementById("gCompareMode");
    if((radCmp != null) && (radCmp.checked == true))
    {
      radCmp.checked == false;
      switchCompareMode(radCmp);
    }
  }

  closeAllDialogs(false);
  myCmiWindow.resetCmiModel();
  if(leftModel != null)
  {
    poi3dConnector.getLeftDocument().getSensorObject().removeHtmlObjects();
    leftModel.clearContent(true);
    leftAssemblyBrowser.clearContent();
    layerBrowser.clearContent();
    leftBomBrowser.clearContent();
    leftModel=null;
    modelDisplayed = false;
  }
  if(rightModel != null)
  {
    rightModel.clearContent(true);
    rightAssemblyBrowser.clearContent();
    rightModel=null;
  }

  document.getElementById("lbrCompHdrTtl").innerHTML = document.getElementById("lbrCompHdrTtl").innerHTML.split("&nbsp;")[0]+"&nbsp;";
  document.getElementById("rbrCompHdrTtl").innerHTML = document.getElementById("rbrCompHdrTtl").innerHTML.split("&nbsp;")[0]+"&nbsp;";

  pickPoints = new Array();
  currentMaterialSetRef = null;
  currentMaterialSetCopy = null;
  currentHighlightedEntity = null;

  currentImageTexture = null;
  currentAnnotationName = "";
  updateBomBrowserSelection();

  currentPageNr = 1;
  multiPageDocument = null;
  pageCount = 0;
  multiPageTifArray = null;
  multiPageType = "";
  measurementScale = 1.0;

  setStatusText("");
  currentModel = myCmiWindow.getCmiModel();
  resizeWindow(false);
  myCmiWindow.drawScene();

  myCmiWindow.useFrontAsTop = poi3dConnector.getUserSettings().useFrontAsTop;
}
// ========================================== Document opening ====================================

function openFileAttachmentFromFile ()
{
  var inputElement = document.createElement('input');
  inputElement.type = 'file';

  inputElement.onchange = e =>
  {
    var fName = e.target.files[0].name.toLowerCase();
    var fileTarget = e.target.files[0];
    showFAttUpldDlg(null,e.target.files[0]);
  }
  inputElement.click();
};//function openFileAttachmentFromFile
function open3dPrimaryModel()
{
  var MainToolbar3d = document.getElementById("MainToolbar3d");
  var MainToolbar2d = document.getElementById("MainToolbar2d");
  var MainToolbarAr = document.getElementById("MainToolbarAr");
  var MainToolbarVr = document.getElementById("MainToolbarVr");

  MainToolbar3d.style.visibility = 'visible';
  MainToolbar2d.style.visibility = 'hidden';
  MainToolbarAr.style.visibility = 'hidden';
  MainToolbarVr.style.visibility = 'hidden';

  viewingMode = "3d";
  myCmiWindow.dynamicRotationAllowed = true;
  switchMouseMode('rotate');

  currentModel = myCmiWindow.getCmiModel();
  leftModel = currentModel;

  var modelCenter = leftModel.getModelCenterPoint();
  myCmiWindow.clipPlanePoint[0]=modelCenter[0];
  myCmiWindow.clipPlanePoint[1]=modelCenter[1];
  myCmiWindow.clipPlanePoint[2]=modelCenter[2];

  var fName = leftModel.modelUrl.split(/[\\/]/).pop();
  var basename = fName.split('.').slice(0, -1).join('.');

  if((basename == "")&&(modelNameFromZip.length >0))
    basename = modelNameFromZip;

  leftModel.setModelName(basename);

  leftAssemblyBrowser.buildAssemblyTree(leftModel);
  leftAssemblyBrowser.rebuildTreeViewTable();
  switchBrowserView("struct");

  layerBrowser.buildLayerList(leftModel,true,0);
  layerBrowser.rebuildLayerViewTable();
  resizeWindow(false);

  leftBomBrowser.clearContent();
  document.getElementById("ArMatSetSelection").options.length = 0;
  document.getElementById("VrMatSetSelection").options.length = 0;
  document.getElementById("MatSetSelection").options.length = 0;
  currentMaterialSetRef = null;
  currentMaterialSetCopy = null;

  poi3dConnector.getAttachmentsFromStorage(leftModel.getModelName());
  poi3dConnector.updateDocumentUsers();
  poi3dConnector.getLeftDocument().getSensorObject().updatePositions(myCmiWindow);
  myCmiWindow.useFrontAsTop = poi3dConnector.getLeftDocument().getUseFrontAsTop();

  if(typeof Poi3dHostInterface != "undefined") //hosted
    Poi3dHostInterface.sendMessageToHost("DocumentLoaded");
}

function open3dCompareModel()
{
  currentModel = myCmiWindow.getCmiModel();
  rightModel = currentModel;

  var cmpCnt = rightModel.countTotalNrOfComponents();
  document.getElementById("rbrCompHdrTtl").innerHTML = document.getElementById("rbrCompHdrTtl").innerHTML.split("&nbsp;")[0]+"&nbsp;" + "("+cmpCnt+")";

  var fName = rightModel.modelUrl.split(/[\\/]/).pop();
  var basename = fName.split('.').slice(0, -1).join('.');

  if((basename == "")&&(modelNameFromZip.length >0))
    basename = modelNameFromZip;

  rightModel.setModelName(basename);

  showLeftTable(true);
  rightAssemblyBrowser.buildAssemblyTree(rightModel);
  rightAssemblyBrowser.rebuildTreeViewTable();

  switchToRightBrowser(true);
}

function open2dImage(imgUrl,modelName,docType,fromDb)
{
  multiPageType = docType;

  if(viewingMode.includes("VR"))
  {
    var vrCheckbox = document.getElementById("gVrMode");
    vrCheckbox.checked = false;
    switchToVrMode(vrCheckbox);
  }
  else if(viewingMode.includes("AR"))
  {
    var arCheckbox = document.getElementById("gArMode");
    arCheckbox.checked = false;
    switchToArMode(arCheckbox);
  }

  var MainToolbar3d = document.getElementById("MainToolbar3d");
  var MainToolbar2d = document.getElementById("MainToolbar2d");
  var MainToolbarAr = document.getElementById("MainToolbarAr");
  var MainToolbarVr = document.getElementById("MainToolbarVr");

  MainToolbar3d.style.visibility = 'hidden';
  MainToolbar2d.style.visibility = 'visible';
  MainToolbarAr.style.visibility = 'hidden';
  MainToolbarVr.style.visibility = 'hidden';

  viewingMode = "2d";
  myCmiWindow.dynamicRotationAllowed = false;
  switchMouseMode('move')

  if(leftModel != null)
  {
    leftModel.clearContent(true);
    leftAssemblyBrowser.clearContent();
    leftBomBrowser.clearContent();
    leftModel=null;
  }
  if(rightModel != null)
  {
    rightModel.clearContent(true);
    rightAssemblyBrowser.clearContent();
    rightModel=null;
  }
  document.getElementById("lbrCompHdrTtl").innerHTML = document.getElementById("lbrCompHdrTtl").innerHTML.split("&nbsp;")[0]+"&nbsp;";
  document.getElementById("rbrCompHdrTtl").innerHTML = document.getElementById("rbrCompHdrTtl").innerHTML.split("&nbsp;")[0]+"&nbsp;";
  showRightTable(false);
  myCmiWindow.showOglStdView("Front");

  currentModel = myCmiWindow.getCmiModel();
  currentModel.setModelName(modelName);
  leftModel = currentModel;

  leftAssemblyBrowser.buildAssemblyTree(leftModel);
  leftAssemblyBrowser.rebuildTreeViewTable();
  switchBrowserView("struct");

  setStatusText(poi3dConnector.getStatusText(7));//"loading document"
  addBaseImageToModel(imgUrl,fromDb);
}

function addBaseImageToModel(imgSrc,fromDb)
{
  if(multiPageType == "tif")
  {
    //https://github.com/photopea/UTIF.js
    //multipage: https://github.com/photopea/UTIF.js/issues/61
    //https://github.com/johnthad/utif-demo/blob/master/thumbnails.html
    //PDF:
    //https://stackoverflow.com/questions/12921052/parsing-pdf-pages-as-javascript-images
    //https://gist.github.com/jdeng/cbfad9cb21e452127c81 (PdfToImage)
    //https://pspdfkit.com/guides/web/
    if(fromDb)
    {
      multiPageDocument = imgSrc;
      multiPageTifArray = UTIF.decode(imgSrc);
      pageCount = multiPageTifArray.length;
      currentPageNr = 1;
      document.getElementById("gPageCnt").innerHTML = "1/"+pageCount;

      fillPageBrowser(pageCount,null);
      poi3dConnector.getAttachmentsFromStorage(leftModel.getModelName());
      poi3dConnector.updateDocumentUsers();

      if(typeof Poi3dHostInterface != "undefined") //hosted
        Poi3dHostInterface.sendMessageToHost("DocumentLoaded");

    }//if(fromDb)
    else
    {
      function tiffLoaded(e)
      {
        var uri = null;

        multiPageDocument = e.target.response;
        multiPageTifArray = UTIF.decode(e.target.response);
        pageCount = multiPageTifArray.length;
        currentPageNr = 1;
        document.getElementById("gPageCnt").innerHTML = "1/"+pageCount;

        fillPageBrowser(pageCount,null);
        poi3dConnector.getAttachmentsFromStorage(leftModel.getModelName());
        poi3dConnector.updateDocumentUsers();

        if(typeof Poi3dHostInterface != "undefined") //hosted
          Poi3dHostInterface.sendMessageToHost("DocumentLoaded");
      }

      var xhr = new XMLHttpRequest();
      xhr.open("GET", imgSrc);
      xhr.responseType = "arraybuffer";
      xhr.onload = tiffLoaded;
      xhr.send();
    }//if(imgSrc.includes("dbId:")) else
  }//if(docType == "tif")
  else if(multiPageType == "pdf")
  {
    //https://mozilla.github.io/pdf.js/
    //https://gist.github.com/fcingolani/3300351
    //https://github.com/mozilla/pdf.js#learning
    //https://mozilla.github.io/pdf.js/examples/
    //https://medium.com/@csofiamsousa/creating-a-table-of-contents-with-pdf-js-4a4316472fff

    var loadingTask = pdfjsLib.getDocument(imgSrc);
    loadingTask.promise.then(function(pdfDoc)
    {
      multiPageDocument = pdfDoc;
      currentPageNr = 1;
      pageCount = pdfDoc.numPages;
      document.getElementById("gPageCnt").innerHTML = "1/"+pageCount;

      pdfDoc.getOutline().then(function(outline)
      {
        if (outline)
          fillPageBrowser(pageCount,outline);
        else
          fillPageBrowser(pageCount,null);

        poi3dConnector.getAttachmentsFromStorage(leftModel.getModelName());
        poi3dConnector.updateDocumentUsers();

        if(typeof Poi3dHostInterface != "undefined") //hosted
          Poi3dHostInterface.sendMessageToHost("DocumentLoaded");
      });

    }, function (reason)
    {
      // PDF loading error
      setStatusText("Error retrieving PDF document");
    });

  }//else if((imgSrc.includes('.pdf')==true)||imgSrc.includes("data:application/pdf")==true)
  else
  {
    currentPageNr = 1;
    multiPageDocument = null;
    multiPageTifArray = null;
    pageCount = 1;

    document.getElementById("gPageCnt").innerHTML = "1/1";

    _addBaseImageToModel(imgSrc);
    fillPageBrowser(pageCount,null);
    poi3dConnector.getAttachmentsFromStorage(leftModel.getModelName());
    poi3dConnector.updateDocumentUsers();

    if(typeof Poi3dHostInterface != "undefined") //hosted
      Poi3dHostInterface.sendMessageToHost("DocumentLoaded");
  }
}

function fillPageBrowser(nrOfPages, pdfOutlines)
{
  leftAssemblyBrowser.createEmptyNodeTree(myCmiWindow);
  var parentNode = leftAssemblyBrowser.addNewNode(null,"pageRef",poi3dConnector.getMessage(41),{pageNr: 1});

  for(let i =1; i<=nrOfPages; i++)
    leftAssemblyBrowser.addNewNode(parentNode,"pageRef",poi3dConnector.getMessage(40)+" "+i,{pageNr: i});

  if(pdfOutlines != null)
  {
    pdfOutlineCheck = 0;
    parentNode = leftAssemblyBrowser.addNewNode(null,"pageRef",poi3dConnector.getMessage(47),{pageNr: 1});
    fillPdfOutlineStructure(parentNode,pdfOutlines);
  }
  else if(nrOfPages > 1)
  {
    leftAssemblyBrowser.rebuildTreeViewTable();
    resizeWindow(false);
    openCurrentMultipageImage();
    modelDisplayed = true;

    updatePageBrowser();
    poi3dConnector.getLeftDocument().getSensorObject().updatePositions(myCmiWindow);
  }
  else
  {
    leftAssemblyBrowser.rebuildTreeViewTable();
    resizeWindow(false);
    openCurrentMultipageImage();
    modelDisplayed = true;

    updatePageBrowser();
    poi3dConnector.getLeftDocument().getSensorObject().updatePositions(myCmiWindow);
  }
}
function fillPdfOutlineStructure(parentNode,pdfOutlines)
{
  if (pdfOutlines)
  {
    pdfOutlineCheck = pdfOutlineCheck + pdfOutlines.length;

    for (var i = 0; i < pdfOutlines.length; i++)
    {
      const item = pdfOutlines[i];
      const dest = item.dest;
      if(dest)
      {
        if(typeof dest == "string")
        {
          multiPageDocument.getDestination(dest).then(function(dest)
          {
            const ref = dest[0];          // And the page id
            multiPageDocument.getPageIndex(ref).then(function(id)
            {
              var newNode = leftAssemblyBrowser.addNewNode(parentNode,"pageRef",item.title,{pageNr: parseInt(id) + 1});
              if(item.items.length > 0)
                fillPdfOutlineStructure(newNode,item.items); //Rekursion

              pdfOutlineCheck--;

              if(pdfOutlineCheck == 0)
              {
                leftAssemblyBrowser.rebuildTreeViewTable();
                updatePageBrowser();
                resizeWindow(false);
                openCurrentMultipageImage();
                modelDisplayed = true;
              }
            });
          });
        }
        else
        {
          const ref = dest[0];
          multiPageDocument.getPageIndex(ref).then(function(id)
          {
            var newNode = leftAssemblyBrowser.addNewNode(parentNode,"pageRef",item.title,{pageNr: parseInt(id) + 1});
            if(item.items.length > 0)
              fillPdfOutlineStructure(newNode,item.items); //Rekursion

            pdfOutlineCheck--;

            if(pdfOutlineCheck == 0)
            {
              leftAssemblyBrowser.rebuildTreeViewTable();
              updatePageBrowser();
              resizeWindow(false);
              openCurrentMultipageImage();
              modelDisplayed = true;
            }
          });
        }
      }//if(dest)
      else
      {
        var newNode = leftAssemblyBrowser.addNewNode(parentNode,"pageRef",item.title,{pageNr: -1});
        if(item.items.length > 0)
          fillPdfOutlineStructure(newNode,item.items); //Rekursion

        pdfOutlineCheck--;

        if(pdfOutlineCheck == 0)
        {
          leftAssemblyBrowser.rebuildTreeViewTable();
          updatePageBrowser();
          resizeWindow(false);
          openCurrentMultipageImage();
          modelDisplayed = true;
        }
      }
    }//for (let i = 0; i < pdfOutline.length; i++)
  }//if (pdfOutline)
}//function fillPdfOutlineStructure(parentNode,pdfOutline)

function updatePageBrowser()
{
  if(viewingMode == "2d")
  {
    let annotations = poi3dConnector.getLeftDocument().getAnnotations();
    let sensors = poi3dConnector.getLeftDocument().getSensors();

    let nodeDataWithAttachements = new Array();
    let currObj = null;
    for(let i =0; i<annotations.length; i++)
    {
      currObj = annotations[i];
      for(let k =0; k<currObj.attribs.length; k++)
      {
        if(currObj.attribs[k].key == "pageRef")
          nodeDataWithAttachements.push({pageNr: currObj.attribs[k].val});
      }
    }

    for(let i =0; i<sensors.length; i++)
    {
      nodeDataWithAttachements.push({pageNr: sensors[i].getPageRef()});
    }

    leftAssemblyBrowser.updateNodeTypeByNodeDataArray("pageRefAnn","pageRef",nodeDataWithAttachements);
    leftAssemblyBrowser.rebuildTreeViewTable();
  }
}

function openCurrentMultipageImage(pdfRes)
{
  if(multiPageType == "tif")
  {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var rgba = null;
    var imgd = null;
    var currentPage = multiPageTifArray[currentPageNr-1];

    //Multipage
    UTIF.decodeImage(multiPageDocument,currentPage);
    rgba = UTIF.toRGBA8(currentPage);
    canvas.width = currentPage.width;
    canvas.height = currentPage.height;
    imgd = new ImageData(new Uint8ClampedArray(rgba.buffer),canvas.width,canvas.height);
    ctx.putImageData(imgd,0,0);
    _addBaseImageToModel(canvas.toDataURL("image/png"));
  }
  else if(multiPageType == "pdf")
  {
    multiPageDocument.getPage(currentPageNr).then(function(page)
    {
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      /*
      ctx.imageSmoothingEnabled = true;
      ctx.imageSmoothingQuality = "low"
      */
      var scale = 2.0;
      if(pdfRes != undefined)
      {
        scale = pdfRes;
      }
      else
      {
        clearInterval(pdfResolutionTimer);
        pdfResolutionTimer = null;
      }

      var viewport = page.getViewport({scale: scale});

      canvas.height = viewport.height;
      canvas.width = viewport.width;

      // Render PDF page into canvas context
      var renderContext =
      {
        canvasContext: ctx,
        viewport: viewport
      };

      var renderTask = page.render(renderContext);
      renderTask.promise.then(function ()
      {
        if(pdfResolutionTimer == null)
        {
          pdfResolutionTimer = setInterval(openCurrentMultipageImage, 1000, 4.0);
          _addBaseImageToModel(canvas.toDataURL("image/png"));
        }
        else
        {
          clearInterval(pdfResolutionTimer);
          pdfResolutionTimer = null;
          _updateBaseImage(canvas.toDataURL("image/png"));
        }

      });
    });
  }//else if(multiPageType == "pdf")

  document.getElementById("gPageCnt").innerHTML = currentPageNr+"/"+pageCount;
}

function _addBaseImageToModel(imgSrc)
{
  var img = new Image;
  img.onerror = function (e)
  {
    setStatusText(poi3dConnector.getStatusText(10));//error loading document
  };

  img.onload = function ()
  {
    if(currentImageTexture != null)
    {
      myCmiWindow.removeTexture(currentImageTexture);
      currentImageTexture = null;
      currentModel.removeEntitiesFromModelByNames([currentAnnotationName]);
    }
    var aspect = this.naturalWidth/this.naturalHeight;
    var updateAnnotations = false;

    if((imgSrc.includes('.svg')==true)||imgSrc.includes("data:image/svg")==true)
    {
      var imgWidth = window.innerWidth*3;
      img.setAttribute('width', imgWidth);
      img.setAttribute('height', imgWidth/aspect);
    }

    if(myCmiWindow.getPreloadedTexture(this.src) != null) //No TextureLoad Event
      updateAnnotations = true;

    var annotation = new CmiImageLabelObject(myCmiWindow);
    var widthValue = 100.0;
    currentAnnotationName = "baseImage"+"_"+Date.now().toString(36);

    annotation.entityName = currentAnnotationName;
    annotation.setColor([0.5,0.5,0.5,1.0]);
    annotation.setArrowSize(0.0);
    annotation.setOrientation(myCmiWindow.getCurrentInvModelViewAngles());
    annotation.setLineStartPoint([1.0,0.0,-1.0]);
    annotation.setLineEndPoint([0.0,0.0,-1.0],true);
    annotation.setImagePoint([0.0,0.0,-1.0],true);
    annotation.setBorderStyle(3);
    annotation.setImageWidth(widthValue);
    annotation.setImageheight(widthValue/aspect);
    annotation.setImage(this);
    annotation.buildLabel(false);

    currentModel.addBaseImageToModel(annotation);
    currentImageTexture = annotation.getTexture();

    if(currentPageNr == 1)
      myCmiWindow.zoomAll();

    setStatusText("");

    if(updateAnnotations == true)
      updateAnnotationVisibility();

    //update sensor visibility for current page
    let sensorsObj = poi3dConnector.getLeftDocument().getSensorObject();
    sensorsObj.updatePageVisibility(currentPageNr);
    sensorsObj.updatePositions(myCmiWindow);
  };
  img.setAttribute('crossorigin', 'anonymous');
  img.src = imgSrc;
}

function _updateBaseImage(imgUrl)
{
  var img = new Image;
  img.onerror = function (e)
  {
  };

  img.onload = function ()
  {
    var annotation = currentModel.getEntityByName(currentAnnotationName);

    myCmiWindow.removeTexture(currentImageTexture);

    annotation.setImage(this);
    currentImageTexture = annotation.getTexture();

  };
  img.src = imgUrl;
}
function updateModelAnnotations(documentAnnotations)
{
  switchToLeftBrowser(false);

  //remove old annotations
  var ann = null;
  var annNameArray = new Array();
  var existingAnnotations = leftModel.getEntitiesByType(["cmiSpriteObject","cmiGrepObject","cmiArcObject","cmiLabelObject","cmiTextObject","cmiImageLabelObject"]);
  for (var i=0; i<existingAnnotations.length; i++)
  {
    if(existingAnnotations[i].fromPoi3d != undefined)
      annNameArray.push(existingAnnotations[i].entityName);
  }
  leftModel.removeEntitiesFromModelByNames(annNameArray);

  //create new annotations
  ann = null;
  for (var i=0; i<documentAnnotations.length; i++)
  {
    if((documentAnnotations[i].clNm == "lB")||(documentAnnotations[i].clNm == "iL"))
    {
      //set dynamic leader line creation
      documentAnnotations[i].kTp = true;
    }
    ann = leftModel.addJsonObjectToModel(documentAnnotations[i],false);
    if(ann != null) ann.fromPoi3d = true;
    ann.setVisibility(false);
  }
  leftModel.updateModel();
  layerBrowser.buildLayerList(leftModel,true,0);
  layerBrowser.rebuildLayerViewTable();
  resizeWindow(false);

  if(viewingMode == "2d")
  {
    openCurrentMultipageImage();
    updatePageBrowser();
  }

  updateAnnotationVisibility();
}
function updateModelLocations(documentLocations)
{
  switchToLeftBrowser(false);

  //remove old locations
  var loc = null;
  var locNameArray = new Array();
  var existingLocations = leftModel.getEntitiesByType(["cmiLocatorObject"]);
  for (var i=0; i<existingLocations.length; i++)
  {
    if(existingLocations[i].fromPoi3d != undefined)
      locNameArray.push(existingLocations[i].eNm);
  }

  leftModel.removeEntitiesFromModelByNames(locNameArray);

  //create new locations
  loc = null;
  for (var i=0; i<documentLocations.length; i++)
  {
    loc = leftModel.addJsonObjectToModel(documentLocations[i],false);
    if(loc != null) loc.fromPoi3d = true;
  }
  leftModel.updateModel();

  if(hdlVlocDlg != null) hdlVlocDlg.initialize();
}
function updateModelInstructions(documentInstructions)
{
  for ( let i =0; i< documentInstructions.length; i++)
  {
    documentInstructions[i].assignEntities(leftModel);
  }

  switchToLeftBrowser(false);
  if(defInstrDlg != null) defInstrDlg.initialize();
  if(hdlInstrDlg != null) hdlInstrDlg.initialize();
}
function updateModelSensors(documentSensors)
{
  if(documentSensors.length > 0)
    myCmiWindow.sendModelTransformationInfo = true;
  else
    myCmiWindow.sendModelTransformationInfo = false;

  for ( let i =0; i< documentSensors.length; i++)
  {
    documentSensors[i].assignEntities(leftModel);
  }

  poi3dConnector.getLeftDocument().getSensorObject().updatePageVisibility(currentPageNr);
  poi3dConnector.getLeftDocument().getSensorObject().updatePositions(myCmiWindow);

  switchToLeftBrowser(false);
  if(defSnsDlg != null) defSnsDlg.initialize();
  if(hdlSnsDlg != null) hdlSnsDlg.initialize();

  updatePageBrowser();
}

function updateModelFileAttachments(documentFileAttachments)
{
  for ( let i =0; i< documentFileAttachments.length; i++)
  {
    documentFileAttachments[i].assignEntities(leftModel);
  }

  switchToLeftBrowser(false);
  if(hdlFattDlg != null) hdlFattDlg.initialize();
}
function updateBomStructures(bomStructures)
{
  for ( let i =0; i< bomStructures.length; i++)
  {
    bomStructures[i].connectToModel(leftModel);
  }

  switchToLeftBrowser(false);

  updateBomBrowserSelection();

  leftBomBrowser.clearContent();
  resizeWindow(false);
  if(defBomDlg != null) defBomDlg.initialize();
}
function updateBomBrowserSelection ()
{
  var bomBrowserSelection = document.getElementById("lbrBomSel");

  bomBrowserSelection.options.length = 0;

  if(poi3dConnector.getLeftDocument() != null)
  {
    let bomStructures = poi3dConnector.getLeftDocument().getBomStructures();
    if(bomStructures.length == 0) return;

    var option = document.createElement("option");
    option.text = "   ";
    option.bomRef = null;

    bomBrowserSelection.add(option);
    for ( var i =0; i< bomStructures.length; i++)
    {
      var option = document.createElement("option");
      option.text = " " + bomStructures[i].getTitle() + " ";
      option.bomRef = bomStructures[i];
      bomBrowserSelection.add(option);
    }
  }
}

function updateMaterialSetSelection (materialSets)
{
  let MainToolbarArMaterialSelection = document.getElementById("ArMatSetSelection");
  let MainToolbarVrMaterialSelection = document.getElementById("VrMatSetSelection");
  let MainToolbarMaterialSelection = document.getElementById("MatSetSelection");

  MainToolbarArMaterialSelection.options.length = 0;
  MainToolbarVrMaterialSelection.options.length = 0;
  MainToolbarMaterialSelection.options.length = 0;

  var option = document.createElement("option");
  option.text = "---";
  MainToolbarArMaterialSelection.add(option);

  var option = document.createElement("option");
  option.text = "---";
  MainToolbarVrMaterialSelection.add(option);

  var option = document.createElement("option");
  option.text = "---";
  MainToolbarMaterialSelection.add(option);

  MainToolbarArMaterialSelection.selectedIndex = 0;
  MainToolbarVrMaterialSelection.selectedIndex = 0;
  MainToolbarMaterialSelection.selectedIndex = 0;

  if(materialSets.length > 0)
  {
  	MainToolbarArMaterialSelection.size = materialSets.length + 2;
  	MainToolbarVrMaterialSelection.size = materialSets.length + 2;
  	MainToolbarMaterialSelection.size = materialSets.length + 2;
  }

  for ( let i =0; i< materialSets.length; i++)
  {
    var option = document.createElement("option");
    option.text = materialSets[i].getMaterialSetTitle();
    MainToolbarArMaterialSelection.add(option);

    var option = document.createElement("option");
    option.text = materialSets[i].getMaterialSetTitle();
    MainToolbarVrMaterialSelection.add(option);

    var option = document.createElement("option");
    option.text = materialSets[i].getMaterialSetTitle();
    MainToolbarMaterialSelection.add(option);
  }
}
function updateModelMaterialSets(materialSets)
{
  currentMaterialSetRef = null;

  if(currentMaterialSetCopy != null)
    currentMaterialSetCopy.deleteFromEntities(leftModel);

  for ( let i =0; i< materialSets.length; i++)
  {
    materialSets[i].assignEntities(leftModel);
    materialSets[i].loadTextures(myCmiWindow);

    if((currentMaterialSetCopy != null)&&(currentMaterialSetCopy.getMaterialSetId() == materialSets[i].getMaterialSetId()))
      currentMaterialSetRef = materialSets[i];
  }

  switchToLeftBrowser(false);

  if(currentMaterialSetRef != null)
  {
    currentMaterialSetCopy = currentMaterialSetRef.createCopy(true);
    currentMaterialSetRef.applyToEntities(leftModel);
    myCmiWindow.drawScene();
  }
  else
    currentMaterialSetCopy = null;

  updateMaterialSetSelection(materialSets);

  if(defMtlSetDlg != null) defMtlSetDlg.initialize();
}

function handleMainMenu(menuObject)
{
  var cmdToHandle = menuObject.options[menuObject.selectedIndex].value;
  menuObject.selectedIndex = 0;
  handleCommand(cmdToHandle);
}

function switchToArMode(theCheckbox)
{
  var MainToolbar3d = document.getElementById("MainToolbar3d");
  var MainToolbar2d = document.getElementById("MainToolbar2d");
  var MainToolbarAr = document.getElementById("MainToolbarAr");
  var MainToolbarVr = document.getElementById("MainToolbarVr");
  var ArMatSetSelectionMnu = document.getElementById("ArMatSetSelectionMnu");
  var icons = document.querySelectorAll("#gArMode");

  currentHighlightedEntity = null;

  if(poi3dConnector.getLeftDocument() != null)
  {
    let materialSets = poi3dConnector.getLeftDocument().getMaterialSets();
    let attRights = poi3dConnector.getCurrentAttachmentRights();
    if((materialSets.length > 0)&&(attRights[3].length > 0))
      ArMatSetSelectionMnu.style.display = 'inline-block';
    else
    	ArMatSetSelectionMnu.style.display = 'none';
  }

  //view-source:https://webrtc.github.io/samples/src/content/getusermedia/gum/js/main.js
  //must be https
  var constraints =  window.constraints = {audio: false, video: true};

  if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia)
  {
    if(theCheckbox.checked)
    {
      viewingMode = "AR";
      MainToolbar3d.style.visibility = 'hidden';
      MainToolbar2d.style.visibility = 'hidden';
      MainToolbarAr.style.visibility = 'visible';
      MainToolbarVr.style.visibility = 'hidden';
      for ( var i =0; i<icons.length; i++) {icons[i].checked = true;}
      resizeWindow(false);

      myCmiWindow.switchToPerspective(true);
      myCmiWindow.useTransparentBackground = true;

      constraints = {video: { facingMode: "environment" }};

      navigator.mediaDevices.getUserMedia(constraints).
        then(handleVideo).catch(handleVideoError);
    }
    else
    {
      if(viewingMode.includes("AR+"))
      {
        var pinIcon = document.getElementById("gPinModel");
        pinIcon.checked = false;
        pinModelToEnv(pinIcon);
      }

      myCmiWindow.useTransparentBackground = false;

      viewingMode = "3d";
      MainToolbar3d.style.visibility = 'visible';
      MainToolbar2d.style.visibility = 'hidden';
      MainToolbarAr.style.visibility = 'hidden';
      MainToolbarVr.style.visibility = 'hidden';
      for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}

      resizeWindow(false);

      myCmiWindow.switchToOrtho(true);

      videoElement.pause();
      stopVideoStream(videoStream);
      videoElement.srcObject=null;
    }
  }
  else
  {
    theCheckbox.checked = false;
    setStatusText("your browser does not support getUserMedia function");
  }
}
function switchToVrMode(theCheckbox)
{
  var MainToolbar3d = document.getElementById("MainToolbar3d");
  var MainToolbar2d = document.getElementById("MainToolbar2d");
  var MainToolbarAr = document.getElementById("MainToolbarAr");
  var MainToolbarVr = document.getElementById("MainToolbarVr");
  var icons = document.querySelectorAll("#gVrMode");
  var viewLocations = new Array();

  if(poi3dConnector.getLeftDocument() != null)
  {
    let materialSets = poi3dConnector.getLeftDocument().getMaterialSets();
    let attRights = poi3dConnector.getCurrentAttachmentRights();
    if((materialSets.length > 0)&&(attRights[3].length > 0))
      VrMatSetSelectionMnu.style.display = 'inline-block';
    else
    	VrMatSetSelectionMnu.style.display = 'none';

    viewLocations = poi3dConnector.getLeftDocument().getViewLocations();
  }

  currentHighlightedEntity = null;
  Poi3dHelpers.setDisplayStyle("#SaveCurrentViewerPositionCmd","none");

  if(theCheckbox.checked)
  {
    viewingMode = "VR";
    MainToolbar3d.style.visibility = 'hidden';
    MainToolbar2d.style.visibility = 'hidden';
    MainToolbarAr.style.visibility = 'hidden';
    MainToolbarVr.style.visibility = 'visible';

    for ( var i =0; i<icons.length; i++) {icons[i].checked = true;}
    resizeWindow(false);

    if(viewLocations.length > 0)
    {
      myCmiWindow.showModelLocators = true;
    }
    else
    {
      myCmiWindow.showModelLocators = false;
    }
    handleSelectionSettings();
    myCmiWindow.switchToPerspective(true);
    myCmiWindow.setBgSkyBox("viewer");
    myCmiWindow.useSkyBoxBackground = true;
    myCmiWindow.useTransparentBackground = false;
    myCmiWindow.drawScene();
  }
  else
  {
    if(viewingMode.includes("VR+"))
    {
      var pinIcon = document.getElementById("gPinModel");
      pinIcon.checked = false;
      pinModelToEnv(pinIcon);
    }
    myCmiWindow.useTransparentBackground = false;

    viewingMode = "3d";
    MainToolbar3d.style.visibility = 'visible';
    MainToolbar2d.style.visibility = 'hidden';
    MainToolbarAr.style.visibility = 'hidden';
    MainToolbarVr.style.visibility = 'hidden';

    for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
    resizeWindow(false);

    myCmiWindow.showModelLocators = false;
    myCmiWindow.switchToOrtho(true);
    myCmiWindow.useSkyBoxBackground = false;
    handleSelectionSettings();
    myCmiWindow.zoomAll();
  }
}
function pinModelToEnv(theCheckbox)
{
  var icons = document.querySelectorAll("#gPinModel");
  var zoomIcons = document.querySelectorAll("#tbMseZmImg");

  for (let i =0; i<icons.length; i++) {icons[i].checked = theCheckbox.checked;}

  if(theCheckbox.checked == true)
  {
    if(myCmiWindow.isMobileEnvironment == true)
    {
      //https://stackoverflow.com/questions/56514116/how-do-i-get-deviceorientationevent-and-devicemotionevent-to-work-on-safari
      //Must be https!!!
      /*
      if ( typeof( DeviceMotionEvent ) !== "undefined" && typeof( DeviceMotionEvent.requestPermission ) === "function" )
      {
        DeviceMotionEvent.requestPermission().then( response =>
        {
          if ( response == "granted" )
          {
            myCmiWindow.enableDeviceTracking();
          }
        })
      }
      */

      if (DeviceMotionEvent &&  typeof DeviceMotionEvent.requestPermission === "function")
      {
        DeviceMotionEvent.requestPermission();
      }
      myCmiWindow.enableDeviceTracking();
    }

    myCmiWindow.handleArrowKeys = false;

    if(viewingMode.includes("AR"))
    {
      myCmiWindow.switchTo1stPersonView(true,true);
      switchMouseMode('move');
      viewingMode = "AR+";
    }
    else if(viewingMode.includes("VR"))
    {
      myCmiWindow.switchTo1stPersonView(true,false);
      switchMouseMode('zoom');
      viewingMode = "VR+";
      myCmiWindow.handleArrowKeys = true;
      document.getElementById("mnuAnnTtipTtl").tbPinImg
      for (let i =0; i<zoomIcons.length; i++) {zoomIcons[i].innerHTML = "&#xE13e;";}
      Poi3dHelpers.setDisplayStyle("#SaveCurrentViewerPositionCmd","");
    }
  }
  else
  {
    for (let i =0; i<zoomIcons.length; i++) {zoomIcons[i].innerHTML = "&#xE116;";}

    if(viewingMode.includes("AR"))
      viewingMode = "AR";
    else if(viewingMode.includes("VR"))
      viewingMode = "VR";

    Poi3dHelpers.setDisplayStyle("#SaveCurrentViewerPositionCmd","none");
    myCmiWindow.handleArrowKeys = false;
    isDeviceTrackingActive = false;
    myCmiWindow.setHeadUpAngle4FirstPersonView(0.0);
    myCmiWindow.setHeadRotationAngle4FirstPersonView(0.0);
    myCmiWindow.setHeadSlopeAngle4FirstPersonView(0.0);
    deviceMode = "";
    myCmiWindow.disableDeviceTracking();
    myCmiWindow.switchToModelView(true);
    switchMouseMode('rotate');
  }
}
function useCameraBgInVr(theCheckbox)
{
  var constraints =  window.constraints = {audio: false, video: true};

  if (navigator.mediaDevices.getUserMedia)
  {
    if(theCheckbox.checked)
    {
      constraints = {video: { facingMode: "environment" }};
      navigator.mediaDevices.getUserMedia(constraints).
        then(handleVideo).catch(handleVideoError);

      myCmiWindow.useSkyBoxBackground = false;
      myCmiWindow.useTransparentBackground = true;
      myCmiWindow.drawScene();
    }
    else
    {
      videoElement.pause();
      stopVideoStream(videoStream);
      videoElement.srcObject=null;

      myCmiWindow.useSkyBoxBackground = true;
      myCmiWindow.useTransparentBackground = false;
      myCmiWindow.drawScene();
    }
  }//if (navigator.mediaDevices.getUserMedia)
}//function useCameraBgInVr(theCheckbox)

function switchToStereoView(theCheckbox)
{
  if(theCheckbox.checked)
  {
    myCmiWindow.enableStereoRendering(true);
    myCmiWindow.drawScene();
  }
  else
  {
    myCmiWindow.enableStereoRendering(false);
    myCmiWindow.drawScene();
  }
}

//Video handling -------------------------------------------------------------------------------------
function handleVideo(stream)
{
  videoStream = stream;
  videoElement.srcObject = stream;
  videoElement.onplaying = () => {cmiCanvas.dispatchEvent(new Event('mousemove'));}
}

function handleVideoError(error)
{
  setStatusText('getUserMedia error: ' + error.name);
}

function stopVideoStream (stream)
{
  if(stream == null) return;
  var tracks = stream.getVideoTracks();
  for ( var i =0; i<tracks.length; i++)
  {
    tracks[i].stop()
  }
}
function showFullMainBar(expand)
{
  var MainToolbarCollapsed = document.getElementById("MainToolbarCollapsed");
  var MainToolbar3d = document.getElementById("MainToolbar3d");
  var MainToolbar2d = document.getElementById("MainToolbar2d");
  var MainToolbarAr = document.getElementById("MainToolbarAr");
  var MainToolbarVr = document.getElementById("MainToolbarVr");

  if(expand==true)
  {
    MainToolbarCollapsed.style.visibility = 'hidden';

    if(viewingMode.includes("VR+"))
    {
      Poi3dHelpers.setDisplayStyle("#SaveCurrentViewerPositionCmd","");
    }

    if(viewingMode.includes("AR"))
    {
      MainToolbar3d.style.visibility = 'hidden';
      MainToolbar2d.style.visibility = 'hidden';
      MainToolbarAr.style.visibility = 'visible';
      MainToolbarVr.style.visibility = 'hidden';
    }
    else if(viewingMode.includes("VR"))
    {
      MainToolbar3d.style.visibility = 'hidden';
      MainToolbar2d.style.visibility = 'hidden';
      MainToolbarAr.style.visibility = 'hidden';
      MainToolbarVr.style.visibility = 'visible';
      Poi3dHelpers.setDisplayStyle("#SaveCurrentViewerPositionCmd","none");
    }
    else if(viewingMode.includes("2d"))
    {
      MainToolbar3d.style.visibility = 'hidden';
      MainToolbar2d.style.visibility = 'visible';
      MainToolbarAr.style.visibility = 'hidden';
      MainToolbarVr.style.visibility = 'hidden';
    }
    else
    {
      MainToolbar3d.style.visibility = 'visible';
      MainToolbar2d.style.visibility = 'hidden';
      MainToolbarAr.style.visibility = 'hidden';
      MainToolbarVr.style.visibility = 'hidden';
    }
  }
  else
  {
    if(viewingMode.includes("AR"))
      MainToolbarCollapsed.style.height = (MainToolbarAr.offsetHeight-MainToolbarAr.offsetTop-5)+"px";
    else if(viewingMode.includes("VR"))
      MainToolbarCollapsed.style.height = (MainToolbarVr.offsetHeight-MainToolbarVr.offsetTop-5)+"px";
    else if(viewingMode.includes("2d"))
      MainToolbarCollapsed.style.height = (MainToolbar2d.offsetHeight-MainToolbar2d.offsetTop-5)+"px";
    else
      MainToolbarCollapsed.style.height = (MainToolbar3d.offsetHeight-MainToolbar3d.offsetTop-5)+"px";

    MainToolbarCollapsed.style.visibility = 'visible';
    MainToolbar3d.style.visibility = 'hidden';
    MainToolbar2d.style.visibility = 'hidden';
    MainToolbarAr.style.visibility = 'hidden';
    MainToolbarVr.style.visibility = 'hidden';
  }
}
function takeScreenshot()
{
  if(myCmiWindow.isUsable)
  {
    var newWindow = window.open();
    newWindow.document.open();
    newWindow.document.write("<body style='background-color:#57616B'>");
    newWindow.document.write("<canvas id='ScreenshotCanvas' style='touch-action: none;' width='"+(cmiCanvas.width-5)+"' height='"+(cmiCanvas.height-5)+"'></canvas>");
    newWindow.document.write("</body>");
    var imageCanvas = newWindow.document.getElementById("ScreenshotCanvas");
    var imageContext = imageCanvas.getContext('2d');
    var canvasAspect = cmiCanvas.height/cmiCanvas.width;

    imageContext.fillStyle = myCmiWindow.getBgColorRGBString();
    imageContext.fillRect(0, 0, imageCanvas.width, imageCanvas.height);

    //draw the video content
    if(videoElement.srcObject != null)
    {
      var videoAspect,vWidth,vHeight,vPosX,vPosY;

      videoAspect = videoElement.videoHeight/videoElement.videoWidth;
      if(canvasAspect > videoAspect)
      {
        vWidth=cmiCanvas.width;
        vHeight=vWidth*videoAspect;
        vPosX=0;
        vPosY=parseInt((cmiCanvas.height-vHeight)*0.5);
      }
      else
      {
        vHeight=cmiCanvas.height;
        vWidth=vHeight/videoAspect;
        vPosX=parseInt((cmiCanvas.width-vWidth)*0.5);
        vPosY=0;
      }
      imageContext.drawImage(videoElement, vPosX, vPosY, vWidth, vHeight);
    }

    //draw the model content
    var modelImage = myCmiWindow.getImageObjectFromWebGlWindow();  //Gets the webgl content as an image
    modelImage.onload = function (drawContext)
    {
      return function()
      {
        drawContext.drawImage(this, 0, 0);
      }
    }(imageContext);

    newWindow.document.close();
  }
}

// ==================================== Browser ============================

function switchBrowserView(viewMode)
{
  var leftBrowserArea = document.getElementById("leftBrowserArea");
  var structureView= document.getElementById("structureView");
  var layerView= document.getElementById("layerView");
  var bomView= document.getElementById("bomView");
  var leftLayerContentArea= document.getElementById("leftLayerContentArea");
  var leftAssemblyContentArea= document.getElementById("leftAssemblyContentArea");
  var leftBomContentArea= document.getElementById("leftBomContentArea");
  var leftBrowserGenPosNrsTitle=document.getElementById("lbrGenPosTtl");

  if(viewMode == "struct")
  {
    leftBrowserGenPosNrsTitle.style.display = 'none';
    leftLayerContentArea.style.visibility = 'hidden';
    leftBomContentArea.style.visibility = 'hidden';
    if(leftBrowserArea.style.visibility == 'visible')
      leftAssemblyContentArea.style.visibility = 'visible';

    structureView.checked = true;
    layerView.checked = false;
    bomView.checked = false;

    if(viewingMode == "2d")
    {
      document.getElementById("lbrCompHdrTtl").innerHTML = poi3dConnector.getMessage(43);
      document.getElementById("lbrShowCompImg").setAttribute("hidden", "hidden");
      document.getElementById("lbrSelectCompImg").setAttribute("hidden", "hidden");
      Poi3dHelpers.setDisplayStyle("lbrActivateBut","none");

      document.getElementById("leftBrowserHideInvisLabel").style.filter = "blur(2px)";
      document.getElementById("leftBrowserHideInvis").disabled = true;
      document.getElementById("leftBrowserSortAlphaLabel").style.filter = "blur(2px)";
      document.getElementById("leftBrowserSortAlpha").disabled = true;
      document.getElementById("leftBrowserSortPosLabel").style.filter = "blur(2px)";
      document.getElementById("leftBrowserSortPos").disabled = true;
      document.getElementById("leftBrowserCollectLabel").style.filter = "blur(2px)";
      document.getElementById("leftBrowserCollect").disabled = true;

      document.getElementById("leftBrowserTableSearchbar").style.filter = "blur(2px)";
      document.getElementById("lbrSearchVal").disabled = true;
      document.getElementById("leftCaseSensitiveSwitch").disabled = true;
      document.getElementById("lbrStartSrchImg").disabled = true;
    }
    else //if(viewMode == "2d")
    {
      let cmpCnt = leftAssemblyBrowser.getNodeCount();
      let hlCnt = leftAssemblyBrowser.getHlNodeCount();

      document.getElementById("lbrCompHdrTtl").innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
      document.getElementById("lbrShowCompImg").removeAttribute("hidden");
      document.getElementById("lbrSelectCompImg").removeAttribute("hidden");
      Poi3dHelpers.setDisplayStyle("lbrActivateBut","table-cell");

      document.getElementById("leftBrowserHideInvisLabel").style.filter = "blur(0px)";
      document.getElementById("leftBrowserHideInvis").disabled = false;
      document.getElementById("leftBrowserSortAlphaLabel").style.filter = "blur(0px)";
      document.getElementById("leftBrowserSortAlpha").disabled = false;
      document.getElementById("leftBrowserSortPosLabel").style.filter = "blur(0px)";
      document.getElementById("leftBrowserSortPos").disabled = false;
      document.getElementById("leftBrowserCollectLabel").style.filter = "blur(0px)";
      document.getElementById("leftBrowserCollect").disabled = false;

      document.getElementById("leftBrowserTableSearchbar").style.filter = "blur(0px)";
      document.getElementById("lbrSearchVal").disabled = false;
      document.getElementById("leftCaseSensitiveSwitch").disabled = false;
      document.getElementById("lbrStartSrchImg").disabled = false;
    }
  }
  else if(viewMode == "bom")
  {
    leftBrowserGenPosNrsTitle.style.display = 'flex';
    leftLayerContentArea.style.visibility = 'hidden';
    leftAssemblyContentArea.style.visibility = 'hidden';
    if(leftBrowserArea.style.visibility == 'visible')
      leftBomContentArea.style.visibility = 'visible';

    structureView.checked = false;
    layerView.checked = false;
    bomView.checked = true;

    let cmpCnt = leftBomBrowser.getNodeCount();
    let hlCnt = leftBomBrowser.getHlNodeCount();

    document.getElementById("lbrBomHdrTtl").innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
    document.getElementById("lbrShowCompImg").removeAttribute("hidden");
    document.getElementById("lbrSelectCompImg").removeAttribute("hidden");
    Poi3dHelpers.setDisplayStyle("lbrActivateBut","table-cell");

    document.getElementById("leftBrowserHideInvisLabel").style.filter = "blur(0px)";
    document.getElementById("leftBrowserHideInvis").disabled = false;
    document.getElementById("leftBrowserSortAlphaLabel").style.filter = "blur(0px)";
    document.getElementById("leftBrowserSortAlpha").disabled = false;
    document.getElementById("leftBrowserSortPosLabel").style.filter = "blur(0px)";
    document.getElementById("leftBrowserSortPos").disabled = false;
    document.getElementById("leftBrowserCollectLabel").style.filter = "blur(0px)";
    document.getElementById("leftBrowserCollect").disabled = false;

    document.getElementById("leftBrowserTableSearchbar").style.filter = "blur(0px)";
    document.getElementById("lbrSearchVal").disabled = false;
    document.getElementById("leftCaseSensitiveSwitch").disabled = false;
    document.getElementById("lbrStartSrchImg").disabled = false;
  }
  else//else if(viewMode == "bom")
  {
    if(leftBrowserArea.style.visibility == 'visible')
      leftLayerContentArea.style.visibility = 'visible';

    leftBomContentArea.style.visibility = 'hidden';
    leftAssemblyContentArea.style.visibility = 'hidden';

    structureView.checked = false;
    layerView.checked = true;
    bomView.checked = false;

    document.getElementById("leftBrowserHideInvisLabel").style.filter = "blur(2px)";
    document.getElementById("leftBrowserHideInvis").disabled = true;
    document.getElementById("leftBrowserSortAlphaLabel").style.filter = "blur(2px)";
    document.getElementById("leftBrowserSortAlpha").disabled = true;
    document.getElementById("leftBrowserSortPosLabel").style.filter = "blur(2px)";
    document.getElementById("leftBrowserSortPos").disabled = true;
    document.getElementById("leftBrowserCollectLabel").style.filter = "blur(2px)";
    document.getElementById("leftBrowserCollect").disabled = true;

    document.getElementById("leftBrowserTableSearchbar").style.filter = "blur(2px)";
    document.getElementById("lbrSearchVal").disabled = true;
    document.getElementById("leftCaseSensitiveSwitch").disabled = true;
    document.getElementById("lbrStartSrchImg").disabled = true;
  }

  resizeWindow(false);
}

function switchMouseMode(mode)
{
  setStatusText("");

  if((pickPoints.length > 0)&&(measDlgVisible == false))
  {
    myCmiWindow.getCmiModel().removeLocatorsFromModelByNames(pickPoints);
    pickPoints = new Array();
  }
  mouseMode = mode;

  if(!viewingMode.includes("VR"))
    myCmiWindow.showModelLocators = false;

  var icons;
  switch(mode)
  {
    case "selectInBrowser":
      myCmiWindow.setMouseModeToSelection();

      icons = document.querySelectorAll("#gMouseSelect"); for ( var i =0; i<icons.length; i++) {icons[i].checked = true;}
      icons = document.querySelectorAll("#gMouseMove"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseZoom"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseRotate"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMousePick"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      interactionMode = "selectInBrowser";

      break;
    case "select":
      myCmiWindow.setMouseModeToSelection();

      icons = document.querySelectorAll("#gMouseSelect"); for ( var i =0; i<icons.length; i++) {icons[i].checked = true;}
      icons = document.querySelectorAll("#gMouseMove"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseZoom"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseRotate"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMousePick"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}

      break;
    case "move":
      interactionMode = "";
      myCmiWindow.setMouseModeToMovement();

      icons = document.querySelectorAll("#gMouseSelect"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseMove"); for ( var i =0; i<icons.length; i++) {icons[i].checked = true;}
      icons = document.querySelectorAll("#gMouseZoom"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseRotate"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMousePick"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}

      break;
    case "zoom":
      interactionMode = "";
      myCmiWindow.setMouseModeToZoom();

      icons = document.querySelectorAll("#gMouseSelect"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseMove"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseZoom"); for ( var i =0; i<icons.length; i++) {icons[i].checked = true;}
      icons = document.querySelectorAll("#gMouseRotate"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMousePick"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}

      break;
    case "rotate":
      interactionMode = "";
      myCmiWindow.setMouseModeToRotation();

      icons = document.querySelectorAll("#gMouseSelect"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseMove"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseZoom"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseRotate"); for ( var i =0; i<icons.length; i++) {icons[i].checked = true;}
      icons = document.querySelectorAll("#gMousePick"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}

      break;
    case "pick":
      myCmiWindow.setMouseModeToPicking();
      myCmiWindow.showModelLocators = true;

      icons = document.querySelectorAll("#gMouseSelect"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseMove"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseZoom"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMouseRotate"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}
      icons = document.querySelectorAll("#gMousePick"); for ( var i =0; i<icons.length; i++) {icons[i].checked = false;}

      break;
  }

  handleSelectionSettings();
}

// ==================================== Command handlers ============================
function handleMmCtxCommand(cmd)
{
  switch(cmd)
  {
    case "MmCtxFileAttShowCmd":
      if(leftModel != null) showHdlFattDlg(null,"std",null);
      break;
    case "MmCtxShowPropCmd":
      if(leftModel != null) showPropDlg(null,null,"model",null);
      break;
    case "MmCtxCancelCmd":
      myCmiWindow.drawScene();
      break;
    default:
      break;
  }
}
function handleCmpCtxCommand(cmd)
{
  if(currentHighlightedEntity == null)
    return;
  if(currentHighlightedEntity.getClassName() != "cmiComponentObject")
    return;

  var sel=null;

  switch(cmd)
  {
    case "CmpCtxShowPropCmd":
      showPropDlg(null,[currentHighlightedEntity],"model",null);
      break;
    case "MultiCmpCtxDeSelAllCmd":
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      rightAssemblyBrowser.switchHighlightStateForAll(false);
      break;
    case "MultiCmpCtxHideCmd":
    case "CmpCtxHideCmd":
      let hlCmps = myCmiWindow.getCmiModel().getHighlightedComponents();
      if(hlCmps.length == 0)
      {
        if((currentHighlightedEntity.getBrowserVisibleState() >= 3)&&(currentHighlightedEntity.getParentComponent() != null))
        {
          currentHighlightedEntity.getParentComponent().setVisibility(false);
          currentHighlightedEntity.getParentComponent().isHighlighted = false;
        }
        else
        {
          currentHighlightedEntity.setVisibility(false);
          currentHighlightedEntity.isHighlighted = false;
        }
      }
      else
      {
        for ( let i =0; i<hlCmps.length; i++)
        {
          hlCmps[i].setVisibility(false);
          hlCmps[i].isHighlighted = false;
        }
      }
      if(myCmiWindow.getCmiModel() == leftModel)
      {
        leftAssemblyBrowser.rebuildTreeViewTable();
        leftBomBrowser.rebuildTreeViewTable();
      }
      else
        rightAssemblyBrowser.rebuildTreeViewTable();

      break;
    case "CmpCtxSelectInBrowserCmd":
      var hlCellId = null;
      var row = null;

      if(myCmiWindow.getCmiModel() == leftModel)
      {
        if(document.getElementById("leftBrowserArea").style.visibility != 'visible')
          showLeftTable(true);

        if(currentHighlightedEntity.isHighlighted == false)
        {
          hlCellId = leftAssemblyBrowser.switchHighlightStateOfComponent(currentHighlightedEntity,true);
          row = document.getElementById(hlCellId);
          if(row != null)
            row.scrollIntoView({behavior: 'smooth',block: 'center'});

          hlCellId = leftBomBrowser.switchHighlightStateOfComponentNode(currentHighlightedEntity,true);
          if(hlCellId.length > 0)
          {
            row = document.getElementById(hlCellId);
            if(row != null)
              row.scrollIntoView({behavior: 'smooth',block: 'center'});
          }
        }
        else
        {
          hlCellId = leftAssemblyBrowser.expandComponentBranch([currentHighlightedEntity]);
          row = document.getElementById(hlCellId);
          if(row != null)
            row.scrollIntoView({behavior: 'smooth',block: 'center'});
        }
      }
      else
      {
        if(document.getElementById("rightBrowserArea").style.visibility != 'visible')
          showRightTable(true);

        if(currentHighlightedEntity.isHighlighted == false)
          hlCellId = rightAssemblyBrowser.switchHighlightStateOfComponent(currentHighlightedEntity,true);
        else
          hlCellId = rightAssemblyBrowser.expandComponentBranch([currentHighlightedEntity]);

        var row = document.getElementById(hlCellId);
        if(row != null)
          row.scrollIntoView({behavior: 'smooth',block: 'center'});
      }
      break;
    case "CmpCtxSlInstCmd":
      handleLeftBrowserCtxCommand("LAsmBrCtxSlInstCmd");
      let cmpCnt = leftAssemblyBrowser.getNodeCount();
      let hlCnt = leftAssemblyBrowser.getHlNodeCount();
      document.getElementById("lbrCompHdrTtl").innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
      
      break;
    case "MultiCmpCtxSelectCmd":
    case "CmpCtxSelectCmd":
      var hlCellId = null;
      if(myCmiWindow.getCmiModel() == leftModel)
      {
        if(currentHighlightedEntity.isHighlighted == false)
        {
          hlCellId = leftAssemblyBrowser.switchHighlightStateOfComponent(currentHighlightedEntity,true);
          hlCellId = leftBomBrowser.switchHighlightStateOfComponentNode(currentHighlightedEntity,true);
        }
        else
          hlCellId = leftAssemblyBrowser.switchHighlightStateOfComponent(currentHighlightedEntity,false);
      }
      else
      {
        if(currentHighlightedEntity.isHighlighted == false)
          hlCellId = rightAssemblyBrowser.switchHighlightStateOfComponent(currentHighlightedEntity,true);
        else
          hlCellId = leftAssemblyBrowser.switchHighlightStateOfComponent(currentHighlightedEntity,false);
      }
      break;
    case "CmpCtxFileAttShowCmd":
      showHdlFattDlg(null,cmd,currentHighlightedEntity);
      break;
    case "CmpCtxFileAttDefineCmd":
      showMultSelDlg(null,cmd,currentHighlightedEntity,null);
      break;
    case "CmpCtxRemoveMaterialCmd":
      if(currentHighlightedEntity.isHighlighted == false)
      {
        leftAssemblyBrowser.switchHighlightStateOfComponent(currentHighlightedEntity,true);
        leftBomBrowser.switchHighlightStateOfComponentNode(currentHighlightedEntity,true);
      }

      sel = leftAssemblyBrowser.getHighlightedComponents(true);
      leftModel.restoreEntityMaterial(sel);
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      break;
    case "CmpCtxCancelCmd":
    default:
      break;
  }

  currentHighlightedEntity=null;
  myCmiWindow.drawScene();
  
}
function handleAnnCtxCommand(cmd)
{
  if(currentHighlightedEntity == null)
    return;

  switch(cmd)
  {
    case "AnnCtxEditCmd":
      selectedEntity=currentHighlightedEntity;
      interactionMode = "selectToEdit";
      if(selectedEntity.cmiType == 3)//Text
      {
        document.getElementById("labAnnDlg_LayVal").value = selectedEntity.getLayer().getLayerName();
        document.getElementById("labAnnDlg_TlTipVal").value = selectedEntity.getSelectionInfo();
        document.getElementById("labAnnDlg_TxtVal").value = selectedEntity.getText();
        var oglCol = selectedEntity.getColor();
        document.getElementById("labAnnDlg_ColVal").value = Poi3dHelpers.oglToHex(oglCol);
        var oglBgCol = selectedEntity.getBgColor();
        document.getElementById("labAnnDlg_BgColVal").value = Poi3dHelpers.oglToHex(oglBgCol);
        if(oglBgCol[3] == 0) document.getElementById("labAnnDlg_hasBgColVal").checked = false;
        else document.getElementById("labAnnDlg_hasBgColVal").checked = true;
        showLabAnnDlg(null,selectedEntity);
      }
      else if(selectedEntity.cmiType == 13)//Text Label
      {
        document.getElementById("txtAnnDlg_LayVal").value = selectedEntity.getLayer().getLayerName();
        document.getElementById("txtAnnDlg_TlTipVal").value = selectedEntity.getSelectionInfo();
        document.getElementById("txtAnnDlg_TextVal").value = selectedEntity.getText();
        var oglCol = selectedEntity.getColor();
        document.getElementById("txtAnnDlg_ColVal").value = Poi3dHelpers.oglToHex(oglCol);
        var oglBgCol = selectedEntity.getBgColor();
        document.getElementById("txtAnnDlg_BgColVal").value = Poi3dHelpers.oglToHex(oglBgCol);
        if(oglBgCol[3] == 0) document.getElementById("txtAnnDlg_hasBgColVal").checked = false;
        else document.getElementById("txtAnnDlg_hasBgColVal").checked = true;
        showTxtAnnDlg(null,selectedEntity);
      }
      else if(selectedEntity.cmiType == 42)//Image Label
      {
        document.getElementById("imgAnnDlg_LayVal").value = selectedEntity.getLayer().getLayerName();
        document.getElementById("imgAnnDlg_TlTipVal").value = selectedEntity.getSelectionInfo();
        document.getElementById("imgAnnDlg_ImgVal").src = selectedEntity.getImageData();
        document.getElementById("imgAnnDlg_WidthVal").value = selectedEntity.getImageWidth();
        var oglCol = selectedEntity.getColor();
        document.getElementById("imgAnnDlg_ColVal").value = Poi3dHelpers.oglToHex(oglCol);
        showImgAnnDlg(null,selectedEntity);
      }
      else if(selectedEntity.cmiType == 29)//Info Point
      {
        document.getElementById("infoPntDlg_LayVal").value = selectedEntity.getLayer().getLayerName();
        document.getElementById("infoPntDlg_TlTipVal").value = selectedEntity.getSelectionInfo();
        document.getElementById("infoPntDlg_HrefVal").value = selectedEntity.getUrlInfo();
        showInfoPntDlg(null,selectedEntity);
      }
      else if (selectedEntity.cmiType == 2)//Circle
      {
        document.getElementById("areaAnnDlg_LayVal").value = selectedEntity.getLayer().getLayerName();
        document.getElementById("areaAnnDlg_TlTipVal").value = selectedEntity.getSelectionInfo();

        var oglCol = selectedEntity.getColor();
        document.getElementById("areaAnnDlg_ColVal").value = Poi3dHelpers.oglToHex(oglCol);
        showAreaAnnDlg(null,"circle",selectedEntity);
      }
      else if (selectedEntity.cmiType == 19)//Grep
      {
        document.getElementById("areaAnnDlg_LayVal").value = selectedEntity.getLayer().getLayerName();
        document.getElementById("areaAnnDlg_TlTipVal").value = selectedEntity.getSelectionInfo();

        var oglCol = selectedEntity.getColor();
        document.getElementById("areaAnnDlg_ColVal").value = Poi3dHelpers.oglToHex(oglCol);

        var annType = selectedEntity.getPropertyValue("annTyp");

        if(annType != null)
          showAreaAnnDlg(null,annType,selectedEntity);
      }
      break;
    case "AnnCtxDeleteCmd":
      switch(currentHighlightedEntity.cmiType)
      {
        case 3:
        case 13:
        case 42:
        case 29:
        case 2:
        case 19:
        {
          leftModel.removeEntitiesFromModelByNames([currentHighlightedEntity.entityName]);
          let annotations = poi3dConnector.getLeftDocument().getAnnotations();

          for (var i=0; i<annotations.length; i++)
          {
            if(annotations[i].eNm == currentHighlightedEntity.entityName)
            {
              annotations = annotations.filter(function(item) {return item !== annotations[i]});
              i = annotations.length;
            }
          }
        	poi3dConnector.getLeftDocument().setAnnotations(annotations);
          updatePageBrowser();
        }
        break;
      }
      break;
    case "AnnCtxCancelCmd":
      currentHighlightedEntity.resetHighlight();
      currentHighlightedEntity = null;
      myCmiWindow.drawScene();
      break;
    default:
      break;
  }
}

function handleBomCtxCommand(cmd)
{
  var components = leftBomBrowser.getHighlightedComponents(true);
  var bomStructures = poi3dConnector.getLeftDocument().getBomStructures();
  var bomObject = poi3dConnector.getLeftDocument().getBomStructureObject();

  if(cmd == "SwitchBomInBrowserCmd")
  {
    if(bomStructures.length == 0) return;

    let bomBrowserSelection = document.getElementById("lbrBomSel");
    let selectedBom = bomBrowserSelection[bomBrowserSelection.selectedIndex].bomRef;

    if(selectedBom == null)
    {
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.clearContent();
    }
    else
    {
      leftBomBrowser.switchHighlightStateForAll(false);
      leftAssemblyBrowser.switchHighlightStateForAll(false);

      leftBomBrowser.saveTableLayout();
      leftBomBrowser.buildProductStructureTree(selectedBom);
      leftBomBrowser.restoreTableLayout();
      leftBomBrowser.rebuildTreeViewTable();
    }
    myCmiWindow.drawScene();
    switchBrowserView('bom');
    return;
  }

  if(components.length == 0)
    return;

  let cmpCnt=0;
  let hlCnt=0;

  switch(cmd)
  {
    case "BomCtxResetCmd":
      leftBomBrowser.setModificationFlagToSelectedNodes("");
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      bomObject.setLocalChangeFlag(true);

      cmpCnt = leftBomBrowser.getNodeCount();
      hlCnt = leftBomBrowser.getHlNodeCount();

      document.getElementById("lbrBomHdrTtl").innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
      myCmiWindow.drawScene();
      break;
    case "BomCtxSuppressCmd":
      leftBomBrowser.setModificationFlagToSelectedNodes("sc");
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      bomObject.setLocalChangeFlag(true);

      cmpCnt = leftBomBrowser.getNodeCount();
      hlCnt = leftBomBrowser.getHlNodeCount();
      document.getElementById("lbrBomHdrTtl").innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
      myCmiWindow.drawScene();
      break;
    case "BomCtxSuppressSubCmd":
      leftBomBrowser.setModificationFlagToSelectedNodes("ss");
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      bomObject.setLocalChangeFlag(true);

      cmpCnt = leftBomBrowser.getNodeCount();
      hlCnt = leftBomBrowser.getHlNodeCount();
      document.getElementById("lbrBomHdrTtl").innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
      myCmiWindow.drawScene();
      break;
    case "BomCtxMoveUpCmd":
      leftBomBrowser.setModificationFlagToSelectedNodes("mus");
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      bomObject.setLocalChangeFlag(true);

      cmpCnt = leftBomBrowser.getNodeCount();
      hlCnt = leftBomBrowser.getHlNodeCount();
      document.getElementById("lbrBomHdrTtl").innerHTML = poi3dConnector.getMessage(42)+"&nbsp;" + "("+hlCnt+"/"+cmpCnt+")";
      myCmiWindow.drawScene();
      break;
    case "BomCtxManageAttCmd":
      let psLinks = leftBomBrowser.getHighlightedStructureLinks(true);
      let currBom = leftBomBrowser.getProductStructure();
      showPropDlg(null,psLinks,"bom",currBom);
      break;
    case "BomCtxCancelCmd":
      currentHighlightedEntity = null;
      break;
    default:
      break;
  }
}

function handleBomPropCtxCommand(cmd)
{
  switch(cmd)
  {
    case "DoBoPropCtxNewPropCmd":
      propDlg.addNewAttribute();
      break;
    case "DoBoPropCtxDeletePropCmd":
      propDlg.deleteAttribute();
      break;
    case "DoBoPropCtxCutPropCmd":
      propDlg.cutAttribute();
      break;
    case "DoBoPropCtxCopyPropCmd":
      propDlg.copyAttribute();
      break;
    case "DoBoPropCtxPastePropCmd":
      propDlg.pasteAttribute();
      break;
    case "DoBoPropCtxDefineAsExtKeyCmd":
      propDlg.setkeyColumn();
      break;
    case "DoBoPropCtxImportPropCmd":
      showMultSelDlg(null,cmd,propDlg.entityArray,propDlg.importModelAttribute);
      break;
    case "DoBoPropCtxSortAscCmd":
      propDlg.sort("asc");
      break;
    case "DoBoPropCtxSortDescCmd":
      propDlg.sort("dsc");
      break;
    case "DoBoPropCtxCancelCmd":
    default:
      propDlg.enableCellEdit = true;
      break;
  }
}

function handleChatCtxCommand(cmd)
{
  switch(cmd)
  {
    case "ChatCtxCopyCmd":
      commDlg.copyTextToClipboard();
      break;
    case "ChatCtxReplyCmd":
      commDlg.replyToChat();
      break;
    case "ChatCtxFilterCmd":
      commDlg.filterChat();
      break;
    case "ChatCtxDelFilterCmd":
      commDlg.updateChatSection("");
      break;
    case "ChatCtxCancelCmd":
      commDlg.clickedChatRow = -1;
      break;
  }
}

function handleCommand(currentCommand)
{
  switch(currentCommand)
  {
    case "ReportAbuseCmd":
      if(poi3dConnector.getPoi3dUser().isLoggedIn() == false)
      {
        showMsgDlg(null,poi3dConnector.getMessage(3));//"You are not logged in"
        return;
      }
      break;
    case "Poi3dPortalManageCmd":
    case "GetAuthorRightsCmd":
    case "ShChatCmd":
    case "ShCommDlgCmd":
      if(poi3dConnector.checkUserAccess()==false)
      {
        showMsgDlg(null,poi3dConnector.getMessage(3));//"You must be logged in to use this function"
        return;
      }
      break;
    case "UploadFileAttachmentCmd":
    case "LoadFileAttachmentsCmd":
    case "DelAllFileAttachmentsCmd":
    case "SaveFileAttachmentsCmd":
      if(poi3dConnector.hasUserAuthorRights() == false)
      {
        showMsgDlg(null,poi3dConnector.getMessage(4));//"You must be logged in as an author to use this function"
        return;
      }
      break;
    case "LockAnnCmd":
    case "LockInstructionsCmd":
    case "LockSensorsCmd":
    case "LockMaterialDefsCmd":
    case "LockBomsCmd":
    case "LockFileAttachmentsCmd":
    case "LockViewLocCmd":
    case "LockDocAttrCmd":
    case "UnlockAnnCmd":
    case "UnlockInstructionsCmd":
    case "UnlockSensorsCmd":
    case "UnlockMaterialDefsCmd":
    case "UnlockFileAttachmentsCmd":
    case "UnlockBomsCmd":
    case "UnlockViewLocCmd":
    case "UnlockDocAttrCmd":
    case "UploadFileAttachmentCmd":
    case "DelAllFileAttachmentsCmd":
    case "SaveFileAttachmentsCmd":
    case "UploadFileAttachmentCmd":
      if(poi3dConnector.getPoi3dUser().isLoggedIn() == false)
      {
        showMsgDlg(null,poi3dConnector.getMessage(3));//"You are not logged in"
        return;
      }
      else if((leftModel == null)||(poi3dConnector.isDocumentAccessible() == false))
      {
        showMsgDlg(null,poi3dConnector.getMessage(5));//"Document not writeable"
        return;
      }
      break;
    case "UserSettingsCmd":
    case "Poi3dPortalManageCmd":
    case "RegisterUserCmd":
    case "ManageUsersCmd":
    case "PortalSettingsCmd":
    case "DownloadConverterCmd":
    case "LoadModCmd":
    case "LoadModFromFileCmd":
    case "LoadCmpModCmd":
    case "LoadCmpModFromFileCmd":
    case "ResetModCmd":
    case "AboutPortalCmd":
    case "ShPrimModStructCmd":
    case "ShCmpModStructCmd":
    case "Poi3dPortalLogInCmd":
    case "Poi3dPortalLogOffCmd":
    case "AboutPortalCmd":
    case "ShowNotDlg":
      break;
    default:
      if(leftModel == null)
      {
        showMsgDlg(null,poi3dConnector.getMessage(5));//"Document not writeable"
        return;
      }
      break;
  }

  switch(currentCommand)
  {
    case "ReportAbuseCmd":
      var userList = poi3dConnector.getAdminUsers();
      if(userList.length >0)
        showTxtInputDlg(null,"SendAbuseMail",userList);
      else
        showMsgDlg(null,poi3dConnector.getMessage(58));//"User not found"

      break;
    case "ViewFrontCmd":
      if(viewingMode=="3d")
      {
        lastStartedAnimation = "viewAnimationFront";
        viewAnimation.clearAnimation();
        viewAnimation.addShowView("Front",20);
        viewAnimation.run(1);
      }
      else
        myCmiWindow.showOglStdView("Front");

      break;
    case "ViewBackCmd":
      if(viewingMode=="3d")
      {
        lastStartedAnimation = "viewAnimationBack";
        viewAnimation.clearAnimation();
        viewAnimation.addShowView("Back",20);
        viewAnimation.run(1);
      }
      else
        myCmiWindow.showOglStdView("Back");
      break;
    case "ViewLeftCmd":
      if(viewingMode=="3d")
      {
        lastStartedAnimation = "viewAnimationLeft";
        viewAnimation.clearAnimation();
        viewAnimation.addShowView("Left",20);
        viewAnimation.run(1);
      }
      else
        myCmiWindow.showOglStdView("Left");
      break;
    case "ViewRightCmd":
      if(viewingMode=="3d")
      {
        lastStartedAnimation = "viewAnimationRight";
        viewAnimation.clearAnimation();
        viewAnimation.addShowView("Right",20);
        viewAnimation.run(1);
      }
      else
        myCmiWindow.showOglStdView("Right");
      break;
    case "ViewTopCmd":
      if(viewingMode=="3d")
      {
        lastStartedAnimation = "viewAnimationTop";
        viewAnimation.clearAnimation();
        viewAnimation.addShowView("Top",20);
        viewAnimation.run(1);
      }
      else
        myCmiWindow.showOglStdView("Top");
      break;
    case "ViewBottomCmd":
      if(viewingMode=="3d")
      {
        lastStartedAnimation = "viewAnimationBottom";
        viewAnimation.clearAnimation();
        viewAnimation.addShowView("Bottom",20);
        viewAnimation.run(1);
      }
      else
        myCmiWindow.showOglStdView("Bottom");
      break;
    case "ViewISOCmd":
      if(viewingMode=="3d")
      {
        lastStartedAnimation = "viewAnimationIso";
        viewAnimation.clearAnimation();
        viewAnimation.addShowView("ISO",20);
        viewAnimation.run(1);
      }
      else
        myCmiWindow.showOglStdView("ISO");
      break;
    case "HandleCutPlane":
      showPlCutDlg(null);
      break;
    case "TakeScreenShot":
      takeScreenshot();
      break;
    case "UserSettingsCmd":
      showUSetDlg(null);
      break;
    case "Poi3dPortalManageCmd":
        showDocMgmtDlg(null);
      break;
    case "GetAuthorRightsCmd":
      if(poi3dConnector.isUserAuthor()==true)
        showMsgDlg(null,poi3dConnector.getMessage(12));//You already have author rights"
      else
        showGetAutRghtDlg(null);
      break;
    case "Measure":
      showMeasDlg(null);
      break;
    case "RegisterUserCmd":
      showRegUserDlg(null);
      break;
    case "ManageUsersCmd":
      showUMgmDlg(null);
      break;
    case "PortalSettingsCmd":
      showPtlSettDlg(null);
      break;
    case "DownloadConverterCmd":
      showDwnldDlg(null);
      break;
    case "LoadModCmd":
      myCmiWindow.currentCommand = "OpenMod";
      poi3dConnector.openPrimaryModelFromHost();
      break;
    case "LoadModFromFileCmd":
      if(myCmiWindow.isMobileEnvironment == true)
        showMobFopenDlg(null);
      else
        Poi3dDocumentLoader.selectFile("left");
      break;
    case "LoadCmpModCmd":
      myCmiWindow.currentCommand = "OpenCmpMod";
      if(leftModel != null)
        poi3dConnector.openCompareModelFromHost(leftModel.getModelName());
      else
        poi3dConnector.openCompareModelFromHost("");
      break;
    case "LoadCmpModFromFileCmd":
      if(myCmiWindow.isMobileEnvironment == true)
        showMobFopenDlg(null);
      else
        Poi3dDocumentLoader.selectFile("right");
      break;
    case "ResetModCmd":
      resetViewer(false);
      poi3dConnector.setLeftDocument(null);
      break;
    case "LeftBrowserHideSelCmd":
      if(leftModel == null) break;

      leftAssemblyBrowser.hideSelectedNodes();
      leftBomBrowser.hideSelectedNodes();
      myCmiWindow.drawScene();
      break;
    case "LeftBrowserHideUnSelCmd":
      if(leftModel == null) break;

      leftAssemblyBrowser.hideUnSelectedNodes();
      leftBomBrowser.hideUnSelectedNodes();
      myCmiWindow.drawScene();
      break;
    case "RightBrowserHideSelCmd":
      if(rightModel == null) break;

      rightAssemblyBrowser.hideSelectedNodes();
      myCmiWindow.drawScene();
      break;
    case "RightBrowserHideUnSelCmd":
      if(leftModel == null) break;

      rightAssemblyBrowser.hideUnSelectedNodes();
      myCmiWindow.drawScene();
      break;
    case "LeftBrowserDeselectAllCmd":
      if(leftModel == null) break;

      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      myCmiWindow.drawScene();
      break;
    case "RightBrowserDeselectAllCmd":
      if(rightModel == null) break;

      rightAssemblyBrowser.switchHighlightStateForAll(false);
      myCmiWindow.drawScene();
      break;
    case "LeftBrowserShowAllCmd":
      if(leftModel == null) break;

      leftAssemblyBrowser.switchVisibilityStateForAll(true);
      leftBomBrowser.switchVisibilityStateForAll(true);
      myCmiWindow.drawScene();
      break;
    case "RightBrowserShowAllCmd":
      if(rightModel == null) break;

      rightAssemblyBrowser.switchVisibilityStateForAll(true);
      myCmiWindow.drawScene();
      break;
    case "LeftBrowserInverseSelCmd":
      inverseHighlight('left');
      myCmiWindow.drawScene();
      break;
    case "LeftBrowserGenPosNrsCmd":
      leftBomBrowser.generatePositionNumbers(poi3dConnector.getUserSettings().deltaValPosNr,true);
      poi3dConnector.getLeftDocument().getBomStructureObject().setLocalChangeFlag(true);
      break;
    case "RightBrowserInverseSelCmd":
      inverseHighlight('right');
      myCmiWindow.drawScene();
      break;
    case "AboutPortalCmd":
      showMsgDlg(null,"Copyright: CADMAI Software GmbH<br>Version: " + poi3dConnector.getVersionString());
      break;
    case "MateSelDocsCmd":
      if((leftModel == null)||(rightModel == null)||(isMated == true)||(compareMode == false))
        break;

      var leftComponents = leftAssemblyBrowser.getHighlightedComponents(true);
      var rightComponents = rightAssemblyBrowser.getHighlightedComponents(true);
      var switchModel = false;

      if((leftComponents.length == 0)||(rightComponents.length == 0))
        break;

      var leftOrigin = leftComponents[0].getGlobalOrigin();
      var leftAngle = leftComponents[0].getGlobalEulerAngles();
      var rightOrigin = rightComponents[0].getGlobalOrigin();
      var rightAngle = rightComponents[0].getGlobalEulerAngles();

      deltaMateOrigin = [leftOrigin[0]-rightOrigin[0],leftOrigin[1]-rightOrigin[1],leftOrigin[2]-rightOrigin[2]];
      deltaMateAngle = [leftAngle[0]-rightAngle[0],leftAngle[1]-rightAngle[1],leftAngle[2]-rightAngle[2]];

      lastStartedAnimation = "mateAnimation";
      mateAnimation.clearAnimation();
      mateAnimation.addModelTranslation(rightModel,deltaMateOrigin[0],deltaMateOrigin[1],deltaMateOrigin[2],20);
      mateAnimation.run(1);

      isMated = true;
      break;
    case "ReMateCmd":
      if((rightModel == null)||(isMated == true))
        break;

      lastStartedAnimation = "mateAnimation";
      mateAnimation.clearAnimation(false,true);
      mateAnimation.addModelTranslation(rightModel,deltaMateOrigin[0],deltaMateOrigin[1],deltaMateOrigin[2],20);
      mateAnimation.run(1);
      isMated = true;
      break;
    case "UnMateCmd":
      if((rightModel == null)||(isMated == false))
        break;

      lastStartedAnimation = "unmateAnimation";
      mateAnimation.clearAnimation(false,true);
      mateAnimation.addModelTranslation(rightModel,-deltaMateOrigin[0],-deltaMateOrigin[1],-deltaMateOrigin[2],20);
      mateAnimation.run(1);
      isMated = false;
      break;
    case "SelComDocsCmd":
      if((leftModel == null)||(rightModel == null))
        break;

      var commonDocsLeft = new Array();
      var uniqueDocsLeft = new Array();
      var commonDocsRight = new Array();
      var uniqueDocsRight = new Array();
      getCompareArrays(uniqueDocsLeft,commonDocsLeft,uniqueDocsRight,commonDocsRight);

      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      leftAssemblyBrowser.highlightComponents(commonDocsLeft);
      leftBomBrowser.highlightComponents(commonDocsLeft);

      rightAssemblyBrowser.switchHighlightStateForAll(false);
      rightAssemblyBrowser.highlightComponents(commonDocsRight);
      myCmiWindow.drawScene();
      break;
    case "SelUniqueDocsCmd":
      if((leftModel == null)||(rightModel == null))
        break;

      var commonDocsLeft = new Array();
      var uniqueDocsLeft = new Array();
      var commonDocsRight = new Array();
      var uniqueDocsRight = new Array();
      getCompareArrays(uniqueDocsLeft,commonDocsLeft,uniqueDocsRight,commonDocsRight);

      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      leftAssemblyBrowser.highlightComponents(uniqueDocsLeft);
      leftBomBrowser.highlightComponents(uniqueDocsLeft);

      rightAssemblyBrowser.switchHighlightStateForAll(false);
      rightAssemblyBrowser.highlightComponents(uniqueDocsRight);
      myCmiWindow.drawScene();
      break;
    case "HideAllSelCmd":
      leftAssemblyBrowser.hideSelectedNodes();
      leftBomBrowser.hideSelectedNodes();
      rightAssemblyBrowser.hideSelectedNodes();
      myCmiWindow.drawScene();
    case "DeSelAllDocsCmd":
      leftAssemblyBrowser.switchHighlightStateForAll(false);
      leftBomBrowser.switchHighlightStateForAll(false);
      rightAssemblyBrowser.switchHighlightStateForAll(false);
      currentHighlightedEntity=null;
      myCmiWindow.drawScene();
      break;
    case "ShowAllDocsCmd":
      leftAssemblyBrowser.switchVisibilityStateForAll(true);
      leftBomBrowser.switchVisibilityStateForAll(true);
      rightAssemblyBrowser.switchVisibilityStateForAll(true);
      myCmiWindow.drawScene();
      break;
    case "HandleAnimsCmd":
      showAnimDlg(null);
      break;
    case "CrSphereAnnCmd":
      switchToLeftBrowser(false);
      switchBrowserView('layer');
      if (pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "spherePick";
      setStatusText(poi3dConnector.getStatusText(8));//"select position"
      break;
    case "CrCrcAnnCmd":
      if (pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "crcPick";
      setStatusText(poi3dConnector.getStatusText(8));//"select center point"
      break;
    case "CrPlateAnnCmd":
      if (pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "platePick";
      setStatusText(poi3dConnector.getStatusText(8));//"select center point"
      break;
    case "CrAreaAnnCmd":
      if (pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "areaPick";
      setStatusText(poi3dConnector.getStatusText(3));//"select first position"
      break;
    case "CrInfoPntCmd":
      switchToLeftBrowser(false);
      switchBrowserView('layer');
      if(pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "ipPick";
      setStatusText(poi3dConnector.getStatusText(2));//"select position"
      break;
    case "CrTxtAnnCmd":
      switchToLeftBrowser(false);
      switchBrowserView('layer');
      if(pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "taPick";
      setStatusText(poi3dConnector.getStatusText(3));//"select first position"
      break;
    case "CrLabelAnnCmd":
      switchToLeftBrowser(false);
      switchBrowserView('layer');
      if(pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "labPick";
      setStatusText(poi3dConnector.getStatusText(17));//"select lower left point"
      break;
    case "CrImgAnnCmd":
      switchToLeftBrowser(false);
      switchBrowserView('layer');
      if(pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "tiPick";
      setStatusText(poi3dConnector.getStatusText(3));//"select first position"
      break;
    case "EditAnnCmd":
      {
        let annotations = poi3dConnector.getLeftDocument().getAnnotations();
        if(annotations.length == 0)
          break;
        switchToLeftBrowser(false);
        switchBrowserView('layer');
        switchMouseMode("select");
        interactionMode = "selectToEdit";
        handleSelectionSettings();
        setStatusText(poi3dConnector.getStatusText(5));//"select annotation to edit"
      }
      break;
    case "DelSglAnnCmd":
      {
        let annotations = poi3dConnector.getLeftDocument().getAnnotations();
        if(annotations.length == 0)
          break;
        switchToLeftBrowser(false);
        switchBrowserView('layer');
        switchMouseMode("select");
        interactionMode = "selectToDelete";
        handleSelectionSettings();
        setStatusText(poi3dConnector.getStatusText(6));//"select annotation to delete"
      }
      break;
    case "CreateInstructionCmd":
      switchToLeftBrowser(false);
      showDefInstrDlg(null);
      break;
    case "CreateSensorCmd":
      switchToLeftBrowser(false);
      showDefSnsDlg(null);
      break;
    case "CreateDocAttrCmd":
      switchToLeftBrowser(false);
      let modelTemplates = leftModel.getUsedTemplateModels(true);
      showPropDlg(null,modelTemplates,"doc",null);
      break;
    case "HandleInstructionCmd":
      switchToLeftBrowser(false);
      showHdlInstrDlg(null);
      break;
    case "HandleSensorCmd":
      switchToLeftBrowser(false);
      showHdlSnsDlg(null);
      break;
    case "DelAllViewLocCmd":
      poi3dConnector.getLeftDocument().setViewLocations(new Array());

      var loc = null;
      var locNameArray = new Array();
      var existingLocations = leftModel.getEntitiesByType(["cmiLocatorObject"]);
      for (var i=0; i<existingLocations.length; i++)
      {
        if(existingLocations[i].fromPoi3d != undefined)
          locNameArray.push(existingLocations[i].entityName);
      }

      leftModel.removeEntitiesFromModelByNames(locNameArray);
      if(hdlVlocDlg != null) hdlVlocDlg.initialize();
      break;
    case "DelAllAnnCmd":
      switchToLeftBrowser(false);
      poi3dConnector.getLeftDocument().setAnnotations(new Array());

      var ann = null;
      var annNameArray = new Array();
      var existingAnnotations = leftModel.getEntitiesByType(["cmiSpriteObject","cmiGrepObject","cmiArcObject","cmiLabelObject","cmiTextObject","cmiImageLabelObject"]);
      for (var i=0; i<existingAnnotations.length; i++)
      {
        if(existingAnnotations[i].fromPoi3d != undefined)
          annNameArray.push(existingAnnotations[i].entityName);
      }

      leftModel.removeEntitiesFromModelByNames(annNameArray);
      updatePageBrowser();
      break;
    case "HandleFileAttachmentCmd":
      showHdlFattDlg(null,"std",null);
      break;
    case "UploadFileAttachmentCmd":
      openFileAttachmentFromFile();
      break;
    case "DelAllInstructionsCmd":
      poi3dConnector.getLeftDocument().setInstructions(new Array());
      if(defInstrDlg != null) defInstrDlg.initialize();
      if(hdlInstrDlg != null) hdlInstrDlg.initialize();
      break;
    case "DelAllSensorsCmd":
      poi3dConnector.getLeftDocument().setSensors(new Array());
      if(defSnsDlg != null) defSnsDlg.initialize();
      if(hdlSnsDlg != null) hdlSnsDlg.initialize();
      updatePageBrowser();
      break;
    case "DelAllDocAttrCmd":
      poi3dConnector.getLeftDocument().setDocAttributes(new Array());
      if(propDlg != null) propDlg.initialize(null);
      break;
    case "SaveInstructionsCmd":
      if(leftModel != null) poi3dConnector.saveInstructionsToStorage(leftModel.getModelName());
      break;
    case "SaveSensorsCmd":
      if(leftModel != null) poi3dConnector.saveSensorsToStorage(leftModel.getModelName());
      break;
    case "SaveAnnCmd":
      if(leftModel != null) poi3dConnector.saveAnnotationsToStorage(leftModel.getModelName());
      break;
    case "SaveViewLocCmd":
      if(leftModel != null) poi3dConnector.saveLocationsToStorage(leftModel.getModelName());
      break;
    case "SaveMaterialDefsCmd":
      if(leftModel != null) poi3dConnector.saveMaterialSetsToStorage(leftModel.getModelName());
      break;
    case "SaveDocAttrCmd":
      if(leftModel != null) poi3dConnector.saveDocAttributesToStorage(leftModel.getModelName());
      break;
    case "LockAnnCmd":
      poi3dConnector.lockAttachment("DocumentAnnotations");
      break;
    case "LockInstructionsCmd":
      poi3dConnector.lockAttachment("DocumentInstructions");
      break;
    case "LockSensorsCmd":
      poi3dConnector.lockAttachment("DocumentSensors");
      break;
    case "LockMaterialDefsCmd":
      poi3dConnector.lockAttachment("DocumentMaterialSets");
      break;
    case "LockFileAttachmentsCmd":
      poi3dConnector.lockAttachment("DocumentFileAttachments");
      break;
    case "LockBomsCmd":
      poi3dConnector.lockAttachment("BomStructures");
      break;
    case "LockViewLocCmd":
      poi3dConnector.lockAttachment("DocumentLocations");
      break;
    case "LockDocAttrCmd":
      poi3dConnector.lockAttachment("DocumentAttributes");
      break;
    case "UnlockAnnCmd":
      poi3dConnector.unlockAttachment("DocumentAnnotations");
      break;
    case "UnlockInstructionsCmd":
      poi3dConnector.unlockAttachment("DocumentInstructions");
      break;
    case "UnlockSensorsCmd":
      poi3dConnector.unlockAttachment("DocumentSensors");
      break;
    case "UnlockMaterialDefsCmd":
      poi3dConnector.unlockAttachment("DocumentMaterialSets");
      break;
    case "UnlockFileAttachmentsCmd":
      poi3dConnector.unlockAttachment("DocumentFileAttachments");
      break;
    case "UnlockBomsCmd":
      poi3dConnector.unlockAttachment("BomStructures");
      break;
    case "UnlockViewLocCmd":
      poi3dConnector.unlockAttachment("DocumentLocations");
      break;
    case "UnlockDocAttrCmd":
      poi3dConnector.unlockAttachment("DocumentAttributes");
      break;
    case "LoadAnnCmd":
      if(leftModel != null) poi3dConnector.loadAnnotations(leftModel.getModelName());
      break;
    case "LoadViewLocCmd":
      if(leftModel != null) poi3dConnector.loadLocations(leftModel.getModelName());
      break;
    case "LoadInstructionsCmd":
      if(leftModel != null) poi3dConnector.loadInstructions(leftModel.getModelName())
      break;
    case "LoadSensorsCmd":
      if(leftModel != null) poi3dConnector.loadSensors(leftModel.getModelName())
      break;
    case "LoadMaterialDefsCmd":
      if(leftModel != null)
      {
        if(currentMaterialSetRef != null)
          currentMaterialSetRef.deleteFromEntities(leftModel);

        currentMaterialSetRef = null;
        currentMaterialSetCopy = null;

        myCmiWindow.drawScene();
        poi3dConnector.loadMaterialSets(leftModel.getModelName());
      }
      break;
    case "LoadFileAttachmentsCmd":
      poi3dConnector.loadDocumentFileAttachments();
      break
    case "LoadDocAttrCmd":
      if(leftModel != null) poi3dConnector.loadDocAttributes(leftModel.getModelName())
      break;
    case "DelAllFileAttachmentsCmd":
      poi3dConnector.getLeftDocument().setFileAttachments(new Array());
      if(hdlFattDlg != null) hdlFattDlg.initialize();
      break;
    case "SaveFileAttachmentsCmd":
      poi3dConnector.saveFileAttachmentsToStorage();
      break;
    case "LoadBomsCmd":
      if(leftModel != null) poi3dConnector.loadBomStructures(leftModel.getModelName());
      break;
    case "CreateBomCmd":
      if(leftModel == null)
        showMsgDlg(null,poi3dConnector.getMessage(5));//"No model loaded"
      else
      {
        switchToLeftBrowser(false);
        showDefBomDlg(null);
      }
      break;
    case "DelAllBomsCmd":
      poi3dConnector.getLeftDocument().setBomStructures(new Array());
      updateBomBrowserSelection();
      leftBomBrowser.clearContent();
      poi3dConnector.getLeftDocument().getBomStructureObject().setLocalChangeFlag(true);
      resizeWindow(false);
      if(defBomDlg != null) defBomDlg.initialize();
      break;
    case "SaveBomsCmd":
      if(leftModel != null) poi3dConnector.saveBomStructuresToStorage(leftModel.getModelName());
      break;
    case "SaveCurrentViewerPositionCmd":
      if(viewingMode == "VR+")
      {
        let viewLocations = poi3dConnector.getLeftDocument().getViewLocations();
        showDefVlocDlg(null);
        if(viewLocations.length > 0)
          myCmiWindow.showModelLocators = true;
      }
      break;
    case "HandleViewerLocCmd":
      showHdlVlocDlg(null);
      break;
    case "CalibrateMeasurementCmd":
      if (pickPoints.length > 0)
      {
        leftModel.removeLocatorsFromModelByNames(pickPoints);
        pickPoints = new Array();
      }
      switchMouseMode("pick");
      interactionMode = "calPick";
      setStatusText(poi3dConnector.getStatusText(3));//"select first position"
      break;
    case "ShPrimModStructCmd":
      showLeftTable(true);
      break;
    case "ShCmpModStructCmd":
      showRightTable(true);
      break;
    case "RevCmpCol":
      reverseCompareColor = !reverseCompareColor;
      switchCompareMode(document.getElementById("gCompareMode"));
      break;
    case "SaveModCmd":
      showModSaveDlg(null);
      break;
    case "Poi3dPortalLogInCmd":
      poi3dConnector.logIn();
      break;
    case "Poi3dPortalLogOffCmd":
      poi3dConnector.logOff();
      document.getElementById("loginDlg_UserNameVal").value = "";
      document.getElementById("loginDlg_PwdVal").value = "";
      break;
    case "AboutPortalCmd":
      showMsgDlg(null,"Copyright: CADMAI Software GmbH<br>Version: " + poi3dConnector.getVersionString());
      break;
    case "AssignMaterial":
      showMatDlg(null);
      break;
    case "DeactivateMaterial":
      if(currentMaterialSetRef!= null)
      {
        currentMaterialSetRef.deleteFromEntities(leftModel);
        currentMaterialSetRef = null;
        currentMaterialSetCopy = null;
        myCmiWindow.drawScene();
      }
      break;
    case "CreateMaterialDefsCmd":
      showDefMtlSetDlg(null);
      break;
    case "DelAllMaterialDefsCmd":
      if(currentMaterialSetRef != null)
        currentMaterialSetRef.deleteFromEntities(leftModel);

      poi3dConnector.getLeftDocument().setMaterialSets(new Array());
      currentMaterialSetRef = null;
      currentMaterialSetCopy = null;
      updateMaterialSetSelection([]);
      if(defMtlSetDlg != null) defMtlSetDlg.initialize();

      myCmiWindow.drawScene();
      break;
    case "SwitchMaterialSet":
    case "SwitchMaterialSetAr":
    case "SwitchMaterialSetVr":
      let materialSets = poi3dConnector.getLeftDocument().getMaterialSets();
      if(materialSets.length > 0)
      {
        let MainToolbarMaterialSelection = null;
        let matNr = 0;

        if(currentCommand == "SwitchMaterialSetVr")
          MainToolbarMaterialSelection = document.getElementById("VrMatSetSelection");
        else if(currentCommand == "SwitchMaterialSetAr")
          MainToolbarMaterialSelection = document.getElementById("ArMatSetSelection");
        else
          MainToolbarMaterialSelection = document.getElementById("MatSetSelection");

        matNr = MainToolbarMaterialSelection.selectedIndex;

        if((matNr == 0)&&(currentMaterialSetRef != null)) //see defMtlSetDlg.deactivateMatSet
        {
          currentMaterialSetRef.deleteFromEntities(leftModel);
          currentMaterialSetRef = null;
          currentMaterialSetCopy = null;
          document.getElementById("defMtlSetDlg_ActSetNameVal").value = "";
          myCmiWindow.drawScene();
        }
        else //see defMtlSetDlg.activateMatSet
        {
          if(currentMaterialSetRef != null)
            currentMaterialSetRef.deleteFromEntities(leftModel);

          currentMaterialSetRef = materialSets[matNr-1];
          currentMaterialSetCopy = currentMaterialSetRef.createCopy(true);
          currentMaterialSetRef.applyToEntities(leftModel);

          myCmiWindow.drawScene();
        }
      }
      break;
    case "ShChatCmd":
      showAiChatDlg(null);
      break;
    case "ShCommDlgCmd":
      showCommDlg(null);
      break;
    case "ShowNotDlg":
      showNotificationTestDialog();
      break;
    default:
      showMsgDlg(null,poi3dConnector.getMessage(0));//"Not yet implemented"
      break;
  }
}
function switchCutMode(radioButt)
{
  if (radioButt.checked)
  {
    showPlCutDlg(null);
  }
  else
  {
    myCmiWindow.clipPlaneActive = false;
    myCmiWindow.drawScene();
  }
}
function switchExplodeMode(radioButt)
{
  var currModel = currentModel;

  if (radioButt.checked)
  {
    var modelCenter = currentModel.getModelCenterPoint();

    if(currentModel == leftModel)
    {
      if(rightModel != null)
      {
        myCmiWindow.setCmiModel(rightModel);

        modelCenter = rightModel.getModelCenterPoint();
        lastStartedAnimation = "explosionAnimationRight";
        explosionAnimationRight.clearAnimation();
        explosionAnimationRight.setExplosionCenter(modelCenter[0],modelCenter[1],modelCenter[2]);
        explosionAnimationRight.addExplosionView("stretch",poi3dConnector.getUserSettings().explosionFactor, 10);
        explosionAnimationRight.run(1);

        myCmiWindow.setCmiModel(leftModel);
      }

      lastStartedAnimation = "explosionAnimationLeft";
      explosionAnimationLeft.clearAnimation();
      explosionAnimationLeft.setExplosionCenter(modelCenter[0],modelCenter[1],modelCenter[2]);
      explosionAnimationLeft.addExplosionView("stretch",poi3dConnector.getUserSettings().explosionFactor, 10);
      explosionAnimationLeft.run(1);
    }//if(currentModel == leftModel)
    else if(currentModel == rightModel)
    {
      if(leftModel != null)
      {
        myCmiWindow.setCmiModel(leftModel);

        modelCenter = leftModel.getModelCenterPoint();
        lastStartedAnimation = "explosionAnimationLeft";
        explosionAnimationLeft.clearAnimation();
        explosionAnimationLeft.setExplosionCenter(modelCenter[0],modelCenter[1],modelCenter[2]);
        explosionAnimationLeft.addExplosionView("stretch",poi3dConnector.getUserSettings().explosionFactor, 10);
        explosionAnimationLeft.run(1);

        myCmiWindow.setCmiModel(rightModel);
      }

      lastStartedAnimation = "explosionAnimationRight";
      explosionAnimationRight.clearAnimation();
      explosionAnimationRight.setExplosionCenter(modelCenter[0],modelCenter[1],modelCenter[2]);
      explosionAnimationRight.addExplosionView("stretch",poi3dConnector.getUserSettings().explosionFactor, 10);
      explosionAnimationRight.run(1);

    }//else if(currentModel == rightModel)
  }//if (radioButt.checked)
  else
  {
    if(currentModel == leftModel)
    {
      if(rightModel != null)
      {
        myCmiWindow.setCmiModel(rightModel);
        explosionAnimationRight.resetEntites(true, false);
        myCmiWindow.setCmiModel(leftModel);
      }

      explosionAnimationLeft.resetEntites(true, false);
    }//if(currentModel == leftModel)
    else if(currentModel == rightModel)
    {
      if(leftModel != null)
      {
        myCmiWindow.setCmiModel(leftModel);
        explosionAnimationLeft.resetEntites(true, false);
        myCmiWindow.setCmiModel(rightModel);
      }

      explosionAnimationRight.resetEntites(true, false);
    }//else if(currentModel == rightModel)
  }////if (radioButt.checked) else
};
function switchCompareMode(radioButt)
{
  if((leftModel == null)||(rightModel == null))
    return;

  if(radioButt.checked)
  {
    switchMouseMode("rotate");
    interactionMode = "";
    document.getElementById('gMouseRotate').checked = true;

    if(reverseCompareColor == true)
    {
      if(compareMode == true)
      {
        myCmiWindow.setCmiModel(rightModel);
        currentModel=rightModel;
        myCmiWindow.activateModelCompare(leftModel);
        myCmiWindow.drawScene();
      }
      else
      {
        switchToRightBrowser(true);
        myCmiWindow.activateModelCompare(leftModel);
      }
    }
    else//if(reverseCompareColor == true)
    {
      if(compareMode == true)
      {
        myCmiWindow.setCmiModel(leftModel);
        currentModel=leftModel;
        myCmiWindow.activateModelCompare(rightModel);
        myCmiWindow.drawScene();
      }
      else
      {
        switchToLeftBrowser(true);
        myCmiWindow.activateModelCompare(rightModel);
      }
    }//if(reverseCompareColor == true) else

    document.getElementById("leftBrowserHeaderTableRow1").className = "inActiveBrowser iconBrowserBar";
    document.getElementById("lbrActivateBut").className = "inActiveBrowser iconBrowserBar";
    document.getElementById("leftBrowserHeaderTableRow1").className = "inActiveBrowser iconBrowserBar";
    document.getElementById("rbrActivateBut").className = "inActiveBrowser iconBrowserBar";

    compareMode = true;
  }
  else//if(radioButt.checked)
  {
    myCmiWindow.activateModelCompare(null);
    compareMode = false;
    switchToLeftBrowser(false);
  }

  myCmiWindow.drawScene();
}

function getCompareArrays(uniqueDocsLeft,commonDocsLeft,uniqueDocsRight,commonDocsRight)
{
  if((leftModel == null)||(rightModel == null))
    return;

  var leftComponents = leftAssemblyBrowser.getComponentArray();
  var rightComponents = rightAssemblyBrowser.getComponentArray();
  var leftTemplateName = "";
  var rightTemplateName = "";
  var hit = false;
  var handledTemplateNames = new Array();
  var handledTemplateNamesWithHit = new Array();

  for ( var i =0; i<leftComponents.length; i++)
  {
    hit = false;
    //leftTemplateName = leftComponents[i].getModelTemplateName();
    leftTemplateName = leftComponents[i].getModel().getModelName();

    if((leftTemplateName != "")&&(handledTemplateNames.includes(leftTemplateName) == false))
    {
      for ( var k =0; k<rightComponents.length; k++)
      {
        //rightTemplateName = rightComponents[k].getModelTemplateName();
        rightTemplateName = rightComponents[k].getModel().getModelName();
        if(leftTemplateName == rightTemplateName)
        {
          hit = true;
          commonDocsRight.push(rightComponents[k]);
        }
      }//for ( var k =0; k<rightComponents.length; k++)

      handledTemplateNames.push(leftTemplateName);

      if(hit == true)
      {
        commonDocsLeft.push(leftComponents[i]);
        handledTemplateNamesWithHit.push(leftTemplateName);
      }
      else
        uniqueDocsLeft.push(leftComponents[i]);

    }//if((leftTemplateName != "")&&(handledTemplateNames.includes(leftTemplateName) == false))
    else if(handledTemplateNamesWithHit.includes(leftTemplateName) == true)
    {
      commonDocsLeft.push(leftComponents[i]);
    }
  }//for ( var i =0; i<leftComponents.length; i++)

  for ( var k =0; k<rightComponents.length; k++)
  {
    rightTemplateName = rightComponents[k].getModel().getModelName();
    if((rightTemplateName != "")&&(handledTemplateNames.includes(rightTemplateName) == false))
    {
      uniqueDocsRight.push(rightComponents[k]);
    }
  }//for ( var k =0; k<rightComponents.length; k++)
}
function setStatusText(newText,anim)//called by windows client
{
  statusText.style.opacity = 1;
  statusText.classList.remove("pulsate");

  statusText.innerHTML = newText;
  if(anim)
  {
    let effect = null;
    switch(anim)
    {
      case "fadeOut":
        effect = setInterval(function ()
        {
          if (!statusText.style.opacity) {statusText.style.opacity = 1;}
          if (statusText.style.opacity > 0) {statusText.style.opacity -= 0.02;}
          else {clearInterval(effect);}
        }, 100);
        break;
      case "pulse":
        statusText.classList.add("pulsate");
        break;
    }
  }//if(anim)
};//function setStatusText
function switchHideInvisMode(chkBox,browserNameToUse)
{
  var browserToUse = null;
  var modelToUse = null;
  var isBomView = document.getElementById("bomView").checked;

  if(browserNameToUse == "right")
  {
    if(rightModel == null)
      return;
    browserToUse = rightAssemblyBrowser;
    modelToUse = rightModel;
  }
  else
  {
    if(leftModel == null)
      return;
    modelToUse = leftModel;

    if(isBomView)
      browserToUse = leftBomBrowser;
    else
      browserToUse = leftAssemblyBrowser;
  }

  browserToUse.setShowInvisibleComponentsFlag(!chkBox.checked);
  browserToUse.rebuildTreeViewTable();
}
function inverseHighlight(browserNameToUse)
{
  var browserToUse = null;
  var components = null;

  if(browserNameToUse == "right")
  {
    if(rightModel == null)
      return;

    components = rightAssemblyBrowser.getUnHighlightedComponents();
    rightAssemblyBrowser.switchHighlightStateForAll(false);
    rightAssemblyBrowser.highlightComponents(components);

  }
  else
  {
    if(leftModel == null)
      return;

    components = leftAssemblyBrowser.getUnHighlightedComponents();
    leftAssemblyBrowser.switchHighlightStateForAll(false);
    leftBomBrowser.switchHighlightStateForAll(false);
    leftAssemblyBrowser.highlightComponents(components);
    leftBomBrowser.highlightComponents(components);
  }
}
function searchAll(browserNameToUse)
{
  var browserToUse = null;
  var components = null;
  var searchString = "";
  var caseSensitive = false;

  if(browserNameToUse == "right")
  {
    if(rightModel == null)
      return;

    searchString = document.getElementById("rbrSearchVal").value;
    if(searchString.length == 0) return;

    caseSensitive = document.getElementById("rightCaseSensitiveSwitch").checked;

    components = rightAssemblyBrowser.searchComponents(searchString,caseSensitive);
    rightAssemblyBrowser.switchHighlightStateForAll(false);
    rightAssemblyBrowser.highlightComponents(components);
  }
  else
  {
    if(leftModel == null)
      return;

    searchString = document.getElementById("lbrSearchVal").value;
    if(searchString.length == 0) return;

    caseSensitive = document.getElementById("leftCaseSensitiveSwitch").checked;

    components = leftAssemblyBrowser.searchComponents(searchString,caseSensitive);
    leftAssemblyBrowser.switchHighlightStateForAll(false);
    leftAssemblyBrowser.highlightComponents(components);

    components = leftBomBrowser.searchComponents(searchString,caseSensitive);
    leftBomBrowser.switchHighlightStateForAll(false);
    leftBomBrowser.highlightComponents(components);
  }
  myCmiWindow.drawScene();
}

//Menu functions
function openMulti(mnuId)
{
  let mnu = document.getElementById(mnuId);
  let allMnus = document.getElementsByClassName("selWrp");

  for (let i = 0; i < allMnus.length; i++)
  {
    if(allMnus[i] != mnu)
    {
      allMnus[i].style.opacity = "0";
      allMnus[i].style.pointerEvents = "none";
    }
  }

  if (mnu.style.pointerEvents == "all")
  {
    mnu.style.opacity = "0";
    mnu.style.pointerEvents = "none";
  }
  else
  {
    mnu.style.opacity = "1";
    mnu.style.pointerEvents = "all";
  }
  return;
}
function closeAllMenus()
{
  let allMnus = document.getElementsByClassName("selWrp");

  for (let i = 0; i < allMnus.length; i++)
  {
    allMnus[i].style.opacity = "0";
    allMnus[i].style.pointerEvents = "none";
  }
}
function handleMuMnuCmd(mainMnuId,mnuCmd)
{
  openMulti(mainMnuId);
  handleCommand(mnuCmd);
}
function openMnuUrl(cmdObject,mnuUrl)
{
  parentId = cmdObject.parentNode.parentNode.id;
  openMulti(parentId);
  window.open(mnuUrl,'_blank')
}
function hdlMnuCmd(cmdObject)
{
  parentId = cmdObject.parentNode.parentNode.id;
  commandString = cmdObject.id;
  openMulti(parentId);

  if(commandString.includes("MmCtx"))
    handleMmCtxCommand(commandString);
  else if(commandString.includes("CmpCtx"))
    handleCmpCtxCommand(commandString);
  else if(commandString.includes("AnnCtx"))
    handleAnnCtxCommand(commandString);
  else if(commandString.includes("BomCtx"))
    handleBomCtxCommand(commandString);
  else if(commandString.includes("ChatCtx"))
    handleChatCtxCommand(commandString);
  else if(commandString.includes("DoBoPropCtx"))
    handleBomPropCtxCommand(commandString);
  else if(commandString.includes("LAsmBrCtx"))
    handleLeftBrowserCtxCommand(commandString);
  else
    handleCommand(commandString);
}
function handleMuHlpMnuCmd(mainMnuId,fName)
{
  let helpDir =  portalSettings.helpDir;

  openMulti(mainMnuId);
  if(fName.includes("mp4"))
    showVidHlpDlg(null,helpDir + "/" + fName);
  else
  {
    if(poi3dConnector.getCurrentLanguage() == "de")
      showVidHlpDlg(null,helpDir + "/" + fName +"De.mp4");
    else
      showVidHlpDlg(null,helpDir + "/" + fName +"En.mp4");
  }
}
function hdlVidCmd(cmdObject,fName)
{
  let helpDir =  portalSettings.helpDir;

  parentId = cmdObject.parentNode.parentNode.id;
  openMulti(parentId);
  if(fName.includes("mp4"))
    showVidHlpDlg(null,helpDir + "/" + fName);
  else
  {
    if(poi3dConnector.getCurrentLanguage() == "de")
      showVidHlpDlg(null,helpDir + "/" + fName +"De.mp4");
    else
      showVidHlpDlg(null,helpDir + "/" + fName +"En.mp4");
  }
}
function switchMenu(currMnuId,nextMnuId)
{
  let currMnu = document.getElementById(currMnuId);
  let nextMnu = document.getElementById(nextMnuId);

  currMnu.style.transform = "translateX(-100%)";
  currMnu.style.clipPath = "polygon(100% 0, 100% 0, 100% 100%, 100% 100%)";
  nextMnu.style.transform = "translateX(0)";
  nextMnu.style.clipPath = "polygon(0 0, 100% 0, 100% 100%, 0% 100%)";
}
