var swiper = null;
var documentArray = new Array();
var currentDocument = null;
var myCmiWindow;
var statusText;
var updateTimer = 0;

var multiPageDocument = null;
var multiPageTifArray = null;
var currentPageNr = 1;
var pageCount = 1;
var currentImageTexture = null;
var currentAnnotationName = "";

function loadModules()
{
  let moduleBasePackage = new Array();
  moduleBasePackage.push({mLoc:"CmiScripts/CmiWindowDefinition.js",loadFct:null});
  moduleBasePackage.push({mLoc:"CmiScripts/CmiObjectDefinitions.js",loadFct:null});
  moduleBasePackage.push({mLoc:"CmiScripts/CmiShaderDefinitions.js",loadFct:null});
  moduleBasePackage.push({mLoc:"CmiScripts/CmiHelperFunctions.js",loadFct:null});
  moduleBasePackage.push({mLoc:"CmiScripts/CmiShaderSources.js",loadFct:null});
  moduleBasePackage.push({mLoc:"CmiScripts/CmiModelDefinition.js",loadFct:null});
  moduleBasePackage.push({mLoc:"CmiScripts/ThirdPartyHelpers.js",loadFct:null});

  moduleBasePackage.push({mLoc:"Poi3d/3rdParty/ImageGallery/swiper-bundle.min.js",loadFct:null});
  moduleBasePackage.push({mLoc:"Poi3d/3rdParty/Zip/jszip-utils.min.js",loadFct:null});
  moduleBasePackage.push({mLoc:"Poi3d/3rdParty/Zip/jszip.min.js",loadFct:null});
  moduleBasePackage.push({mLoc:"Poi3d/3rdParty/pdfjs/build/pdf.mjs",loadFct:function()
  {
    var { pdfjsLib } = globalThis;
    pdfjsLib.GlobalWorkerOptions.workerSrc = 'Poi3d/3rdParty/pdfjs/build/pdf.worker.mjs';
  }});
  moduleBasePackage.push({mLoc:"Poi3d/3rdParty/Tiff/UTIF.js",loadFct:null});

  let baseLibLoader = new Poi3dModuleLoader(moduleBasePackage);
  baseLibLoader.loadParallel = true;
  baseLibLoader.afterLoadFunction = function()
  {
    statusText = document.getElementById("statusText");

    storageConnector.registerCallback("categoryListLoaded",onCategoryListLoaded);
    storageConnector.registerCallback("categoriesLoaded",onCategoriesLoaded);
    storageConnector.registerCallback("documentCollectionLoaded",onDocumentCollectionLoaded);
    storageConnector.registerCallback("fileAttachmentsLoaded",onFileAttachmentsLoaded);
    storageConnector.registerCallback("updateState",setStateText);
    storageConnector.clearBrowserDb();

    if(storageConnector.libraries.length > 0)
    {
      let connectorLibLoader = new Poi3dModuleLoader(storageConnector.libraries);
      connectorLibLoader.loadParallel = true;
      connectorLibLoader.afterLoadFunction = function()
      {
        storageConnector.init();
        initUi();
      };
      connectorLibLoader.loadModules();
    }
    else
    {
      storageConnector.init();
      initUi();
    }
  };
  baseLibLoader.loadModules();
};

