####################################################################################################
#
# Invoking X3D model self-test:
#
#   $ python NavigationInfoExample.py
#
# Python package x3d.py package is available on PyPI for import.
#   This approach simplifies Python X3D deployment and use.
#   https://pypi.org/project/x3d
#
# Installation:
#       pip install x3d
# or
#       python -m pip install x3d
#
# Developer options for loading x3d package in other Python programs:
#
#    from x3d import *  # preferred approach, terser source that avoids x3d.* class prefixes
#
# or
#    import x3d         # traditional way to subclass x3d package, all classes require x3d.* prefix,
#                       # but python source is very verbose, for example x3d.Material x3d.Shape etc.
#                       # X3dToPython.xslt stylesheet insertPackagePrefix=true supports this option.
#
# Project home page:    # X3D Python Scene Access Interface Library (X3DPSAIL)
#                       # https://www.web3d.org/x3d/stylesheets/python/python.html
# Conversion generator: # https://www.web3d.org/x3d/stylesheets/X3dToPython.xslt
#
####################################################################################################

from x3d import *

newModel=X3D(profile='Immersive',version='3.3',
  head=head(
    children=[
    meta(content='NavigationInfoExample.x3d',name='title'),
    meta(content='This example provides three Viewpoint nodes bound to corresponding selectable NavigationInfo nodes that override navigation modes in the Hello World example, superseding default NavigationInfo type provided in that contained Inline model. To test this model, change viewpoints and then try to navigate each time, noting the new navigation mode.',name='description'),
    meta(content='NavigationInfo nodes have their own binding stack, similar to Viewpoint nodes, meaning that they can be activated (bound) in any order, but only one can be active at a given time. Cross-connecting a custom NavigationInfo to some Viewpoints can improve user experience in larger scenes.',name='info'),
    meta(content='Don Brutzman',name='creator'),
    meta(content='Leonard Daly',name='creator'),
    meta(content='14 November 2005',name='created'),
    meta(content='12 August 2025',name='modified'),
    meta(content='NavigationInfoExampleDashboard.png',name='Image'),
    meta(content='NavigationInfoExampleIndexPage.png',name='Image'),
    meta(content='X3D Scene Authoring Hints: Viewing and Navigation https://web3d.org/x3d/content/examples/X3dSceneAuthoringHints.html#Viewpoints',name='reference'),
    meta(content='https://www.web3d.org/x3d/content/examples/X3dResources.html',name='reference'),
    meta(content='Copyright (c) 2005, Daly Realism and Don Brutzman',name='rights'),
    meta(content='X3D book, X3D graphics, X3D-Edit, http://www.x3dGraphics.com',name='subject'),
    meta(content='https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter04ViewingNavigation/NavigationInfoExample.x3d',name='identifier'),
    meta(content='X3D-Edit 4.0, https://www.web3d.org/x3d/tools/X3D-Edit',name='generator'),
    meta(content='../license.html',name='license')]),
  Scene=Scene(
    children=[
    WorldInfo(title='NavigationInfoExample.x3d'),
    Comment('Because these NavigationInfo nodes are here in the parent scene, the first one is bound at load time, and thus governs the active navigation modes'),
    Comment('Note that an author can control what choices a user has available, and initial type selected, while the user can select among navigation choices from available options'),
    Comment('Author option: experiment by swapping order of these NavigationInfo nodes, first one is bound at load time.'),
    Comment('FLY_FIRST is initial choice so that it noticeably overrides EXAMINE ANY found in the Inline HelloWorld scene'),
    NavigationInfo(DEF='FLY_FIRST',type=["FLY","ANY"]),
    NavigationInfo(DEF='DEFAULT_EXAMINE_FIRST'),
    NavigationInfo(DEF='SIT_TIGHT',type=["NONE"]),
    Comment('For this scene, first Viewpoint bound also binds corresponding NavigationInfo'),
    Viewpoint(DEF='view_navigation_FLY',description='user navigation mode changed to FLY ANY'),
    Viewpoint(DEF='view_navigation_EXAMINE',description='user navigation mode changed to EXAMINE ANY',orientation=(0,1,0,-0.380506),position=(-4,0,10)),
    Viewpoint(DEF='view_navigation_NONE',description='disable user navigation mode to NONE',orientation=(0,1,0,0.380506),position=(4,0,10)),
    ROUTE(fromField='isBound',fromNode='view_navigation_FLY',toField='set_bind',toNode='FLY_FIRST'),
    ROUTE(fromField='isBound',fromNode='view_navigation_EXAMINE',toField='set_bind',toNode='DEFAULT_EXAMINE_FIRST'),
    ROUTE(fromField='isBound',fromNode='view_navigation_NONE',toField='set_bind',toNode='SIT_TIGHT'),
    Comment('Finally here is original scene which also has a Viewpoint and a default EXAMINE ANY for NavigationInfo.type'),
    Inline(url=["../HelloWorld.x3d","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/HelloWorld.x3d","../HelloWorld.wrl","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/HelloWorld.wrl"],
      metadata=MetadataString(name='profile',value=["Immersive"]))])
)

### X3D model conversion complete ###

####################################################################################################
# Self-test diagnostics
####################################################################################################

print('Self-test diagnostics for NavigationInfoExample.py:')
if        metaDiagnostics(newModel): # built-in utility method in X3D class
    print(metaDiagnostics(newModel)) # display meta info, hint, warning, error, TODO values in this model
# print('check newModel.XML() serialization...')
newModelXML= newModel.XML() # test export method XML() for exceptions during export
newModel.XMLvalidate()
# print(newModelXML) # diagnostic

try:
#   print('check newModel.VRML() serialization...')
    newModelVRML=newModel.VRML() # test export method VRML() for exceptions during export
    # print(prependLineNumbers(newModelVRML)) # debug
    print("Python-to-VRML export of VRML output successful", flush=True)
except Exception as err: # usually BaseException
    # https://stackoverflow.com/questions/18176602/how-to-get-the-name-of-an-exception-that-was-caught-in-python
    print("*** Python-to-VRML export of VRML output failed:", type(err).__name__, err)
    if newModelVRML: # may have failed to generate
        print(prependLineNumbers(newModelVRML, err.lineno))

try:
#   print('check newModel.JSON() serialization...')
    newModelJSON=newModel.JSON() # test export method JSON() for exceptions during export
#   print(prependLineNumbers(newModelJSON)) # debug
    print("Python-to-JSON export of JSON output successful (under development)")
except Exception as err: # usually SyntaxError
    print("*** Python-to-JSON export of JSON output failed:", type(err).__name__, err)
    if newModelJSON: # may have failed to generate
        print(prependLineNumbers(newModelJSON,err.lineno))

print("python NavigationInfoExample.py load and self-test diagnostics complete.")
