/*======================================================================================================*/
/* Display/hide things											*/
/*													*/
/* Plugin for EQUINOX-3D										*/
/*													*/
/* AUTHOR:	Gabor Nagy										*/
/* DATE:	1996-Oct-17 23:22:50									*/
/*													*/
/* EQUINOX-3D(TM), 3DPanel(TM) and 3DLib(TM) Copyright (C) 1995 By Gabor Nagy. All rights reserved.	*/
/*======================================================================================================*/
#include <stdio.h>

#include <EPlugins.h>

#include <EGUI/PushButton.h>
#include <EGUI/Dialog.h>

#include <E3D/E3D.h>
#include <E3D/3DWindow.h>

#include <Xe/Label.h>


static EguiItem		E3d_HideToggleSelectedMenuButton = NULL,
			E3d_HideSelectedMenuButton = NULL,
			E3d_HideUnselectedMenuButton = NULL,
			E3dp_UnHideSelectionMenuButton = NULL,
			E3dp_UnHideAllMenuButton = NULL,
			E3dp_ShowHotKeysMenuButton = NULL;


// Operations
//
enum
{
 CR_HIDE_TOGGLE_SELECTED=1,
 CR_HIDE_SELECTED,
 CR_HIDE_UNSELECTED,
 CR_UNHIDE_SELECTED,
 CR_UNHIDE_ALL
};


/*======================================*/
/* Object display/hide			*/
/*======================================*/
static void E3d_HideToggleSelection()
{
 E3dScene*	LScene=E3d_Scene;
 E3dModel*	LModel;
 E3dGeometry**	LGeometries;
 E3dGeometry*	LGeometry;
 unsigned int	LC, LN=LScene->NumOfRootModels;
 unsigned int	LGmCnt, LGmNum,
		LModelsHid=0, LModelsUnhid=0,
		LGeometriesHid=0, LGeometriesUnhid=0,
		LPolyGroupsHid=0, LPolyGroupsUnhid=0;


 for(LC=0;LC<LN;LC++)
 {
  LModel=LScene->RootModels[LC];

  for(;LModel;LModel=LModel->Next)
  {
   LGmNum=LModel->NumOfGeometries;LGeometries=LModel->Geometries;

   switch(LModel->Selection)
   {
    case E3dSEL_NODE:
    case E3dSEL_BRANCH:
    case E3dSEL_BRANCH_ROOT:
     if(LModel->Visible) { LModel->Visible = FALSE;LModelsHid++; }
     else { LModel->Visible = TRUE;LModelsUnhid++; }
    break;

    default:
     for(LGmCnt=0;LGmCnt<LGmNum;LGmCnt++)
     {
      if((LGeometry=LGeometries[LGmCnt])!=NULL)
      {
       if(LGeometry->Selection==E3dSEL_GEOMETRY)
       {
	if(LGeometry->Visible) { LGeometry->Visible=FALSE;LGeometriesHid++; }
	else { LGeometry->Visible=TRUE;LGeometriesUnhid++; }
       }
       else
       {
	switch(LGeometry->GeoType)
	{
	 caseE3dMESH():
	  {
	   E3dMesh*		LMesh=(E3dMesh*)LGeometry;
	   E3dPolyGroup**	LPolyGroups=LMesh->PolyGroups;
	   E3dPolyGroup*	LPolyGroup;
	   unsigned int		LGCnt, LGNum=LMesh->NumOfPolyGroups;


	   for(LGCnt=0;LGCnt<LGNum;LGCnt++)
	   {
	    LPolyGroup=LPolyGroups[LGCnt];
	    if(LPolyGroup->Selected)
	    {
	     if(LPolyGroup->Visible) { LPolyGroup->Visible=FALSE;LPolyGroupsHid++; }
	     else { LPolyGroup->Visible=TRUE;LPolyGroupsUnhid++; }
	    }
	   }
	  }
	 break;
	}
       }
      }
     }
    break;
   }
  }
 }

 if((LModelsHid>0)||(LModelsUnhid>0)||(LGeometriesHid)||(LGeometriesUnhid)||(LPolyGroupsHid)||(LPolyGroupsUnhid))
 {
  E3dSceneCallbackStruct	LCBS;

  LCBS.Reason=E3dCR_HIDE_UNHIDE;
  E3d_CallCallbacks(LScene, LScene->Callbacks, LScene->NumOfCallbacks, &LCBS);
 }
}


