mainBuild:
  name: opencascade.ocjsx-viewer.prod-full.js

  bindings:
    - symbol: AIS_ColoredShape
    - symbol: AIS_ConnectedInteractive
    - symbol: AIS_DisplayMode
    - symbol: AIS_InteractiveContext
    - symbol: AIS_InteractiveObject
    - symbol: AIS_Shape
    - symbol: AIS_ViewController
    - symbol: AIS_ViewCube
    - symbol: Aspect_GradientFillMethod
    - symbol: Aspect_TypeOfResize
    - symbol: Aspect_Window
    - symbol: Aspect_WindowInputListener
    - symbol: Bnd_Box
    - symbol: BRep_Builder
    - symbol: BRepMesh_DiscretRoot
    - symbol: BRepMesh_IncrementalMesh
    - symbol: BRepTools
    - symbol: CDM_Document
    - symbol: gp_Dir
    - symbol: gp_Pln
    - symbol: gp_Pnt
    - symbol: gp_Trsf
    - symbol: Graphic3d_ClipPlane
    - symbol: Graphic3d_CView
    - symbol: Graphic3d_DataStructureManager
    - symbol: Graphic3d_GraphicDriver
    - symbol: Graphic3d_SequenceOfHClipPlane
    - symbol: Graphic3d_Texture2D
    - symbol: Graphic3d_Texture2Dplane
    - symbol: Graphic3d_TextureRoot
    - symbol: Graphic3d_TextureMap
    - symbol: Graphic3d_TransformPers
    - symbol: Graphic3d_Vec2i
    - symbol: Handle_AIS_InteractiveContext
    - symbol: Handle_AIS_InteractiveObject
    - symbol: Handle_Aspect_DisplayConnection
    - symbol: Handle_Aspect_Window
    - symbol: Handle_Graphic3d_ClipPlane
    - symbol: Handle_Graphic3d_CView
    - symbol: Handle_Graphic3d_GraphicDriver
    - symbol: Handle_Graphic3d_SequenceOfHClipPlane
    - symbol: Handle_Graphic3d_TextureMap
    - symbol: Handle_Graphic3d_TransformPers
    - symbol: Handle_Prs3d_Drawer
    - symbol: Handle_Image_PixMap
    - symbol: Handle_TDocStd_Document
    - symbol: Handle_V3d_View
    - symbol: Handle_V3d_Viewer
    - symbol: Handle_XCAFDoc_DimTolTool
    - symbol: Handle_XCAFDoc_ShapeTool
    - symbol: IFSelect_ReturnStatus
    - symbol: Image_Format
    - symbol: Image_PixMap
    - symbol: Message_ProgressRange
    - symbol: NCollection_BaseSequence
    - symbol: OCJS
    - symbol: OpenGl_GraphicDriver
    - symbol: Prs3d_Drawer
    - symbol: Graphic3d_PresentationAttributes
    - symbol: PrsMgr_PresentableObject
    - symbol: PrsMgr_TypeOfPresentation3d
    - symbol: Quantity_Color
    - symbol: Quantity_ColorRGBA
    - symbol: Quantity_TypeOfColor
    - symbol: SelectMgr_SelectableObject
    - symbol: Standard_Failure
    - symbol: Standard_Transient
    - symbol: STEPCAFControl_Reader
    - symbol: StdPrs_ToolTriangulatedShape
    - symbol: TCollection_AsciiString
    - symbol: TCollection_ExtendedString
    - symbol: TDataStd_GenericEmpty
    - symbol: TDF_Attribute
    - symbol: TDF_ChildIterator
    - symbol: TDF_Label
    - symbol: TDF_LabelSequence
    - symbol: TDF_Tool
    - symbol: TDocStd_Document
    - symbol: Test
    - symbol: TopLoc_Location
    - symbol: TopoDS_Builder
    - symbol: TopoDS_Compound
    - symbol: TopoDS_Shape
    - symbol: V3d_TypeOfView
    - symbol: V3d_View
    - symbol: V3d_Viewer
    - symbol: Wasm_Window
    - symbol: XCAFPrs_AISObject
    - symbol: XCAFDoc_ColorTool
    - symbol: XCAFDoc_ColorType
    - symbol: XCAFDoc_DimTolTool
    - symbol: XCAFDoc_DocumentTool
    - symbol: XCAFDoc_ShapeTool
    - symbol: XCAFPrs_Style
    - symbol: IGESCAFControl_Reader
    - symbol: IGESControl_Reader
    - symbol: XSControl_Reader
    - symbol: RWGltf_CafReader
    - symbol: RWMesh_CafReader

  emccFlags:
    # These are just the default values as defined in /src/customBuildSchema.py
    - -O3
    - -sEXPORT_ES6=1
    - -sUSE_ES6_IMPORT_META=1
    - -sEXPORTED_RUNTIME_METHODS=['FS']
    - -sINITIAL_MEMORY=100MB
    - -sMAXIMUM_MEMORY=4GB
    - -sALLOW_MEMORY_GROWTH=1
    - -sUSE_FREETYPE=1
    - -sLLD_REPORT_UNDEFINED
    - --no-entry
    - |
      -sPTHREAD_POOL_SIZE='globalThis.ocThreadCount ?? (navigator.hardwareConcurrency ?? 6)'
    - -sENVIRONMENT='web,worker'
    - -sDISABLE_EXCEPTION_CATCHING=0
    - -flto
    - -sMAX_WEBGL_VERSION=2
    - -sWEBGL2_BACKWARDS_COMPATIBILITY_EMULATION=1
    - /src/freeimage/Dist/libfreeimage.a

