/*
-----------------------------------------------------------------------------
This source file is part of OpenSpace3D
For the latest info, see http://www.openspace3d.com

Copyright (c) 2012 I-maginer

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt

-----------------------------------------------------------------------------
*/

struct PlugHide = [
  HIDE_shell                 : SO3_OBJECT,
  HIDE_sons                  : I,
  HIDE_bDisableBody          : I,
  HIDE_bState                : I

  ]mkPlugHide;;


fun setBodiesIgnoreState(l, state, sons)=
  if l == nil then nil else
  let hd l -> obj in
  let SO3SceneNodeGetBody obj -> body in
  (
    if (!sons) then nil else
    (
      //apply on bones too
      setBodiesIgnoreState (SO3GetRootBonesFromMesh obj) state sons;     
      setBodiesIgnoreState (SO3ObjectGetChildren obj) state sons;
    );
    
    SO3BodySetIgnoreCollision body state;
    
    if (!state) then nil else
    (
      SO3BodySetVelocity body [0.0 0.0 0.0];
      SO3BodySetOmega body [0.0 0.0 0.0];
      SO3BodySetFreeze body 1;
    );
    
    setBodiesIgnoreState (tl l) state sons;
  );
  0;;


fun deleteOb(inst, hidestr)=
  SO3ObjectSetVisible hidestr.HIDE_shell 1 hidestr.HIDE_sons;
  
  if (!hidestr.HIDE_bDisableBody) then nil else
    setBodiesIgnoreState hidestr.HIDE_shell::nil 0 hidestr.HIDE_sons;
  0;;


fun hideObject(inst, from, action, param, rep, hidestr) =
  set hidestr.HIDE_bState = 0;
  SO3ObjectSetVisible hidestr.HIDE_shell 0 hidestr.HIDE_sons;
  
  if (!hidestr.HIDE_bDisableBody) then nil else
    setBodiesIgnoreState hidestr.HIDE_shell::nil 1 hidestr.HIDE_sons;
    
  SendPluginEvent inst "Hidden" param nil;
  0;;


fun showObject(inst, from, action, param, rep, hidestr) =
  set hidestr.HIDE_bState = 1;
  SO3ObjectSetVisible hidestr.HIDE_shell 1 hidestr.HIDE_sons;
  
  if (!hidestr.HIDE_bDisableBody) then nil else
    setBodiesIgnoreState hidestr.HIDE_shell::nil 0 hidestr.HIDE_sons;
    
  SendPluginEvent inst "Shown" param nil;
  0;;


fun newOb(inst)=
  let (getPluginInstanceParam inst "object") -> objname in
  let atoi (getPluginInstanceParam inst "sons") -> sons in
  let atoi (getPluginInstanceParam inst "disablebody") -> disablebody in
  let if disablebody == nil then 0 else disablebody -> disablebody in
  let atoi (getPluginInstanceParam inst "enable") -> hidestate in
  let SO3SceneGetObject (V3DgetSession c3dXsession) objname -> obj in
  if obj == nil then nil else
  let mkPlugHide [obj sons disablebody 1] -> hidestr in
  (
	  PluginRegisterAction inst "Hide" mkfun6 @hideObject hidestr;
	  PluginRegisterAction inst "Show" mkfun6 @showObject hidestr;
    
    if !hidestate then nil else
    (
      hideObject inst nil nil nil nil hidestr;
    );
    
    setPluginInstanceCbDel inst mkfun2 @deleteOb hidestr;
  );
  0;;


fun IniPlug(file)=
  PlugRegister @newOb nil;
  setPluginEditor @dynamicedit;
  0;;