function initUi()
{
  swiper = new Swiper(".poi3dSwiper",
  {
    effect: "coverflow",
    grabCursor: true,
    centeredSlides: true,
    slidesPerView: "auto",
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev",
    },
    loop: false,
    pagination: {
      el: ".swiper-pagination",
      type: "fraction",
    },
    coverflowEffect: {
      rotate: 50,
      stretch: 0,
      depth: 100,
      modifier: 1,
      slideShadows: false,
    },
  });

  swiper.on('realIndexChange', function (theEvent)
  {
    clearTimeout(updateTimer);
    updateTimer = setTimeout(function(realIndex)
    {
      currentDocument = documentArray[realIndex];
      updateDocumentInformation();
    }, 800, theEvent.realIndex);
  });

  let storageUrl = document.getElementById("storageUrl");
  if(storageUrl != undefined) storageUrl.value = storageConnector.configuration.storageAddress;

  canBeUsed("loginBut",true);

  canBeUsed("docDescriptionLab",false);
  canBeUsed("docAttributesLab",false);
  canBeUsed("docFileAttachmentsLab",false);
  canBeUsed("docPreviewLab",false);

  canBeUsed("docDescriptionTab",false);
  canBeUsed("docAttributesTab",false);
  canBeUsed("docFileAttachmentsTab",false);
  canBeUsed("docPreviewTab",false);

  canBeUsed("openInPortalButt",false);

  //Preview Window
  myCmiWindow = new CmiWindow("previewCanvas");
  if(myCmiWindow.isUsable)
  {
    if(myCmiWindow.checkWebGlUsage() < 0)
    {
      setStateText(myCmiWindow.getLastError().message,true);
      return;
    }

    var bgColor3D = getComputedStyle(document.querySelector('body')).getPropertyValue('--MainBgCol').match(/\d+/g).map(Number);
    myCmiWindow.setBgColorRGB(bgColor3D[0],bgColor3D[1],bgColor3D[2]);
    myCmiWindow.setBgText("Preview");
    myCmiWindow.colGradient =false;
    myCmiWindow.useMinimumStartupImageLoad = true;

    if(myCmiWindow.initWebGlWindow() < 0)
    {
      setStateText(myCmiWindow.getLastError().message,true);
      return;
    }

    myCmiWindow.setNotificationHandler(onCmiNotification);
    myCmiWindow.handleArrowKeys = false;
    myCmiWindow.switchToOrtho(true);
    myCmiWindow.setMouseModeToRotation();
    myCmiWindow.currentDocFilName = "";

    resizeDocumentInfoArea();
  }

  storageConnector.setCmiWindow(myCmiWindow);
};//initUi

function getElementHight(ent)
{
  let height = parseInt(getComputedStyle(ent).getPropertyValue("height"));
  height += parseInt(getComputedStyle(ent).getPropertyValue('margin-top'));
  height += parseInt(getComputedStyle(ent).getPropertyValue('margin-bottom'));
  height += parseInt(getComputedStyle(ent).getPropertyValue('padding-top'));
  height += parseInt(getComputedStyle(ent).getPropertyValue('padding-bottom'));

  return height;
}
//Preview functions --------------------------------
function resizeDocumentInfoArea ()
{

  //compute document info area
  let headerArea = document.getElementById("headerArea");
  let swiperArea = document.getElementById("swiperArea");
  let documentTabArea = document.getElementById("documentTabArea");
  let documentInfoPages = document.getElementById("documentInfoPages");
  let previewCanvas = document.getElementById("previewCanvas");

  let hdrAreaHeight = getElementHight(headerArea);
  let swiperAreaHeight = getElementHight(swiperArea);

  let docInfoHeight = window.innerHeight - hdrAreaHeight - swiperAreaHeight - 5;
  documentInfoArea.style.height = docInfoHeight + "px";

  let documentInfoPagesHeight = docInfoHeight - getElementHight(documentTabArea) - 5;
  documentInfoPages.style.height = documentInfoPagesHeight + "px";

  if((myCmiWindow)&&(myCmiWindow.isUsable))
  {
    var webglCanvas = myCmiWindow.getCanvas();
    myCmiWindow.resizeContext(previewCanvas.clientWidth,previewCanvas.clientHeight);
  }

  return;
};//resizeDocumentInfoArea

function updatePreviewMouseBehavior(env)
{
  if(env == "2d")
  {
    myCmiWindow.setMouseModeToMovement();
    document.getElementById("gMouseMove").checked = true;
    setDisplayStyle("gMouseRotateLab","none");
    if(pageCount > 1)
      setDisplayStyle("tbPageArea","");
    else
      setDisplayStyle("tbPageArea","none");
  }
  else
  {
    setDisplayStyle("gMouseRotateLab","");
    setDisplayStyle("tbPageArea","none");
    myCmiWindow.setMouseModeToRotation();
    document.getElementById("gMouseRotate").checked = true;
  }
};//updatePreviewMouseBehavior

