void Dialog::OnEvidenceSelectorClosing(EvidenceSelector *pSender)
{
    Confrontation *pConfrontation = pState->GetCurrentConfrontation();

    if (pConfrontation != NULL)
    {
        pConfrontation->ShowHealthIcons();
    }
}
bool Dialog::HandleClick()
{
    // If this dialog is automatic or static, then we'll ignore every click.
    if (GetIsAutomatic() || isStatic)
    {
        return false;
    }

    if (isInterrogation && !pEvidenceSelector->GetIsShowing() && !pState->WasInterjectionOngoing())
    {
        if (!isPassive)
        {
            pPressForInfoTab->Update();
            pPresentEvidenceTab->Update();

            if (Case::GetInstance()->GetPartnerManager()->GetCurrentPartnerId().length() > 0 && pCurrentPartner->GetConversationAbilityName().length() > 0)
            {
                pUsePartnerTab->Update();
            }
        }

        if (!isConfrontation || Confrontation::GetEnabledConfrontationTopicCount() > 1)
        {
            pEndInterrogationTab->Update();
        }

        pInterrogationUpArrow->UpdateState();
        pInterrogationDownArrow->UpdateState();
    }
    else if (pEvidenceSelector->GetIsShowing())
    {
        pEvidenceSelector->UpdateState();
        return true;
    }
    else if (presentEvidenceAutomatically && !pEvidenceSelector->GetIsShowing() && GetIsReadyToProgress())
    {
        // If the evidence selector is being shown automatically, is not presently showing,
        // and if the dialog is ready to progress, then the user must've canceled.
        // We'll ignore clicks in this case, since we're about to exit.
        return true;
    }

    if (!GetIsReadyToProgress())
    {
        //SetTextSkipped(true);
        Finish();
        return true;
    }
    else if (
        pPressForInfoTab->GetIsClicked() ||
        pPresentEvidenceTab->GetIsClicked() ||
        pUsePartnerTab->GetIsClicked() ||
        pEndInterrogationTab->GetIsClicked() ||
        pInterrogationUpArrow->GetIsClicked() ||
        pInterrogationDownArrow->GetIsClicked())
    {
        if (pPressForInfoTab->GetIsClicked())
        {
            if (filePath.length() > 0 && gVoiceVolume > 0)
            {
                stopDialog();
            }

            Finish();
            OnPressForInfoClicked();
            pPressForInfoTab->SetIsClicked(false);
        }
        else if (pPresentEvidenceTab->GetIsClicked())
        {
            pEvidenceSelector->Begin();
            pEvidenceSelector->Show();

            Confrontation *pConfrontation = pState->GetCurrentConfrontation();

            if (pConfrontation != NULL)
            {
                pConfrontation->HideHealthIcons();
            }

            pPresentEvidenceTab->SetIsClicked(false);
        }
        else if (pUsePartnerTab->GetIsClicked())
        {
            if (filePath.length() > 0 && gVoiceVolume > 0)
            {
                stopDialog();
            }

            Finish();
            OnUsePartnerClicked();
            pUsePartnerTab->SetIsClicked(false);
        }
        else if (pEndInterrogationTab->GetIsClicked())
        {
            if (filePath.length() > 0 && gVoiceVolume > 0)
            {
                stopDialog();
            }

            Finish();
            OnEndRequested();
            pEndInterrogationTab->SetIsClicked(false);
        }
        else if (pInterrogationUpArrow->GetIsClicked())
        {
            if (filePath.length() > 0 && gVoiceVolume > 0)
            {
                stopDialog();
            }

            Finish();
            OnDirectlyNavigated(DirectNavigationDirectionBack);
            pInterrogationUpArrow->SetIsClicked(false);
        }
        else if (pInterrogationDownArrow->GetIsClicked())
        {
            if (filePath.length() > 0 && gVoiceVolume > 0)
            {
                stopDialog();
            }

            Finish();
            OnDirectlyNavigated(DirectNavigationDirectionForward);
            pInterrogationDownArrow->SetIsClicked(false);
        }

        return true;
    }

    return false;
}
void Dialog::Update(int delta)
{
    bool newCharacterDrawn = false;

    double lastCurrentTime = currentTime;
    currentTime += delta;

    // If we're now ready to play the dialog, do so.
    if (timeBeforeDialog >= lastCurrentTime && timeBeforeDialog < currentTime)
    {
        if (filePath.length() > 0 && gVoiceVolume > 0 && !GetIsFinished())
        {
            playDialog(filePath);
        }
    }

    if (!dialogEventIteratorSet && !dialogEventList.empty())
    {
        dialogEventIterator = dialogEventList.begin();
        pCurrentDialogEvent = *dialogEventIterator;
        ++dialogEventIterator;
        dialogEventIteratorSet = true;
    }

    if (!GetIsPaused())
    {
        lastPausePosition = -1;

        if (!GetIsFinished())
        {
            millisecondsSinceLastUpdate += delta;

            if (!GetIsStarted() || millisecondsSinceLastUpdate > millisecondsPerCharacterUpdate)
            {
                int positionsToAdvance = (int)(millisecondsSinceLastUpdate / millisecondsPerCharacterUpdate);
                try
                {
                    string::const_iterator begin = GetText().begin() + curTextPosition;
                    string::const_iterator end = begin;
                    utf8::advance(end, positionsToAdvance, GetText().end());
                    curTextPosition = curTextPosition + distance(begin, end);
                }
                catch (utf8::not_enough_room ex)
                {
                    curTextPosition = (int)GetText().length();
                }

                millisecondsSinceLastUpdate = max(millisecondsSinceLastUpdate - positionsToAdvance * millisecondsPerCharacterUpdate, 0.0);
                newCharacterDrawn = true;
            }
        }
    }
    else
    {
        millisecondsSinceLastUpdate = 0;
        millisecondsUntilPauseCompletes -= delta;
        millisecondsUntilAudioPauseCompletes -= delta;

        if (millisecondsUntilPauseCompletes < 0)
        {
            // Account for going over by adding the amount we went over
            // to the milliseconds since we updated,
            // such that we'll update sooner if we went over.
            millisecondsSinceLastUpdate += -millisecondsUntilPauseCompletes;
            millisecondsUntilPauseCompletes = 0;
        }

        if (millisecondsUntilAudioPauseCompletes < 0)
        {
            millisecondsUntilAudioPauseCompletes = 0;
        }
    }

    if (!GetIsPaused() && pCurrentDialogEvent != NULL)
    {
        while (curTextPosition >= pCurrentDialogEvent->GetPosition())
        {
            int eventPosition = pCurrentDialogEvent->GetPosition();
            pCurrentDialogEvent->RaiseEvent();

            if (dialogEventIterator != dialogEventList.end())
            {
                pCurrentDialogEvent = *dialogEventIterator;
                ++dialogEventIterator;
            }
            else
            {
                pCurrentDialogEvent = NULL;
            }

            if (GetIsPaused() || pCurrentDialogEvent == NULL)
            {
                if (GetIsPaused())
                {
                    lastPausePosition = eventPosition;
                }

                break;
            }
        }
    }

    // We'll only play the letter blips if voice acting isn't enabled.
    if (gVoiceVolume <= 0 && !GetIsReadyToProgress())
    {
        timeSinceLetterBlipPlayed += delta;

        if (newCharacterDrawn && timeSinceLetterBlipPlayed > 50)// TODO letterBlipSoundEffect.Duration.TotalMilliseconds)
        {
            playSound(LetterBlipSoundEffect);
            timeSinceLetterBlipPlayed = 0;
        }
    }

    if (GetIsReadyToProgress())
    {
        if (presentEvidenceAutomatically && !pEvidenceSelector->GetIsShowing())
        {
            if (!evidenceSelectorShownOnce)
            {
                pEvidenceSelector->Show();
                evidenceSelectorShownOnce = true;

                Confrontation *pConfrontation = pState->GetCurrentConfrontation();

                if (pConfrontation != NULL)
                {
                    pConfrontation->HideHealthIcons();
                }
            }
            else
            {
                if (!evidencePresented)
                {
                    // If the evidence selector isn't showing and it was shown once,
                    // and if no evidence has been shown, then the player must've
                    // clicked Cancel, so we'll end the conversation here
                    // since progress depends on presenting the right evidence.
                    OnEndRequested();
                }

                endRequested = true;
            }
        }
        else if (!presentEvidenceAutomatically)
        {
            endRequested = true;
        }

        if (isInterrogation)
        {
            if (pEvidenceSelector->GetIsShowing())
            {
                pEvidenceSelector->Update(delta);
            }
            else if (!pState->WasInterjectionOngoing())
            {
                if (!isPassive)
                {
                    pPressForInfoTab->Update();
                    pPresentEvidenceTab->Update();

                    if (Case::GetInstance()->GetPartnerManager()->GetCurrentPartnerId().length() > 0 && pCurrentPartner->GetConversationAbilityName().length() > 0)
                    {
                        pUsePartnerTab->Update();
                    }
                }

                if (!isConfrontation || Confrontation::GetEnabledConfrontationTopicCount() > 1)
                {
                    pEndInterrogationTab->Update();
                }

                pInterrogationUpArrow->Update(delta);
                pInterrogationDownArrow->Update(delta);
            }
        }
        else
        {
            if (pEvidenceSelector->GetIsShowing())
            {
                pEvidenceSelector->Update(delta);
            }
            else if (!GetIsAutomatic() && !isStatic)
            {
                pConversationDownArrow->Update(delta);
            }
        }
    }

    if (isInterrogation && !pState->WasInterjectionOngoing())
    {
        if (!isPassive)
        {
            pPressForInfoTab->SetIsEnabled(GetIsReadyToProgress());
            pPresentEvidenceTab->SetIsEnabled(GetIsReadyToProgress() && Case::GetInstance()->GetEvidenceManager()->GetHasEvidence());

            if (Case::GetInstance()->GetPartnerManager()->GetCurrentPartnerId().length() > 0 && pCurrentPartner->GetConversationAbilityName().length() > 0)
            {
                pUsePartnerTab->SetIsEnabled(GetIsReadyToProgress());
            }
        }

        if (!isConfrontation || Confrontation::GetEnabledConfrontationTopicCount() > 1)
        {
            pEndInterrogationTab->SetIsEnabled(GetIsReadyToProgress());
        }
    }
}
void Encounter::RefreshButtonArrayContents()
{
    vector<ButtonArrayLoadParameters> loadParametersList;

    for (unsigned int i = 0; i < conversationList.size(); i++)
    {
        Conversation *pConversation = conversationList[i];

        if (pConversation->GetIsEnabled())
        {
            ButtonArrayLoadParameters loadParameters;

            loadParameters.text = pConversation->GetName();

            if (pConversation->GetIsLocked())
            {
                loadParameters.lockCount = pConversation->GetLockCount();
            }

            loadParameters.unlockedLockCount = 0;

            vector<Conversation::UnlockCondition *> *pUnlockConditions = pConversation->GetUnlockConditions();

            for (unsigned int i = 0; i < pUnlockConditions->size(); i++)
            {
                Conversation::UnlockCondition *pUnlockCondition = (*pUnlockConditions)[i];

                if (pUnlockCondition->GetIsConditionMet() && !pUnlockCondition->GetHasHandledMetCondition())
                {
                    loadParameters.unlockedLockCount++;
                    pUnlockCondition->SetHasHandledMetCondition(true);
                }
            }

            loadParameters.showCheckBox = pConversation->GetHasBeenCompleted();

            loadParametersList.push_back(loadParameters);
        }
    }

    for (unsigned int i = 0; i < interrogationList.size(); i++)
    {
        Interrogation *pInterrogation = interrogationList[i];

        if (!pInterrogation->GetHasBeenCompleted())
        {
            if (pInterrogation->GetIsEnabled())
            {
                ButtonArrayLoadParameters loadParameters;

                char text[256];
                snprintf(text, 256, gpLocalizableContent->GetText("Encounter/InterrogationDesignationFormatText").c_str(), pInterrogation->GetName().c_str());

                loadParameters.text = string(text);
                loadParametersList.push_back(loadParameters);
            }
        }
    }

    for (unsigned int i = 0; i < confrontationList.size(); i++)
    {
        Confrontation *pConfrontation = confrontationList[i];

        if (!pConfrontation->GetHasBeenCompleted())
        {
            if (pConfrontation->GetIsEnabled())
            {
                ButtonArrayLoadParameters loadParameters;

                char text[256];
                snprintf(text, 256, gpLocalizableContent->GetText("Encounter/ConfrontationDesignationFormatText").c_str(), pConfrontation->GetName().c_str());

                loadParameters.text = string(text);
                loadParametersList.push_back(loadParameters);
            }
        }
    }

    pMainMenuButtonArray->Load(loadParametersList);
    pPresentEvidenceTab->SetIsEnabled(Case::GetInstance()->GetEvidenceManager()->GetHasEvidence());
}
void DialogCharacterManager::UpdateForState(State *pState, int delta)
{
    if (pState->GetBreakdownTransitionStarted() && !pFlashSpriteOpacityEaseIn->GetIsStarted())
    {
        pState->SetBreakdownTransitionStarted(false);
        pFlashSpriteOpacityEaseIn->Begin();
        pFlashSpriteOpacityEaseOut->Reset();
        playSound("BreakdownSwish");
    }

    if (pFlashSpriteOpacityEaseIn->GetIsStarted() && !pFlashSpriteOpacityEaseIn->GetIsFinished())
    {
        pFlashSpriteOpacityEaseIn->Update(delta);
        flashSpriteOpacity = pFlashSpriteOpacityEaseIn->GetCurrentValue();

        if (pFlashSpriteOpacityEaseIn->GetIsFinished())
        {
            if (pState->GetBreakdownActivePosition() != CharacterPositionNone)
            {
                string characterId =
                    pState->GetBreakdownActivePosition() == CharacterPositionLeft ?
                    pState->GetLeftCharacterId() :
                    pState->GetRightCharacterId();

                pBreakdownVideo = characterByIdMap[characterId]->GetBreakdownVideo();
                pBreakdownVideo->Begin();
                pFlashSpriteOpacityEaseOut->Begin();

                Confrontation *pConfrontation = pState->GetCurrentConfrontation();

                if (pConfrontation != NULL)
                {
                    pConfrontation->HideHealthIcons();
                }
            }
            else
            {
                pBreakdownVideo = NULL;
                pFlashSpriteOpacityEaseOut->Begin();
            }
        }
    }

    if (pFlashSpriteOpacityEaseOut->GetIsStarted() && !pFlashSpriteOpacityEaseOut->GetIsFinished())
    {
        pFlashSpriteOpacityEaseOut->Update(delta);
        flashSpriteOpacity = pFlashSpriteOpacityEaseOut->GetCurrentValue();

        if (pFlashSpriteOpacityEaseOut->GetIsFinished())
        {
            pFlashSpriteOpacityEaseIn->Reset();
            pState->SetBreakdownTransitionComplete(true);
        }
    }

    if (pBreakdownVideo == NULL)
    {
        string leftCharacterEmotionId = pState->GetLeftCharacterEmotionId();
        string leftReplacementCharacterEmotionId = pState->GetLeftReplacementCharacterEmotionId();
        string rightCharacterEmotionId = pState->GetRightCharacterEmotionId();
        string rightReplacementCharacterEmotionId = pState->GetRightReplacementCharacterEmotionId();

        if (pState->GetIsLeftCharacterZoomed() || pState->GetIsRightCharacterZoomed())
        {
            if (!isShowingSpeedLines)
            {
                isShowingSpeedLines = true;

                if (pSpeedLinesVideo == NULL)
                {
                    pSpeedLinesVideo = CommonCaseResources::GetInstance()->GetAnimationManager()->GetVideoFromId("SpeedLines");
                }

                pSpeedLinesVideo->Begin();
            }
            else
            {
                pSpeedLinesVideo->Update(delta);
            }
        }
        else
        {
            isShowingSpeedLines = false;
        }

        if (pState->GetIsLeftCharacterZoomed())
        {
            string zoomEmotion = "Zoom";

            Update(pState->GetLeftCharacterId(), leftCharacterEmotionId, delta, pState->GetIsFinishingDialog(), true /* isInBackground */);
            Update(pState->GetLeftCharacterId(), zoomEmotion, delta, pState->GetIsFinishingDialog());
        }
        else
        {
            Update(pState->GetLeftCharacterId(), leftCharacterEmotionId, delta, pState->GetIsFinishingDialog());
        }

        Update(pState->GetLeftReplacementCharacterId(), leftReplacementCharacterEmotionId, delta, pState->GetIsFinishingDialog());

        if (pState->GetIsRightCharacterZoomed())
        {
            string zoomEmotion = "Zoom";

            Update(pState->GetRightCharacterId(), rightCharacterEmotionId, delta, pState->GetIsFinishingDialog(), true /* isInBackground */);
            Update(pState->GetRightCharacterId(), zoomEmotion, delta, pState->GetIsFinishingDialog());
        }
        else
        {
            Update(pState->GetRightCharacterId(), rightCharacterEmotionId, delta, pState->GetIsFinishingDialog());
        }

        Update(pState->GetRightReplacementCharacterId(), rightReplacementCharacterEmotionId, delta, pState->GetIsFinishingDialog());

        if (leftCharacterEmotionId != pState->GetLeftCharacterEmotionId())
        {
            pState->SetLeftCharacterEmotionId(leftCharacterEmotionId);
        }

        if (leftReplacementCharacterEmotionId != pState->GetLeftReplacementCharacterEmotionId())
        {
            pState->SetLeftReplacementCharacterEmotionId(leftReplacementCharacterEmotionId);
        }

        if (rightCharacterEmotionId != pState->GetRightCharacterEmotionId())
        {
            pState->SetRightCharacterEmotionId(rightCharacterEmotionId);
        }

        if (rightReplacementCharacterEmotionId != pState->GetRightReplacementCharacterEmotionId())
        {
            pState->SetRightReplacementCharacterEmotionId(rightReplacementCharacterEmotionId);
        }

        if (pState->GetIsInterjectionOngoing())
        {
            pState->UpdateInterjection(delta);
        }
    }
    else if (pFlashSpriteOpacityEaseOut->GetIsFinished())
    {
        pBreakdownVideo->Update(delta);
    }
}