/*======================================*/
/* Object display/hide			*/
/*======================================*/
void E3d_HideUnhide(int LOperation)
{
 E3dScene*	LScene=E3d_Scene;
 E3dModel*	LModel;
 E3dGeometry**	LGeometries;
 E3dGeometry*	LGeometry;
 unsigned int	LC, LN=LScene->NumOfRootModels;
 unsigned int	LGmCnt, LGmNum,
		LModelsHid=0, LModelsUnhid=0,
		LGeometriesHid=0, LGeometriesUnhid=0,
		LPolyGroupsHid=0, LPolyGroupsUnhid=0;
 EBool		LModelSelected;


 for(LC=0;LC<LN;LC++)
 {
  LModel=LScene->RootModels[LC];

  for(;LModel;LModel=LModel->Next)
  {
   LGmNum=LModel->NumOfGeometries;LGeometries=LModel->Geometries;
   switch(LOperation)
   {
    case CR_HIDE_SELECTED:
     switch(LModel->Selection)
     {
      case E3dSEL_NODE:
      case E3dSEL_BRANCH:
      case E3dSEL_BRANCH_ROOT:
       if(LModel->Visible) { LModel->Visible = FALSE;LModelsHid++; }
      break;

      default:
       for(LGmCnt=0;LGmCnt<LGmNum;LGmCnt++)
       {
	if((LGeometry=LGeometries[LGmCnt])!=NULL)
	{
	 if(LGeometry->Selection==E3dSEL_GEOMETRY)
	 {
	  if(LGeometry->Visible) { LGeometry->Visible=FALSE;LGeometriesHid++; }
	 }
	 else
	 {
	  switch(LGeometry->GeoType)
	  {
	   caseE3dMESH():
	    {
	     E3dMesh*		LMesh=(E3dMesh*)LGeometry;
	     E3dPolyGroup**	LPolyGroups=LMesh->PolyGroups;
	     E3dPolyGroup*	LPolyGroup;
	     unsigned int	LGCnt, LGNum=LMesh->NumOfPolyGroups;


	     for(LGCnt=0;LGCnt<LGNum;LGCnt++)
	     {
	      LPolyGroup=LPolyGroups[LGCnt];
	      if(LPolyGroup->Selected) { if(LPolyGroup->Visible) { LPolyGroup->Visible=FALSE;LPolyGroupsHid++; } }
	     }
	    }
	   break;
	  }
	 }
	}
       }
      break;
     }
    break;

    case CR_HIDE_UNSELECTED:
     switch(LModel->Selection)
     {
      case E3dSEL_NONE:
       if(LModel->Visible) { LModel->Visible = FALSE;LModelsHid++; }
      break;

      case E3dSEL_GEOMETRY:
       LGmNum=LModel->NumOfGeometries;LGeometries=LModel->Geometries;
       for(LGmCnt=0;LGmCnt<LGmNum;LGmCnt++)
       {
	if((LGeometry=LGeometries[LGmCnt])!=NULL)
	{
         switch(LGeometry->Selection)
	 {
	  case E3dGSEL_NONE:
	   if(LGeometry->Visible) { LGeometry->Visible=FALSE;LGeometriesHid++; }
	  break;

	  case E3dGSEL_POLYGROUP:
	   switch(LGeometry->GeoType)
	   {
	    caseE3dMESH():
	     {
	      E3dMesh*		LMesh=(E3dMesh*)LGeometry;
	      E3dPolyGroup**	LPolyGroups=LMesh->PolyGroups;
	      E3dPolyGroup*	LPolyGroup;
	      unsigned int	LGCnt, LGNum=LMesh->NumOfPolyGroups;


	      for(LGCnt=0;LGCnt<LGNum;LGCnt++)
	      {
	       LPolyGroup=LPolyGroups[LGCnt];
	       if(!LPolyGroup->Selected) { if(LPolyGroup->Visible) LPolyGroup->Visible=FALSE;LPolyGroupsHid++; }
	      }
	     }
	    break;
	   }
	  break;
	 }
	}
       }
      break;
     }
    break;

    case CR_UNHIDE_SELECTED:
     if(LModel->Selection!=E3dSEL_NONE)
     {
      E3dM_IsModelSelected(LModel, LModelSelected);
      if(!LModel->Visible) { LModel->Visible = TRUE;LModelsUnhid++; }

      for(LGmCnt=0;LGmCnt<LGmNum;LGmCnt++)
      {
       if((LGeometry=LGeometries[LGmCnt])!=NULL)
       {
	if(LModelSelected||(LGeometry->Selection!=E3dGSEL_NONE))
	{
	 if(!LGeometry->Visible) { LGeometry->Visible=TRUE;LGeometriesUnhid++; }

	 switch(LGeometry->GeoType)
	 {
	  caseE3dMESH():
	   {
	    E3dMesh*		LMesh=(E3dMesh*)LGeometry;
	    E3dPolyGroup**	LPolyGroups=LMesh->PolyGroups;
	    E3dPolyGroup*	LPolyGroup;
	    unsigned int	LGCnt, LGNum=LMesh->NumOfPolyGroups;


	    for(LGCnt=0;LGCnt<LGNum;LGCnt++)
	    {
	     LPolyGroup=LPolyGroups[LGCnt];
	     if(LGeometry->Selection==E3dGSEL_POLYGROUP)
	     {
	      if(LPolyGroup->Selected) if(!LPolyGroup->Visible) { LPolyGroup->Visible=TRUE;LPolyGroupsUnhid++; }
	     }
	     else if(!LPolyGroup->Visible) { LPolyGroup->Visible=TRUE;LPolyGroupsUnhid++; }
	    }
	   }
	  break;
	 }
	}
       }
      }
     }
    break;

    case CR_UNHIDE_ALL:
     if((LModel->Type!=E3dMDL_CAMERA)&&(LModel->Type!=E3dMDL_CAMERA_INTEREST))
     {
      if(!LModel->Visible) { LModel->Visible = TRUE;LModelsUnhid++; }

      for(LGmCnt=0;LGmCnt<LGmNum;LGmCnt++)
      {
       if((LGeometry=LGeometries[LGmCnt])!=NULL)
       {
	if(!LGeometry->Visible) { LGeometry->Visible=TRUE;LGeometriesUnhid++; }

	switch(LGeometry->GeoType)
	{
	 caseE3dMESH():
	  {
	   E3dMesh*		LMesh=(E3dMesh*)LGeometry;
	   E3dPolyGroup**	LPolyGroups=LMesh->PolyGroups;
	   E3dPolyGroup*	LPolyGroup;
	   unsigned int		LGCnt, LGNum=LMesh->NumOfPolyGroups;


	   for(LGCnt=0;LGCnt<LGNum;LGCnt++)
	   {
	    LPolyGroup=LPolyGroups[LGCnt];
	    if(!LPolyGroup->Visible) { LPolyGroup->Visible=TRUE;LPolyGroupsUnhid++; }
	   }
	  }
	 break;
	}
       }
      }
     }
    break;
   }
  }
 }

 if((LModelsHid>0)||(LModelsUnhid>0)||(LGeometriesHid)||(LGeometriesUnhid)||(LPolyGroupsHid)||(LPolyGroupsUnhid))
 {
  E3dSceneCallbackStruct	LCBS;

  LCBS.Reason=E3dCR_HIDE_UNHIDE;
  E3d_CallCallbacks(LScene, LScene->Callbacks, LScene->NumOfCallbacks, &LCBS);
 }
}