function loadCurrentDocumentIntoPreview(reloadFromSrc)
{
  if(currentDocument == null)
    return;

  let skipDbSearch = false;
  if(reloadFromSrc)
  {
    myCmiWindow.resetCmiModel();
    myCmiWindow.currentDocFilName = "";
    skipDbSearch = true;
  }

  let docFileName = currentDocument.getFileName();
  let docUrl = currentDocument.getPreviewUrl();
  let docData = currentDocument.getDocData();
  let docType = currentDocument.getDocType();

  if(docFileName != myCmiWindow.currentDocFilName)
  {
    myCmiWindow.currentDocFilName = docFileName;

    myCmiWindow.resetCmiModel();
    myCmiWindow.zoomAll();
    setStateText("loading document");

    //check if it is already buffered
    storageConnector.readDocumentFromBrowserDb(currentDocument.getDocId(),skipDbSearch).then
    (
      function(value)
      {
        if(value == null) //read from URL
        {
          currentDocument.setDbFlag(false);
          storageConnector.loadPreview(currentDocument).then
          (
            function(result)
            {
              if(result == 0)
              {
                docData = currentDocument.getDocData();
                docType = currentDocument.getDocType();//ToDo can be overwritten in loadPreview
                switch(docType)
                {
                  case "wpm":
                    if(docData != null)
                      myCmiWindow.openModelFromJsonString(docData,false,false);
                    else
                      myCmiWindow.loadModelFromUrl(docUrl,false,false);
                    updatePreviewMouseBehavior("3d");
                    break;
                  case "zip":
                    if(docData != null)
                      load3dWpmZipModel(docData);
                    else
                      load3dWpmZipModel(docUrl);
                    break;
                  case "jpg":
                  case "jpeg":
                  case "bmp":
                  case "gif":
                  case "svg":
                  case "png":
                  case "tif":
                  case "tiff":
                  case "pdf":
                    if(docData != null)
                      load2dDocument(docType,docData);
                    else
                      load2dDocument(docType,docUrl);
                    break;
                  default:
                    setStateText("Unsupported format",true);
                    break;
                }
              }//if(result == 0)
              else
              {
                setStateText("Error loading preview",true);
              }
            }//function(result)
          );//storageConnector.loadPreview(currentDocument).then
        }
        else //read from db
        {
          currentDocument.setDbFlag(true);
          switch(value.docType)
          {
            case "wpm":
              myCmiWindow.openModelFromJsonString(value.docData,false,false);
              updatePreviewMouseBehavior("3d");
              break;
            case "jpg":
            case "jpeg":
            case "bmp":
            case "gif":
            case "svg":
            case "png":
            case "tif":
            case "tiff":
            case "pdf":
              load2dDocument(docType,value.docData);
              break;
            default:
              setStateText("Unsupported format",true);
              break;
          }
        }
      }//function(value)
    );
  }//if(docUrl != currModelUrl)
};//loadCurrentDocumentIntoPreview

