// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/ash_touch_exploration_manager_chromeos.h"

#include "ash/accessibility_delegate.h"
#include "ash/root_window_controller.h"
#include "ash/shared/app_types.h"
#include "ash/shell.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/wm/window_util.h"
#include "ash/wm_window.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "chromeos/audio/chromeos_sounds.h"
#include "chromeos/audio/cras_audio_handler.h"
#include "chromeos/chromeos_switches.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/chromeos/touch_exploration_controller.h"
#include "ui/wm/public/activation_client.h"

namespace ash {

AshTouchExplorationManager::AshTouchExplorationManager(
    RootWindowController* root_window_controller)
    : root_window_controller_(root_window_controller),
      audio_handler_(chromeos::CrasAudioHandler::Get()),
      enable_chromevox_arc_support_(
          base::CommandLine::ForCurrentProcess()->HasSwitch(
              chromeos::switches::kEnableChromeVoxArcSupport)) {
  Shell::Get()->system_tray_notifier()->AddAccessibilityObserver(this);
  Shell::Get()->activation_client()->AddObserver(this);
  display::Screen::GetScreen()->AddObserver(this);
  UpdateTouchExplorationState();
}

AshTouchExplorationManager::~AshTouchExplorationManager() {
  SystemTrayNotifier* system_tray_notifier =
      Shell::Get()->system_tray_notifier();
  if (system_tray_notifier)
    system_tray_notifier->RemoveAccessibilityObserver(this);
  Shell::Get()->activation_client()->RemoveObserver(this);
  display::Screen::GetScreen()->RemoveObserver(this);
}

void AshTouchExplorationManager::OnAccessibilityModeChanged(
    AccessibilityNotificationVisibility notify) {
  UpdateTouchExplorationState();
}

void AshTouchExplorationManager::SetOutputLevel(int volume) {
  if (volume > 0) {
    if (audio_handler_->IsOutputMuted()) {
      audio_handler_->SetOutputMute(false);
    }
  }
  audio_handler_->SetOutputVolumePercent(volume);
  // Avoid negative volume.
  if (audio_handler_->IsOutputVolumeBelowDefaultMuteLevel())
    audio_handler_->SetOutputMute(true);
}

void AshTouchExplorationManager::SilenceSpokenFeedback() {
  if (Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled())
    Shell::Get()->accessibility_delegate()->SilenceSpokenFeedback();
}

void AshTouchExplorationManager::PlayVolumeAdjustEarcon() {
  if (!VolumeAdjustSoundEnabled())
    return;
  if (!audio_handler_->IsOutputMuted() &&
      audio_handler_->GetOutputVolumePercent() != 100) {
    Shell::Get()->accessibility_delegate()->PlayEarcon(
        chromeos::SOUND_VOLUME_ADJUST);
  }
}

void AshTouchExplorationManager::PlayPassthroughEarcon() {
  Shell::Get()->accessibility_delegate()->PlayEarcon(
      chromeos::SOUND_PASSTHROUGH);
}

void AshTouchExplorationManager::PlayExitScreenEarcon() {
  Shell::Get()->accessibility_delegate()->PlayEarcon(
      chromeos::SOUND_EXIT_SCREEN);
}

void AshTouchExplorationManager::PlayEnterScreenEarcon() {
  Shell::Get()->accessibility_delegate()->PlayEarcon(
      chromeos::SOUND_ENTER_SCREEN);
}

void AshTouchExplorationManager::HandleAccessibilityGesture(
    ui::AXGesture gesture) {
  Shell::Get()->accessibility_delegate()->HandleAccessibilityGesture(gesture);
}

void AshTouchExplorationManager::OnDisplayMetricsChanged(
    const display::Display& display,
    uint32_t changed_metrics) {
  if (root_window_controller_->GetWindow()->GetDisplayNearestWindow().id() ==
      display.id())
    UpdateTouchExplorationState();
}

void AshTouchExplorationManager::OnTwoFingerTouchStart() {
  AccessibilityDelegate* delegate = Shell::Get()->accessibility_delegate();
  delegate->OnTwoFingerTouchStart();
}

void AshTouchExplorationManager::OnTwoFingerTouchStop() {
  AccessibilityDelegate* delegate = Shell::Get()->accessibility_delegate();
  delegate->OnTwoFingerTouchStart();
}

void AshTouchExplorationManager::PlaySpokenFeedbackToggleCountdown(
    int tick_count) {
  AccessibilityDelegate* delegate = Shell::Get()->accessibility_delegate();
  if (delegate->ShouldToggleSpokenFeedbackViaTouch())
    delegate->PlaySpokenFeedbackToggleCountdown(tick_count);
}

void AshTouchExplorationManager::ToggleSpokenFeedback() {
  AccessibilityDelegate* delegate = Shell::Get()->accessibility_delegate();
  if (delegate->ShouldToggleSpokenFeedbackViaTouch())
    delegate->ToggleSpokenFeedback(ash::A11Y_NOTIFICATION_SHOW);
}

void AshTouchExplorationManager::OnWindowActivated(
    aura::client::ActivationChangeObserver::ActivationReason reason,
    aura::Window* gained_active,
    aura::Window* lost_active) {
  UpdateTouchExplorationState();
}

void AshTouchExplorationManager::SetTouchAccessibilityAnchorPoint(
    const gfx::Point& anchor_point) {
  if (touch_exploration_controller_) {
    touch_exploration_controller_->SetTouchAccessibilityAnchorPoint(
        anchor_point);
  }
}

void AshTouchExplorationManager::UpdateTouchExplorationState() {
  // See crbug.com/603745 for more details.
  const bool pass_through_surface =
      wm::GetActiveWindow() &&
      wm::GetActiveWindow()->GetProperty(aura::client::kAppType) ==
          static_cast<int>(ash::AppType::ARC_APP) &&
      !enable_chromevox_arc_support_;

  const bool spoken_feedback_enabled =
      Shell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();

  if (!touch_accessibility_enabler_) {
    // Always enable gesture to toggle spoken feedback.
    touch_accessibility_enabler_.reset(new ui::TouchAccessibilityEnabler(
        root_window_controller_->GetRootWindow(), this));
  }

  if (spoken_feedback_enabled) {
    if (!touch_exploration_controller_.get()) {
      touch_exploration_controller_ =
          base::MakeUnique<ui::TouchExplorationController>(
              root_window_controller_->GetRootWindow(), this,
              touch_accessibility_enabler_.get());
    }
    if (pass_through_surface) {
      const gfx::Rect& work_area = root_window_controller_->GetWindow()
                                       ->GetDisplayNearestWindow()
                                       .work_area();
      touch_exploration_controller_->SetExcludeBounds(work_area);
      SilenceSpokenFeedback();
      Shell::Get()->accessibility_delegate()->ClearFocusHighlight();
    } else {
      touch_exploration_controller_->SetExcludeBounds(gfx::Rect());
    }
  } else {
    touch_exploration_controller_.reset();
  }
}

bool AshTouchExplorationManager::VolumeAdjustSoundEnabled() {
  return !base::CommandLine::ForCurrentProcess()->HasSwitch(
      chromeos::switches::kDisableVolumeAdjustSound);
}

}  // namespace ash