/*======================================*/
/* Menu callback			*/
/*======================================*/
static void E3dMCB_ModelDisplay(EguiItem LGUIItem, EPointer LClientData, EPointer LCallData)
{
 switch((int)LClientData)
 {
  case CR_HIDE_TOGGLE_SELECTED:	E3d_HideToggleSelection();break;

  default:	E3d_HideUnhide((int)LClientData);break;
 }

 E3dp_Refresh3DWindows(E3dDF_ALL, E3dVM_ALL);
}


/*======================================*/
/* Menu callback			*/
/*======================================*/
static void E3dMCB_Debug(EguiItem LGUIItem, EPointer LClientData, EPointer LCallData)
{
 E_PrintKeyTable();
}


/*======================================*/
/* Entry point of the plugin		*/
/*======================================*/
int Plugin_Init(EPlugin* LPlugin)
{
 E3d_HideToggleSelectedMenuButton=EGUI_AddPushButton("Menu->Display", "Toggle hide/un-hide selected", '\0', NULL, NULL, FALSE, NULL, E3dMCB_ModelDisplay, (EPointer)CR_HIDE_TOGGLE_SELECTED);
 E3d_HideSelectedMenuButton=EGUI_AddPushButton("Menu->Display", "Hide selected", '\0', NULL, NULL, FALSE, NULL, E3dMCB_ModelDisplay, (EPointer)CR_HIDE_SELECTED);
 E3d_HideUnselectedMenuButton=EGUI_AddPushButton("Menu->Display", "Hide unselected", '\0', NULL, NULL, FALSE, NULL, E3dMCB_ModelDisplay, (EPointer)CR_HIDE_UNSELECTED);
 E3dp_UnHideSelectionMenuButton=EGUI_AddPushButton("Menu->Display", "Un-hide selected", '\0', NULL, NULL, FALSE, NULL, E3dMCB_ModelDisplay, (EPointer)CR_UNHIDE_SELECTED);
 E3dp_UnHideAllMenuButton=EGUI_AddPushButton("Menu->Display", "Un-hide all", '\0', NULL, NULL, FALSE, NULL, E3dMCB_ModelDisplay, (EPointer)CR_UNHIDE_ALL);

 E3dp_ShowHotKeysMenuButton=EGUI_AddPushButton("Menu->Debug", "ShowHotKeys", '\0', NULL, NULL, FALSE, NULL, E3dMCB_Debug, (EPointer)0);
 return(0);
}


/*======================================*/
/* Exit method of the plugin		*/
/*======================================*/
int Plugin_Exit()
{
 if(E3d_HideToggleSelectedMenuButton!=NULL) EGUI_DestroyItem(E3d_HideToggleSelectedMenuButton);
 if(E3d_HideSelectedMenuButton!=NULL) EGUI_DestroyItem(E3d_HideSelectedMenuButton);
 if(E3d_HideUnselectedMenuButton!=NULL) EGUI_DestroyItem(E3d_HideUnselectedMenuButton);
 if(E3dp_UnHideSelectionMenuButton!=NULL) EGUI_DestroyItem(E3dp_UnHideSelectionMenuButton);
 if(E3dp_UnHideAllMenuButton!=NULL) EGUI_DestroyItem(E3dp_UnHideAllMenuButton);

 if(E3dp_ShowHotKeysMenuButton!=NULL) EGUI_DestroyItem(E3dp_ShowHotKeysMenuButton);

 return(0);
}