additionalCppCode: |
  #include <string>
  #include <iostream>
  #include <emscripten/html5.h>
  #include <emscripten/val.h>
  typedef Handle(IMeshTools_Context) Handle_IMeshTools_Context;

  class OCJS {
  public:
    static Standard_Failure* getStandard_FailureData(intptr_t exceptionPtr) {
      return reinterpret_cast<Standard_Failure*>(exceptionPtr);
    }
  };

  class Test {
  public:
    static void SetWindow(V3d_View* v, const Handle(Aspect_Window)& w) {
      v->SetWindow(w);
      // v->ChangeRenderingParams().IsAntialiasingEnabled = true;
      // v->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * myDevicePixelRatio + 0.5);
    }
    static AIS_InteractiveContext* castAIS_InteractiveContext(intptr_t ptr) {
      return reinterpret_cast<AIS_InteractiveContext*>(ptr);
    }
    static V3d_View* castV3d_View(intptr_t ptr) {
      return reinterpret_cast<V3d_View*>(ptr);
    }
    static AIS_ViewController* castAIS_ViewController(intptr_t ptr) {
      return reinterpret_cast<AIS_ViewController*>(ptr);
    }
    static Handle_AIS_InteractiveObject* castHandle_AIS_InteractiveObject(intptr_t ptr) {
      return reinterpret_cast<Handle_AIS_InteractiveObject*>(ptr);
    }
    static Graphic3d_ClipPlane* castGraphic3d_ClipPlane(intptr_t ptr) {
      return reinterpret_cast<Graphic3d_ClipPlane*>(ptr);
    }
    static bool ProcessWheelEvent(Wasm_Window* w, Aspect_WindowInputListener& theListener, emscripten::val event) {
      EmscriptenWheelEvent theEvent;
      theEvent.mouse.timestamp = event["timestamp"].as<double>();
      theEvent.mouse.screenX = event["screenX"].as<long>();
      theEvent.mouse.screenY = event["screenY"].as<long>();
      theEvent.mouse.clientX = event["clientX"].as<long>();
      theEvent.mouse.clientY = event["clientY"].as<long>();
      theEvent.mouse.ctrlKey = event["ctrlKey"].as<EM_BOOL>();
      theEvent.mouse.shiftKey = event["shiftKey"].as<EM_BOOL>();
      theEvent.mouse.altKey = event["altKey"].as<EM_BOOL>();
      theEvent.mouse.metaKey = event["metaKey"].as<EM_BOOL>();
      theEvent.mouse.button = event["button"].as<short>();
      theEvent.mouse.buttons = event["buttons"].as<short>();
      theEvent.mouse.movementX = event["movementX"].as<long>();
      theEvent.mouse.movementY = event["movementY"].as<long>();
      theEvent.mouse.targetX = event["targetX"].as<long>();
      theEvent.mouse.targetY = event["targetY"].as<long>();
      theEvent.deltaX = event["deltaX"].as<double>();
      theEvent.deltaY = event["deltaY"].as<double>();
      theEvent.deltaZ = event["deltaZ"].as<double>();
      theEvent.deltaMode = event["deltaMode"].as<unsigned long>();
      return w->ProcessWheelEvent(theListener, EMSCRIPTEN_EVENT_WHEEL, &theEvent);
    }
    static bool ProcessMouseEvent(Wasm_Window* w, Aspect_WindowInputListener& theListener, emscripten::val event, int eventType) {
      EmscriptenMouseEvent theEvent;
      theEvent.timestamp = event["timestamp"].as<double>();
      theEvent.screenX = event["screenX"].as<long>();
      theEvent.screenY = event["screenY"].as<long>();
      theEvent.clientX = event["clientX"].as<long>();
      theEvent.clientY = event["clientY"].as<long>();
      theEvent.ctrlKey = event["ctrlKey"].as<EM_BOOL>();
      theEvent.shiftKey = event["shiftKey"].as<EM_BOOL>();
      theEvent.altKey = event["altKey"].as<EM_BOOL>();
      theEvent.metaKey = event["metaKey"].as<EM_BOOL>();
      theEvent.button = event["button"].as<short>();
      theEvent.buttons = event["buttons"].as<short>();
      theEvent.movementX = event["movementX"].as<long>();
      theEvent.movementY = event["movementY"].as<long>();
      theEvent.targetX = event["targetX"].as<long>();
      theEvent.targetY = event["targetY"].as<long>();
      return w->ProcessMouseEvent(theListener, eventType, &theEvent);
    }
    static bool ProcesUiEvent(Wasm_Window* w, Aspect_WindowInputListener& theListener, emscripten::val event, int eventType) {
      EmscriptenUiEvent theEvent;
      theEvent.detail = event["detail"].as<long>();
      theEvent.documentBodyClientWidth = event["documentBodyClientWidth"].as<int>();
      theEvent.documentBodyClientHeight = event["documentBodyClientHeight"].as<int>();
      theEvent.windowInnerWidth = event["windowInnerWidth"].as<int>();
      theEvent.windowInnerHeight = event["windowInnerHeight"].as<int>();
      theEvent.windowOuterWidth = event["windowOuterWidth"].as<int>();
      theEvent.windowOuterHeight = event["windowOuterHeight"].as<int>();
      theEvent.scrollTop = event["scrollTop"].as<int>();
      theEvent.scrollLeft = event["scrollLeft"].as<int>();
      return w->ProcessUiEvent(theListener, eventType, &theEvent);
    }
    static bool ProcessTouchEvent(Wasm_Window* w, Aspect_WindowInputListener& theListener, emscripten::val event, int eventType) {
      EmscriptenTouchEvent theEvent;
      theEvent.timestamp = event["timestamp"].as<double>();
      theEvent.numTouches = event["numTouches"].as<int>();
      theEvent.ctrlKey = event["ctrlKey"].as<EM_BOOL>();
      theEvent.shiftKey = event["shiftKey"].as<EM_BOOL>();
      theEvent.altKey = event["altKey"].as<EM_BOOL>();
      theEvent.metaKey = event["metaKey"].as<EM_BOOL>();

      if(theEvent.numTouches >= 1) {
        theEvent.touches[0].identifier = event["touches0"]["identifier"].as<long>();
        theEvent.touches[0].screenX = event["touches0"]["screenX"].as<long>();
        theEvent.touches[0].screenY = event["touches0"]["screenY"].as<long>();
        theEvent.touches[0].clientX = event["touches0"]["clientX"].as<long>();
        theEvent.touches[0].clientY = event["touches0"]["clientY"].as<long>();
        theEvent.touches[0].pageX = event["touches0"]["pageX"].as<long>();
        theEvent.touches[0].pageY = event["touches0"]["pageY"].as<long>();
        theEvent.touches[0].isChanged = event["touches0"]["isChanged"].as<EM_BOOL>();
        theEvent.touches[0].onTarget = event["touches0"]["onTarget"].as<EM_BOOL>();
        theEvent.touches[0].targetX = event["touches0"]["targetX"].as<long>();
        theEvent.touches[0].targetY = event["touches0"]["targetY"].as<long>();
      }

      if(theEvent.numTouches >= 2) {
        theEvent.touches[1].identifier = event["touches1"]["identifier"].as<long>();
        theEvent.touches[1].screenX = event["touches1"]["screenX"].as<long>();
        theEvent.touches[1].screenY = event["touches1"]["screenY"].as<long>();
        theEvent.touches[1].clientX = event["touches1"]["clientX"].as<long>();
        theEvent.touches[1].clientY = event["touches1"]["clientY"].as<long>();
        theEvent.touches[1].pageX = event["touches1"]["pageX"].as<long>();
        theEvent.touches[1].pageY = event["touches1"]["pageY"].as<long>();
        theEvent.touches[1].isChanged = event["touches1"]["isChanged"].as<EM_BOOL>();
        theEvent.touches[1].onTarget = event["touches1"]["onTarget"].as<EM_BOOL>();
        theEvent.touches[1].targetX = event["touches1"]["targetX"].as<long>();
        theEvent.touches[1].targetY = event["touches1"]["targetY"].as<long>();
      }

      return w->ProcessTouchEvent(theListener, eventType, &theEvent);
    }
    static emscripten::val GetListOfGDTShapes(XCAFDoc_DimTolTool* dimTolTool) {
      NCollection_IndexedDataMap<TDF_Label, TopoDS_Shape, TDF_LabelMapHasher> theGDTLabelToShape;
      dimTolTool->GetGDTPresentations(theGDTLabelToShape);
      emscripten::val ret = emscripten::val::array();
      int ii = 0;
      for(auto i = theGDTLabelToShape.begin(); i != theGDTLabelToShape.end(); i++) {
        ret.set(ii++, emscripten::val(*i));
      }
      return ret;
    }
  };
