// Copyright (c) 2011 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 "chrome/browser/chromeos/login/user_image_view.h"

#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/login/default_images_view.h"
#include "chrome/browser/chromeos/login/default_user_images.h"
#include "chrome/browser/chromeos/login/helper.h"
#include "chrome/browser/chromeos/login/rounded_rect_painter.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "views/background.h"
#include "views/controls/button/native_button.h"
#include "views/controls/label.h"
#include "views/layout/grid_layout.h"

namespace {

// Margin in pixels from the left and right borders of screen's contents.
const int kHorizontalMargin = 10;
// Margin in pixels from the top and bottom borders of screen's contents.
const int kVerticalMargin = 10;
// Padding between horizontally neighboring elements.
const int kHorizontalPadding = 10;
// Padding between vertically neighboring elements.
const int kVerticalPadding = 10;
// Color for splitter separating contents from OK button.
const SkColor kSplitterColor = SkColorSetRGB(187, 195, 200);
// Height for the splitter.
const int kSplitterHeight = 1;

// IDs of column sets for grid layout manager.
enum ColumnSets {
  kTitleRow,     // Column set for screen title.
  kImagesRow,    // Column set for image from camera and snapshot button.
  kSplitterRow, // Place for the splitter.
  kButtonsRow,   // Column set for OK button.
};

views::View* CreateSplitter(const SkColor& color) {
  views::View* splitter = new views::View();
  splitter->set_background(views::Background::CreateSolidBackground(color));
  return splitter;
}

}  // namespace

namespace chromeos {

UserImageView::UserImageView(Delegate* delegate)
    : title_label_(NULL),
      default_images_view_(NULL),
      take_photo_view_(NULL),
      splitter_(NULL),
      ok_button_(NULL),
      delegate_(delegate) {
}

UserImageView::~UserImageView() {
}

void UserImageView::Init() {
  // Use rounded rect background.
  set_border(CreateWizardBorder(&BorderDefinition::kScreenBorder));
  views::Painter* painter = CreateWizardPainter(
      &BorderDefinition::kScreenBorder);
  set_background(views::Background::CreateBackgroundPainter(true, painter));

  title_label_ = new views::Label(UTF16ToWide(
      l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT)));
  title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
  title_label_->SetMultiLine(true);
  CorrectLabelFontSize(title_label_);

  default_images_view_ = new DefaultImagesView(this);
  take_photo_view_ = new TakePhotoView(this);
  take_photo_view_->set_show_title(false);

  splitter_ = CreateSplitter(kSplitterColor);

  ok_button_ = new login::WideButton(
      this, UTF16ToWide(l10n_util::GetStringUTF16(IDS_OK)));
  ok_button_->SetEnabled(false);

  InitLayout();

  default_images_view_->Init();
  take_photo_view_->Init();

  UserManager* user_manager = UserManager::Get();
  const std::string& logged_in_user = user_manager->logged_in_user().email();
  int image_index = user_manager->GetUserDefaultImageIndex(logged_in_user);

  default_images_view_->SetDefaultImageIndex(image_index);
}

