void VTimeOfDayComponent::UpdateParent()
{
  IVTimeOfDay *pTimeOfDayInterface = Vision::Renderer.GetTimeOfDayHandler();
  if (pTimeOfDayInterface == NULL)
    return;

  VisObject3D_cl *pOwnerObject = (VisObject3D_cl *)m_pOwner;
  VASSERT(pOwnerObject);

  hkvVec3 vDirection(hkvNoInitialization);
  pTimeOfDayInterface->GetSunDirection(vDirection);
  vDirection.normalizeIfNotZero();

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE)
  {
    vDirection = -vDirection; 
  }
  else if(AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE)
  {
    vDirection.x = -vDirection.x;
    vDirection.y = -vDirection.y;
  }
  
  if (AttachmentType != TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE)
  {
    pOwnerObject->SetDirection(vDirection);
  }

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
  {
    // TODO (multiple renderer nodes)
    IVRendererNode *pRenderer = Vision::Renderer.GetRendererNode(0);
    float fNear, fFar;
    pRenderer->GetReferenceContext()->GetClipPlanes(fNear, fFar);
    hkvVec3 vCamPos = pRenderer->GetReferenceContext()->GetCamera()->GetPosition();

    hkvVec3 vCoronaPos = -vDirection;
    vCoronaPos *= 0.95f * fFar;
    vCoronaPos += vCamPos;
    pOwnerObject->SetPosition(vCoronaPos);
  }

  if (m_bIsLightClass)
  {
    VisLightSource_cl *pLight = (VisLightSource_cl*)m_pOwner;
    VColorRef sunColor = pTimeOfDayInterface->GetSunColor();

    bool bSwitchable = (AttachmentType == TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE);
    float fBelowHorizonMultiplier = hkvMath::pow (hkvMath::Max(-vDirection.z+0.1f, 0.0f), bSwitchable ? 1.0f : 0.1f);
    fBelowHorizonMultiplier = hkvMath::Min(1.0f, fBelowHorizonMultiplier);

    if (bSwitchable && fBelowHorizonMultiplier < 1.0f && fBelowHorizonMultiplier > 0.f)
    {
      pLight->SetColor(m_iColor);
      pLight->SetMultiplier(Intensity * (1.0f - fBelowHorizonMultiplier));
    }
    else if (AttachmentType == TIMEOFDAY_ATTACHMENT_SUNLIGHTSOURCE)
    {
      pLight->SetColor(sunColor);
      pLight->SetMultiplier(Intensity * fBelowHorizonMultiplier);
    }
    else if ((AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE) ||
             (AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE))
    {
      // TODO
      VColorRef negativeColor = V_RGBA_WHITE - sunColor;
      pLight->SetColor(negativeColor);
      pLight->SetMultiplier(Intensity * fBelowHorizonMultiplier * 0.333f);
    }  
    else if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
    {
      hkvVec3 vSunColorFloat = sunColor.ToFloat();
      float fLargestComponent = hkvMath::Max(hkvMath::Max(vSunColorFloat.x, vSunColorFloat.y), vSunColorFloat.z);
      if (fLargestComponent <= 0.0f)
        fLargestComponent = 1.0f;
      sunColor.FromFloat(vSunColorFloat * (1.0f / fLargestComponent));

      pLight->SetColor(sunColor * fBelowHorizonMultiplier);
      pLight->SetMultiplier(0.0f);
    }
  }
}
void VTimeOfDayComponent::UpdateParent()
{
  VTimeOfDay *pTimeOfDayInterface = (VTimeOfDay*)Vision::Renderer.GetTimeOfDayHandler();
  if (pTimeOfDayInterface == NULL)
    return;

  VisObject3D_cl *pOwnerObject = (VisObject3D_cl *)m_pOwner;
  VASSERT(pOwnerObject);

  hkvVec3 vDirection(hkvNoInitialization);
  pTimeOfDayInterface->GetSunDirection(vDirection);

  // The Moon and back light direction is calculated from the Sun direction
  if (AttachmentType == TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE)
  {
    vDirection = -vDirection; 
  }
  else if(AttachmentType == TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE)
  {
    vDirection.x = -vDirection.x;
    vDirection.y = -vDirection.y;
  }
  
  if (AttachmentType != TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE)
  {
    pOwnerObject->SetDirection(vDirection);
  }

  if (AttachmentType == TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE)
  {
    // TODO (multiple renderer nodes)
    IVRendererNode *pRenderer = Vision::Renderer.GetRendererNode(0);
    float fNear, fFar;
    pRenderer->GetReferenceContext()->GetClipPlanes(fNear, fFar);
    hkvVec3 vCamPos = pRenderer->GetReferenceContext()->GetCamera()->GetPosition();

    hkvVec3 vCoronaPos = -vDirection;
    vCoronaPos *= 0.95f * fFar;
    vCoronaPos += vCamPos;
    pOwnerObject->SetPosition(vCoronaPos);
  }

  // Set the color and intensity of the light
  if (m_bIsLightClass)
  {
    VisLightSource_cl *pLight = (VisLightSource_cl*)m_pOwner;
    VColorRef color;
    float intensity = 0.0f;

    switch (AttachmentType)
    {
    case TIMEOFDAY_ATTACHMENT_ENABLEDATNIGHTLIGHTSOURCE:
      {
        color = m_iColor;
        const float fMarginNearHorizon = 0.1f; //10% - Margin above the horizon to switch lights ON/OFF
        const float fBelowHorizonMultiplier = hkvMath::Max(-vDirection.z + fMarginNearHorizon, 0.0f);
        intensity = 1.0f - hkvMath::Min(1.0f, fBelowHorizonMultiplier);
        break;
      }
    case TIMEOFDAY_ATTACHMENT_CORONALIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetSunColor();
        hkvVec3 vSunColorFloat = color.ToFloat();
        float fLargestComponent = hkvMath::Max(hkvMath::Max(vSunColorFloat.x, vSunColorFloat.y), vSunColorFloat.z);
        if (fLargestComponent > 0.0f)
        {
          color.FromFloat(vSunColorFloat / fLargestComponent);
        }      
        intensity = 0.0f;
        break;
      }
    case TIMEOFDAY_ATTACHMENT_SUNLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetSunColor();
        intensity = pTimeOfDayInterface->GetSunIntensity();
        break;
      }
    case TIMEOFDAY_ATTACHMENT_SUNBACKLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetBackLightColor();
        intensity = pTimeOfDayInterface->GetBackLightIntensity();
        break;
      }
    case TIMEOFDAY_ATTACHMENT_MOONLIGHTSOURCE:
      {
        color = pTimeOfDayInterface->GetMoonColor();
        intensity = pTimeOfDayInterface->GetMoonIntensity();
        break;
      }
    default:
      VASSERT_MSG(0,"Unknown time of day attachment type");
    }

    pLight->SetColor(color);
    pLight->SetMultiplier(intensity * Intensity);    
  }
}