function load2dDocument(docType,docUrl)
{
  if(docType == "tif")
  {
    if(currentDocument.getDbFlag() == true)
    {
      multiPageDocument = docUrl
      multiPageTifArray = UTIF.decode(docUrl);
      pageCount = multiPageTifArray.length;
      currentPageNr = 1;

      currentDocument.setDocData(multiPageDocument);
      document.getElementById("tbPrevPageCnt").innerHTML = "1/"+pageCount;
      showCurrentPage();
    }
    else
    {
      function tiffLoaded(e)
      {
        var uri = null;

        multiPageDocument = e.target.response;
        multiPageTifArray = UTIF.decode(e.target.response);
        pageCount = multiPageTifArray.length;
        currentPageNr = 1;

        currentDocument.setDocData(multiPageDocument);

        storageConnector.saveDocumentToBrowserDb(currentDocument).then
        (
          function(value)
          {
            currentDocument.setDocData(null);
          }
        );

        document.getElementById("tbPrevPageCnt").innerHTML = "1/"+pageCount;
        showCurrentPage();
      }//tiffLoaded

      var xhr = new XMLHttpRequest();
      xhr.open("GET", docUrl);
      xhr.responseType = "arraybuffer";
      xhr.onload = tiffLoaded;
      xhr.send();
    }//if(currentDocument.getDbFlag() == false)
  }//if(docType == "tif")
  else if(docType == "pdf")
  {
    var loadingTask = pdfjsLib.getDocument(docUrl);
    loadingTask.promise.then(function(pdfDoc)
    {
      multiPageDocument = pdfDoc
      pageCount = pdfDoc.numPages;
      currentPageNr = 1;

      document.getElementById("tbPrevPageCnt").innerHTML = "1/"+pageCount;
      showCurrentPage();

      if(currentDocument.getDbFlag() == false)
      {
        pdfDoc.getData().then
        (
          function(value)
          {
            currentDocument.setDocData(value);

            storageConnector.saveDocumentToBrowserDb(currentDocument).then
            (
              function(value)
              {
                currentDocument.setDocData(null);
              }
            );
          }
        );
      }//if(currentDocument.getDbFlag() == false)
    }, function (reason)
    {
      setStateText("Error loading pdf document",true);
    });//loadingTask.promise.then
  }//else if(docType == "pdf")
  else
  {
    multiPageDocument = null;
    multiPageTifArray = null;
    pageCount = 1;
    currentPageNr = 1;
    document.getElementById("tbPrevPageCnt").innerHTML = "1/"+pageCount;

    addBaseImageToModel(docUrl).then
    (
      function(value)
      {
        if(value == null)
        {
          setStateText("Error loading image",true);
          return;
        }

        if(currentDocument.getDbFlag() == false)
        {
          var canvas = document.createElement('canvas');
          var ctx = canvas.getContext('2d');
          canvas.height = value.naturalHeight;
          canvas.width = value.naturalWidth;
          ctx.drawImage(value, 0, 0);
          currentDocument.setDocData(canvas.toDataURL("image/" + currentDocument.getDocType()));

          storageConnector.saveDocumentToBrowserDb(currentDocument).then
          (
            function(value)
            {
              currentDocument.setDocData(null);
            }
          );
        }//if(currentDocument.getDbFlag() == false)
      }//function(value)
    );//addBaseImageToModel
  }//if(docType == "tif") else
}

async function addBaseImageToModel(docUrl)
{
  let dbPromise = new Promise(function(resolve)
  {
    myCmiWindow.getCmiModel().modelUrl = docUrl;
    setStateText("Loading page");

    var img = new Image;
    img.onerror = function (e)
    {
      setStateText("Error loading page",true);
      resolve(null);
    };

    img.onload = function ()
    {
      if(currentImageTexture != null)
      {
        myCmiWindow.removeTexture(currentImageTexture);
        currentImageTexture = null;
        myCmiWindow.getCmiModel().removeEntitiesFromModelByNames([currentAnnotationName]);
      }

      var aspect = this.naturalWidth/this.naturalHeight;

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

      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);

      myCmiWindow.getCmiModel().addBaseImageToModel(annotation);
      currentImageTexture = annotation.getTexture();

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

      updatePreviewMouseBehavior("2d");

      setStateText("",false);

      resolve(this);
    };
    img.setAttribute('crossorigin', 'anonymous');
    img.src = docUrl;
  });//dbPromise = new Promise

  return await dbPromise;
};//addBaseImageToModel

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

    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(currentDocument.getDocType() == "pdf")
  {
    multiPageDocument.getPage(currentPageNr).then(function(page)
    {
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      var scale = 2.0;

      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 ()
      {
        addBaseImageToModel(canvas.toDataURL("image/png"));
      });
    });
  }//else if(currentDocument.getDocType() == "pdf")

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