void UserImageView::InitLayout() {
  views::GridLayout* layout = new views::GridLayout(this);
  layout->SetInsets(GetInsets());
  SetLayoutManager(layout);

  // The title, left-top aligned.
  views::ColumnSet* column_set = layout->AddColumnSet(kTitleRow);
  column_set->AddPaddingColumn(0, kHorizontalMargin);
  column_set->AddColumn(views::GridLayout::FILL,
                        views::GridLayout::LEADING,
                        1,
                        views::GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kHorizontalMargin);

  // The view with default images and the one with image from camera and label.
  column_set = layout->AddColumnSet(kImagesRow);
  column_set->AddPaddingColumn(0, kHorizontalMargin);
  column_set->AddColumn(views::GridLayout::LEADING,
                        views::GridLayout::LEADING,
                        0,
                        views::GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kHorizontalPadding);
  column_set->AddColumn(views::GridLayout::FILL,
                        views::GridLayout::LEADING,
                        1,
                        views::GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kHorizontalMargin);

  // Splitter.
  column_set = layout->AddColumnSet(kSplitterRow);
  column_set->AddColumn(views::GridLayout::FILL,
                        views::GridLayout::TRAILING,
                        1,
                        views::GridLayout::USE_PREF, 0, 0);

  // OK button is in the right bottom corner of the view.
  column_set = layout->AddColumnSet(kButtonsRow);
  column_set->AddPaddingColumn(0, kHorizontalMargin);
  column_set->AddColumn(views::GridLayout::TRAILING,
                        views::GridLayout::TRAILING,
                        1,
                        views::GridLayout::USE_PREF, 0, 0);
  column_set->AddPaddingColumn(0, kHorizontalMargin);

  // Fill the layout with rows and views now.
  layout->StartRowWithPadding(0, kTitleRow, 0, kVerticalMargin);
  layout->AddView(title_label_);
  layout->StartRowWithPadding(0, kImagesRow, 0, kVerticalPadding);
  layout->AddView(default_images_view_);
  layout->AddView(take_photo_view_);
  layout->StartRowWithPadding(1, kSplitterRow, 0, kVerticalPadding);
  // Set height for splitter view explicitly otherwise it's set to 0
  // by default.
  layout->AddView(splitter_,
                  1, 1,
                  views::GridLayout::FILL,
                  views::GridLayout::TRAILING,
                  0,
                  kSplitterHeight);
  layout->StartRowWithPadding(0, kButtonsRow, 0, kVerticalPadding);
  layout->AddView(ok_button_);
  layout->AddPaddingRow(0, kVerticalMargin);
}

void UserImageView::UpdateVideoFrame(const SkBitmap& frame) {
  DCHECK(take_photo_view_);
  take_photo_view_->UpdateVideoFrame(frame);
}

void UserImageView::ShowCameraInitializing() {
  DCHECK(take_photo_view_);
  take_photo_view_->ShowCameraInitializing();
}

void UserImageView::ShowCameraError() {
  DCHECK(take_photo_view_);
  take_photo_view_->ShowCameraError();
}

bool UserImageView::IsCapturing() const {
  DCHECK(default_images_view_);
  DCHECK(take_photo_view_);
  return default_images_view_->GetDefaultImageIndex() == -1 &&
         take_photo_view_->is_capturing();
}

gfx::Size UserImageView::GetPreferredSize() {
  return gfx::Size(width(), height());
}

void UserImageView::ButtonPressed(
    views::Button* sender, const views::Event& event) {
  DCHECK(delegate_);
  if (sender == ok_button_) {
    if (default_images_view_->GetDefaultImageIndex() == -1) {
      delegate_->OnPhotoTaken(take_photo_view_->GetImage());
    } else {
      delegate_->OnDefaultImageSelected(
          default_images_view_->GetDefaultImageIndex());
    }
  } else {
    NOTREACHED();
  }
}

void UserImageView::OnCapturingStarted() {
  delegate_->StartCamera();
  default_images_view_->ClearSelection();
  ok_button_->SetEnabled(false);
  ShowCameraInitializing();
}

void UserImageView::OnCapturingStopped() {
  delegate_->StopCamera();
  default_images_view_->ClearSelection();
  ok_button_->SetEnabled(true);
  ok_button_->RequestFocus();
}

void UserImageView::OnCaptureButtonClicked() {
  if (!IsCapturing())
    OnCapturingStarted();
}

void UserImageView::OnImageSelected(int image_index) {
  // Can happen when user is not known, i.e. in tests.
  if (image_index < 0 || image_index >= kDefaultImagesCount)
    return;
  delegate_->StopCamera();
  ok_button_->SetEnabled(true);
  ok_button_->RequestFocus();
  take_photo_view_->SetImage(
      ResourceBundle::GetSharedInstance().GetBitmapNamed(
            kDefaultImageResources[image_index]));
}

}  // namespace chromeos