// Copyright (c) 2012 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/system/tray_update.h"

#include "ash/root_window_controller.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/tray/fixed_sized_image_view.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_delegate.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/system/tray/tray_constants.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "ui/aura/window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget.h"

namespace {

// How many seconds should we wait before showing the nag reminder?
const int kUpdateNaggingTimeSeconds = 24 * 60 * 60;

// How long should the nag reminder be displayed?
const int kShowUpdateNaggerForSeconds = 15;

int DecideResource(ash::UpdateObserver::UpdateSeverity severity, bool dark) {
  switch (severity) {
    case ash::UpdateObserver::UPDATE_NORMAL:
      return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK:
                    IDR_AURA_UBER_TRAY_UPDATE;

    case ash::UpdateObserver::UPDATE_LOW_GREEN:
      return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK_GREEN :
                    IDR_AURA_UBER_TRAY_UPDATE_GREEN;

    case ash::UpdateObserver::UPDATE_HIGH_ORANGE:
      return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK_ORANGE :
                    IDR_AURA_UBER_TRAY_UPDATE_ORANGE;

    case ash::UpdateObserver::UPDATE_SEVERE_RED:
      return dark ? IDR_AURA_UBER_TRAY_UPDATE_DARK_RED :
                    IDR_AURA_UBER_TRAY_UPDATE_RED;
  }

  NOTREACHED() << "Unknown update severity level.";
  return 0;
}

class UpdateView : public ash::ActionableView {
 public:
  explicit UpdateView(ash::UpdateObserver::UpdateSeverity severity) {
    SetLayoutManager(new
        views::BoxLayout(views::BoxLayout::kHorizontal,
        ash::kTrayPopupPaddingHorizontal, 0,
        ash::kTrayPopupPaddingBetweenItems));

    ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
    views::ImageView* image =
        new ash::FixedSizedImageView(0, ash::kTrayPopupItemHeight);
    image->SetImage(bundle.GetImageNamed(DecideResource(severity, true)).
        ToImageSkia());

    AddChildView(image);
    AddChildView(new views::Label(
        bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_UPDATE)));
    SetAccessibleName(bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_UPDATE));
  }

  virtual ~UpdateView() {}

 private:
  // Overridden from ActionableView.
  virtual bool PerformAction(const ui::Event& event) OVERRIDE {
    ash::Shell::GetInstance()->
        system_tray_delegate()->RequestRestartForUpdate();
    return true;
  }

  DISALLOW_COPY_AND_ASSIGN(UpdateView);
};

}

namespace ash {
namespace tray {

class UpdateNagger : public ui::LayerAnimationObserver {
 public:
  explicit UpdateNagger(SystemTrayItem* owner)
      : owner_(owner) {
    RestartTimer();
    owner_->system_tray()->GetWidget()->GetNativeView()->layer()->
        GetAnimator()->AddObserver(this);
  }

  virtual ~UpdateNagger() {
    StatusAreaWidget* status_area =
        Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
    if (status_area) {
      status_area->system_tray()->GetWidget()->GetNativeView()->layer()->
          GetAnimator()->RemoveObserver(this);
    }
  }

  void RestartTimer() {
    timer_.Stop();
    timer_.Start(FROM_HERE,
                 base::TimeDelta::FromSeconds(kUpdateNaggingTimeSeconds),
                 this,
                 &UpdateNagger::Nag);
  }

 private:
  void Nag() {
    owner_->PopupDetailedView(kShowUpdateNaggerForSeconds, false);
  }

  // Overridden from ui::LayerAnimationObserver.
  virtual void OnLayerAnimationEnded(
      ui::LayerAnimationSequence* sequence) OVERRIDE {
    // TODO(oshima): Find out if the updator will be shown on non
    // primary display.
    if (Shell::GetPrimaryRootWindowController()->shelf()->IsVisible())
      timer_.Stop();
    else if (!timer_.IsRunning())
      RestartTimer();
  }

  virtual void OnLayerAnimationAborted(
      ui::LayerAnimationSequence* sequence) OVERRIDE {}

  virtual void OnLayerAnimationScheduled(
      ui::LayerAnimationSequence* sequence) OVERRIDE {}

  SystemTrayItem* owner_;
  base::OneShotTimer<UpdateNagger> timer_;

  DISALLOW_COPY_AND_ASSIGN(UpdateNagger);
};

}  // namespace tray

TrayUpdate::TrayUpdate(SystemTray* system_tray)
    : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_UPDATE),
      severity_(UpdateObserver::UPDATE_NORMAL) {
  Shell::GetInstance()->system_tray_notifier()->AddUpdateObserver(this);
}

TrayUpdate::~TrayUpdate() {
  Shell::GetInstance()->system_tray_notifier()->RemoveUpdateObserver(this);
}

bool TrayUpdate::GetInitialVisibility() {
  return Shell::GetInstance()->system_tray_delegate()->SystemShouldUpgrade();
}

views::View* TrayUpdate::CreateDefaultView(user::LoginStatus status) {
  if (!Shell::GetInstance()->system_tray_delegate()->SystemShouldUpgrade())
    return NULL;
  return new UpdateView(severity_);
}

views::View* TrayUpdate::CreateDetailedView(user::LoginStatus status) {
  return CreateDefaultView(status);
}

void TrayUpdate::DestroyDetailedView() {
  if (nagger_) {
    // The nagger was being displayed. Now that the detailed view is being
    // closed, that means either the user clicks on it to restart, or the user
    // didn't click on it to restart. In either case, start the timer to show
    // the nag reminder again after the specified time.
    nagger_->RestartTimer();
  }
}

void TrayUpdate::OnUpdateRecommended(UpdateObserver::UpdateSeverity severity) {
  severity_ = severity;
  SetImageFromResourceId(DecideResource(severity_, false));
  tray_view()->SetVisible(true);
  if (!Shell::GetPrimaryRootWindowController()->shelf()->IsVisible() &&
      !nagger_.get()) {
    // The shelf is not visible, and there is no nagger scheduled.
    nagger_.reset(new tray::UpdateNagger(this));
  }
}

}  // namespace ash