function navigatePage(direction)
{
  switch(direction)
  {
    case "<":
      if(currentPageNr > 1)
      {
        currentPageNr=1;
        showCurrentPage();
      }
      break;
    case "-":
      if(currentPageNr > 1)
      {
        currentPageNr--;
        showCurrentPage();
      }
      break;
    case "+":
      if(currentPageNr < pageCount)
      {
        currentPageNr++;
        showCurrentPage();
      }
      break;
    case ">":
      if(currentPageNr < pageCount)
      {
        currentPageNr=pageCount;
        showCurrentPage();
      }
      break;
  }
};//showPage

function load3dWpmZipModel(docUrl)
{
  JSZipUtils.getBinaryContent(docUrl,
  {
    progress: function(e)
    {
      setStateText(e.percent.toFixed(0) + "% received");
    },//progress: function(e)
    callback: function (err, zipData)
    {
      if(err)
        setStateText(err.message,true);
      else if(zipData.byteLength == 0)
        setStateText("Error getting zip file",true);
      else
      {
        JSZip.loadAsync(zipData).then(function (zip)
        {
          var cnt=0;
          var foundWpm = false;
          for (filename in zip.files)
          {
            cnt++;
            if(filename.includes(".wpm"))
              foundWpm = true;
          }
          if((cnt != 1)||(foundWpm == false))
          {
            setStateText("Invalid zip",true);
            return;
          }

          setStateText("Extracting from zip");

          zip.forEach(function (relativePath, zipFileContent)
          {
            if(zipFileContent.name.includes(".wpm"))
            {
              zipFileContent.async("string")
              .then(function success(content,username)
              {
                var utf8String =content;
                if(content.charCodeAt(0) === 0xFEFF)
                  {utf8String = content.substr(1);}

                myCmiWindow.openModelFromJsonString(utf8String,false,false);
                myCmiWindow.getCmiModel().modelUrl = docUrl;
                updatePreviewMouseBehavior("3d");
              },
              function error(e)
              {
                setStateText("Wrong format in zip file",true);
              });
            };//if(zipFileContent.name.includes(".wpm"))
          });//zip.forEach(
        })//JSZip.loadAsync.then
        .catch
        (
          err => setStateText(err,true)
        );//JSZip.loadAsync
      }
    }//callback: function (err, data)
  });//JSZipUtils.getBinaryContent(modelUrl,
};//load3dWpmZipModel

function onCmiNotification (event)
{
  if(event.data.split == undefined) return;
  var txtParts = event.data.split("|");
  if(txtParts[0]=="CMI_ERROR")
  {
    setStateText(txtParts[2]);
  }
  else if(txtParts[0]=="CMI_INFO")
  {
    switch(txtParts[1])
    {
      case "ModelLoading":
        setStateText(txtParts[2]);
        break;
      case "ModelOpened":
        if(currentDocument.getDbFlag() == false)
        {
          currentDocument.setDocData(JSON.stringify(myCmiWindow.getCmiModel().jsonObject));
          storageConnector.saveDocumentToBrowserDb(currentDocument).then
          (
            function(value)
            {
              currentDocument.setDocData(null);
            }
          );
        }

        setStateText("",false);
        break;
    }
  }
};//onCmiNotification

