#ifndef RF_SPLIT_UTIL_SURV_H
#define RF_SPLIT_UTIL_SURV_H
#include "node.h"
void stackAndGetSplitSurv(uint    treeID,
                          Node    *parent,
                          char    eventType,
                          uint  **eventTimeCount,
                          uint  **eventTimeIndex,
                          uint   *eventTimeSize,
                          uint  **parentEvent,
                          uint  **parentAtRisk,
                          uint  **leftEvent,
                          uint  **leftAtRisk,
                          uint  **rightEvent,
                          uint  **rightAtRisk);
void unstackSplitSurv(uint    treeID,
                      Node    *parent,
                      uint *eventTimeCount,
                      uint *eventTimeIndex,
                      uint  eventTimeSize,
                      uint *parentEvent,
                      uint *parentAtRisk,
                      uint *leftEvent,
                      uint *leftAtRisk,
                      uint *rightEvent,
                      uint *rightAtRisk);
void stackSplitSurv3(uint    treeID,
                     Node    *parent,
                     uint   eventTimeSize,
                     double **leftLocalRatio,
                     double **rightLocalRatio,
                     double **leftLocalSurvival,
                     double **rightLocalSurvival,
                     uint   revEventTimeSize,
                     double **leftRevLocalRatio,
                     double **rightRevLocalRatio,
                     double **leftRevLocalSurvival,
                     double **rightRevLocalSurvival,
                     double **leftBS,
                     double **rightBS);
void unstackSplitSurv3(uint    treeID,
                       Node    *parent,
                       uint   eventTimeSize,
                       double *leftLocalRatio,
                       double *rightLocalRatio,
                       double *leftLocalSurvival,
                       double *rightLocalSurvival,
                       uint   revEventTimeSize,
                       double *leftRevLocalRatio,
                       double *rightRevLocalRatio,
                       double *leftRevLocalSurvival,
                       double *rightRevLocalSurvival,
                       double *leftBS,
                       double *rightBS);
uint getEventTime(uint   treeID,
                  Node   *parent,                  
                  uint   *repMembrIndx,
                  uint    repMembrSize,
                  uint   *nonMissMembrIndx,
                  uint    nonMissMembrSize,
                  char    eventType,
                  uint   *eventTimeCount,
                  uint   *eventTimeIndex);
void stackSplitEventAndRisk(uint    treeID,
                            Node    *parent,
                            uint    genEventTimeSize,
                            uint  **genParentEvent,
                            uint  **genParentAtRisk,
                            uint  **genLeftEvent,
                            uint  **genLeftAtRisk,
                            uint  **genRightEvent,
                            uint  **genRightAtRisk);
void unstackSplitEventAndRisk(uint    treeID,
                              Node    *parent,
                              uint    eventTimeSize,
                              uint   *genParentEvent,
                              uint   *genParentAtRisk,
                              uint   *genLeftEvent,
                              uint   *genLeftAtRisk,
                              uint   *genRightEvent,
                              uint   *genRightAtRisk);
void getSplitEventAndRisk(uint    treeID,
                          Node    *parent,
                          uint   *repMembrIndx,
                          uint    repMembrSize,
                          uint   *nonMissMembrIndx,
                          uint    nonMissMembrSize,
                          uint   *eventTimeCount,
                          uint   *eventTimeIndex,
                          uint    eventTimeSize,
                          uint   *parentEvent,
                          uint   *parentAtRisk);
void stackAndGetSplitSurv2(uint     treeID,
                           Node    *parent,
                           uint     eventTimeSize,
                           uint    *nodeParentEvent,
                           uint    *nodeParentAtRisk,
                           double **localSurvival);
void unstackAndGetSplitSurv2(uint     treeID,
                             Node    *parent,
                             uint     eventTimeSize,
                             double  *localSurvival);
void stackAndGetFZhat(uint  treeID,
                      Node *parent,
                      uint *repMembrIndx,
                      uint  repMembrSize,
                      uint *nonMissMembrIndx,
                      uint  nonMissMembrSize,
                      uint *eventTimeIndex,
                      uint  eventTimeSize,
                      uint *revEventTimeIndex,
                      uint  revEventTimeSize,
                      double *revParentSurvival,
                      double **fZHat);
void unstackFZhat(uint  treeID,
                  Node *parent,
                  uint  eventTimeSize,
                  double *fZHat);
void stackAndGetFZhatNew(uint  treeID,
                         Node *parent,
                         uint *repMembrIndx,
                         uint  repMembrSize,
                         uint *nonMissMembrIndx,
                         uint  nonMissMembrSize,
                         uint *eventTimeIndex,
                         uint  eventTimeSize,
                         uint *revEventTimeIndex,
                         uint  revEventTimeSize,
                         double *revParentSurvival,
                         double **gHat,
                         double **fZHat);
double getW_kt(uint  treeID,
               Node *parent,
               uint  indv,
               uint  tIndx,
               uint *eventTimeIndex,
               uint *revEventTimeIndex,
               uint  revEventTimeSize,
               double *revParentSurvival,
               double *gHatPrevious,
               double *gHatCurrent);
void stackAndGetQTime(uint  treeID,
                      Node *parent,
                      uint  eventTimeSize,
                      double *survival,
                      uint  **quantileTime);
void unstackQTime(uint  *quantileTime);
void stackAndGetQETime(uint   treeID,
                       Node  *parent,
                       uint  *eventTimeIndex,                       
                       uint   eventTimeSize,
                       double *survival,
                       uint  **qeTimeIndex,
                       uint   *qeTimeSize);
void unstackQETime(uint treeID,
                   uint eventTimeSize,
                   uint  *qeTimeIndex);
void stackAndGetLocalGamma(uint  treeID,
                             Node *parent,
                             uint *repMembrIndx,
                             uint  repMembrSize,
                             uint *nonMissMembrIndx,
                             uint  nonMissMembrSize,
                             uint *eventTimeIndex,
                             uint  eventTimeSize,
                             uint *revEventTimeIndex,
                             uint  revEventTimeSize,
                             double *revParentSurvival,
                           uint      *qeTimeIndex,
                           uint       qeTimeSize,
                           double   **gHat,
                             double  ***w_ktm,
                             double  ***gamma_ktm);
void  unstackLocalGamma(uint    treeID,
                        uint    nonMissMembrSize,
                        uint   *eventTimeIndex,
                        uint    eventTimeSize,
                           uint      *qeTimeIndex,
                        uint       qeTimeSize,
                        double **gamma_ktm);
#endif