function updateDocumentInformation ()
{
  if((documentArray.length == 0)||(currentDocument == null))
  {
    document.getElementById("docTitle").innerHTML = "";
    document.getElementById("docDescription").value = "";
    document.getElementById("fileAttachments").options.length = 0;
    return;
  }

  document.getElementById("docTitle").innerHTML = currentDocument.getTitle();
  document.getElementById("docDescription").value = currentDocument.getDescription();

  //document attributes
  let docAttributes = currentDocument.getAttributes();
  let htmlTable = document.getElementById("docAttributeTable");

  let rowCount = htmlTable.rows.length;
  for ( var i = 1; i<rowCount; i++)//keep header
  {
    htmlTable.deleteRow(-1);
  };

  let row = null;
  let cell = null;
  let body = document.getElementById("docAttributeTableBody");

  for ( let i = 0; i<docAttributes.length; i++)
  {
    row = body.insertRow(-1);
    row.classList.add('notranslate');
    cell = row.insertCell(0);
    cell.innerHTML = docAttributes[i].getKey();

    cell = row.insertCell(1);
    cell.innerHTML = docAttributes[i].getValue();
  };

  //file attachments
  let fileAttachmentSelection = document.getElementById("fileAttachments");
  let fileAttachments = currentDocument.getFileAttachments();
  let attachmentDescription = document.getElementById("fileAttDesc");

  fileAttachmentSelection.options.length = 0;

  fileAttachments.sort(function(a, b)
  {
    let x = a.getTitle().toLowerCase();
    let y = b.getTitle().toLowerCase();
    if (x < y) {return -1;}
    if (x > y) {return 1;}
    return 0;
  });

  for ( let i =0; i< fileAttachments.length; i++)
  {
    var option = document.createElement("option");
    option.text = fileAttachments[i].getTitle();
    option.ref = fileAttachments[i];
    fileAttachmentSelection.add(option);
  }

  if(fileAttachments.length > 0)
  {
    fileAttachmentSelection.options.selectedIndex = 0;
    attachmentDescription.innerHTML = fileAttachments[0].getDescription();
  }
  else
    attachmentDescription.innerHTML = "";

  //document preview
  if(document.getElementById("docPreviewTab").checked == true)
    loadCurrentDocumentIntoPreview();

};//updateDocumentInformation

function downloadSelectedFileAttachment()
{
  let fileAttachmentSelection = document.getElementById("fileAttachments");
  if(fileAttachmentSelection.options.length == 0) return;
  if(fileAttachmentSelection.selectedIndex == -1) return;

  let selectedFileAttachment = fileAttachmentSelection[fileAttachmentSelection.selectedIndex].ref;
  storageConnector.downloadFileAttachment(selectedFileAttachment);
};//downloadSelectedFileAttachment

function openSelectedDocumentInPortal()
{
  if(currentDocument != null)
    storageConnector.openDocumentInPortal(currentDocument);
};//openSelectedDocumentInPortal

//Category document functions ---------------------------

function onDocAttributesLoaded(attributeArray,storageDocument)
{
  poi3dDocument.arrtibutesLoaded = true;
  if(currentDocument == storageDocument)
  {
    updateDocumentInformation();
  }
};//onDocAttributesLoaded

function onFileAttachmentSelect(selectObject)
{
  let fileAttachments = currentDocument.getFileAttachments();
  let attachmentDescription = document.getElementById("fileAttDesc");
  attachmentDescription.innerHTML = fileAttachments[selectObject.options.selectedIndex].getDescription();
};//onFileAttachmentSelect

onDocumentTabSelection = function(sectionToActivate)
{
  canBeUsed("openInPortalButt",false);
  setStateText("");

  if(sectionToActivate == "connectSect")
  {
    setDisplayStyle("connectSect","block");
    setDisplayStyle("docDescriptionSect","none");
    setDisplayStyle("docAttributesSect","none");
    setDisplayStyle("docFileAttachmentsSect","none");
    setDisplayStyle("docPreviewSect","none");
  }
  else if(sectionToActivate == "docDescriptionSect")
  {
    setDisplayStyle("connectSect","none");
    setDisplayStyle("docDescriptionSect","block");
    setDisplayStyle("docAttributesSect","none");
    setDisplayStyle("docFileAttachmentsSect","none");
    setDisplayStyle("docPreviewSect","none");
  }
  else if(sectionToActivate == "docAttributesSect")
  {
    setDisplayStyle("connectSect","none");
    setDisplayStyle("docDescriptionSect","none");
    setDisplayStyle("docAttributesSect","block");
    setDisplayStyle("docFileAttachmentsSect","none");
    setDisplayStyle("docPreviewSect","none");
  }
  else if(sectionToActivate == "docFileAttachmentsSect")
  {
    setDisplayStyle("connectSect","none");
    setDisplayStyle("docDescriptionSect","none");
    setDisplayStyle("docAttributesSect","none");
    setDisplayStyle("docFileAttachmentsSect","block");
    setDisplayStyle("docPreviewSect","none");
  }
  else if(sectionToActivate == "docPreviewSect")
  {
    setDisplayStyle("connectSect","none");
    setDisplayStyle("docDescriptionSect","none");
    setDisplayStyle("docAttributesSect","none");
    setDisplayStyle("docFileAttachmentsSect","none");
    setDisplayStyle("docPreviewSect","block");
    resizeDocumentInfoArea();
    loadCurrentDocumentIntoPreview();

    canBeUsed("openInPortalButt",true);
  }
};//onDocumentTabSelection

function setStateText(msg,style)
{
  if(msg.length == 0)
  {
    statusText.style.display = "none";
    return;
  }
  else
    statusText.style.display = "";

  if(style == "error")
  {
    statusText.innerHTML  = "<b>"+msg+"</b>";
    canBeUsed("openInPortalButt",false);
  }
  else if(style == "success")
  {
    statusText.innerHTML  = msg;
    canBeUsed("openInPortalButt",true);
  }
  else
  {
    statusText.innerHTML  = msg;
  }
};

//Category functions ------------------------
function loadCategory()
{
  let categorySelection = document.getElementById("categorySelection");
  let selectedCategory = categorySelection[categorySelection.selectedIndex].categoryEntry;
  storageConnector.loadCategory(selectedCategory);
};

function onCategoryListLoaded()
{
  let categorySelection = document.getElementById("categorySelection");
  let categories = storageConnector.getCategories();
  let category = null;
  let optionEntry = null;

  if(categorySelection)
  {
    categorySelection.options.length = 0;

    for(let i = 0; i < categories.length; i++)
    {
      category = categories[i];

      optionEntry = document.createElement("option");
      optionEntry.text = category.getTitle();
      optionEntry.categoryEntry = category;
      categorySelection.add(optionEntry);
    }
  }
  canBeUsed("loadCategoryBut",true);
}

function onCategoriesLoaded()
{
  let categorySelection = document.getElementById("categorySelection");
  let categories = storageConnector.getCategories();
  let category = null;
  let optionEntry = null;

  if(categorySelection)
  {
    categorySelection.options.length = 0;

    for(let i = 0; i < categories.length; i++)
    {
      category = categories[i];

      optionEntry = document.createElement("option");
      optionEntry.text = category.getTitle();
      optionEntry.categoryEntry = category;
      categorySelection.add(optionEntry);
    }
    if(categories.length > 0)
      updateDocumentCollectionSelection(categories[0]);
  }
  else if(categories.length > 0)
    updateDocumentCollectionSelection(categories[0]);
};

function onCategoryEntrySelect(categorySelection)
{
  let category = categorySelection[categorySelection.selectedIndex].categoryEntry;
  updateDocumentCollectionSelection(category);

  if(category.getLoadState() == false)
    canBeUsed("loadCategoryBut",true);
  else
    canBeUsed("loadCategoryBut",false);

  if(storageConnector.categorySelectedCb != null)
    storageConnector.categorySelectedCb(category);
};

function updateDocumentCollectionSelection(category)
{
  let docCollectionSelection = document.getElementById("docCollectionSelection");
  let documentCollections = category.getDocumentCollections();
  let documentCollection = null;
  docCollectionSelection.options.length = 0;

  myCmiWindow.resetCmiModel();
  myCmiWindow.currentDocFilName = "";
  myCmiWindow.drawScene();

  if(documentCollections.length > 0)
  {
    for(let i = 0; i < documentCollections.length; i++)
    {
      documentCollection = documentCollections[i];

      optionEntry = document.createElement("option");
      optionEntry.text = documentCollection.getTitle();
      optionEntry.docCollectioEntry = documentCollection;
      docCollectionSelection.add(optionEntry);
    }
  }//if(documentCollectionArray.length > 0)

  if(category.getLoadState() == true)
    canBeUsed("loadDocCollBut",false);
  else
    canBeUsed("loadDocCollBut",true);

  onDocCollectionEntrySelect(docCollectionSelection);
};

function loadDocumentCollection()
{
  let docCollectionSelection = document.getElementById("docCollectionSelection");
  if(docCollectionSelection.length == 0)
    return;

  let selectedDocumentCollection = docCollectionSelection[docCollectionSelection.selectedIndex].docCollectioEntry;
  storageConnector.loadDocumentCollection(selectedDocumentCollection);
};

function onFileAttachmentsLoaded(documentObject)
{
  let updateUi = false;

  if(
    ( documentObject == undefined || documentObject == null)&&
    (currentDocument != null)
    )
    updateUi = true;
  else if(documentObject == currentDocument)
    updateUi = true;

  if(updateUi == true)//see updateDocumentInformation
  {
    let fileAttachmentSelection = document.getElementById("fileAttachments");
    let fileAttachments = currentDocument.getFileAttachments();
    let attachmentDescription = document.getElementById("fileAttDesc");

    fileAttachmentSelection.options.length = 0;

    fileAttachments.sort(function(a, b)
    {
      let x = a.getTitle().toLowerCase();
      let y = b.getTitle().toLowerCase();
      if (x < y) {return -1;}
      if (x > y) {return 1;}
      return 0;
    });

    for ( let i =0; i< fileAttachments.length; i++)
    {
      var option = document.createElement("option");
      option.text = fileAttachments[i].getTitle();
      option.ref = fileAttachments[i];
      fileAttachmentSelection.add(option);
    }

    if(fileAttachments.length > 0)
    {
      fileAttachmentSelection.options.selectedIndex = 0;
      attachmentDescription.innerHTML = fileAttachments[0].getDescription();
    }
    else
      attachmentDescription.innerHTML = "";
  }//if(documentObject == currentDocument)
};

function onDocumentCollectionLoaded(category)
{
  let docCollectionSelection = document.getElementById("docCollectionSelection");
  if((docCollectionSelection.length == 0)&&(category.getDocumentCollections().length > 0))
    updateDocumentCollectionSelection(category);

  canBeUsed("loadDocCollBut",false);

  canBeUsed("docDescriptionLab",true);
  canBeUsed("docAttributesLab",true);
  canBeUsed("docFileAttachmentsLab",true);
  canBeUsed("docPreviewLab",true);

  canBeUsed("docDescriptionTab",true);
  canBeUsed("docAttributesTab",true);
  canBeUsed("docFileAttachmentsTab",true);
  canBeUsed("docPreviewTab",true);

  onDocCollectionEntrySelect(docCollectionSelection);
};//onDocumentCollectionLoaded

function onDocCollectionEntrySelect(docCollectionSelection)
{
  let swiperCollection = document.getElementsByClassName("swiper-wrapper")[0];
  while (swiperCollection.firstChild) {swiperCollection.firstChild.remove()};
  currentDocument = null;
  swiper.update();
  myCmiWindow.resetCmiModel();
  setStateText("");

  if(docCollectionSelection.length == 0)
    return;

  let selDocCollection = docCollectionSelection[docCollectionSelection.selectedIndex].docCollectioEntry;
  let selCategoryEntry = selDocCollection.getCategory();

  if(selDocCollection.getLoadState() == true)
    canBeUsed("loadDocCollBut",false);
  else
    canBeUsed("loadDocCollBut",true);

  documentArray = selDocCollection.getDocuments();

  for ( let i =0; i< documentArray.length; i++)
  {
    addImageToSwiper(swiperCollection,documentArray[i].getThumbnailUrl());
  }
  if(documentArray.length >0)
  {
    swiper.update();
    swiper.slideTo(0, 700, false);
    currentDocument = documentArray[0];
    updateDocumentInformation();
  }
};//onDocCollectionEntrySelect

function addImageToSwiper (swiperCollection, imageUrl)
{
  var swiperSlide = document.createElement("div");
  swiperSlide.classList.add("swiper-slide");
  swiperCollection.append(swiperSlide);

  var swiperImage = document.createElement("img");
  swiperSlide.append(swiperImage);
  swiperImage.src = imageUrl;
};//addImageToSwiper

function login()
{
  getConnectionInfo();
  let userName = document.getElementById("userName").value;
  let userPwd = document.getElementById("userPwd").value;

  storageConnector.login(userName,userPwd);
};
