// 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 "ui/shell_dialogs/select_file_dialog.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/shell_dialogs/select_file_dialog_factory.h"
#include "ui/shell_dialogs/select_file_policy.h"
#include "ui/shell_dialogs/selected_file_info.h"
#include "ui/shell_dialogs/shell_dialogs_delegate.h"

#if defined(OS_WIN)
#include "ui/shell_dialogs/select_file_dialog_win.h"
#elif defined(OS_MACOSX)
#include "ui/shell_dialogs/select_file_dialog_mac.h"
#elif defined(TOOLKIT_GTK)
#include "ui/shell_dialogs/gtk/select_file_dialog_impl.h"
#elif defined(OS_ANDROID)
#include "ui/shell_dialogs/select_file_dialog_android.h"
#elif defined(USE_AURA) && !defined(USE_ASH) && defined(OS_LINUX)
#include "ui/shell_dialogs/linux_shell_dialog.h"
#endif

namespace {

// Optional dialog factory. Leaked.
ui::SelectFileDialogFactory* dialog_factory_ = NULL;

// The global shell dialogs delegate.
ui::ShellDialogsDelegate* g_shell_dialogs_delegate_ = NULL;

}  // namespace

namespace ui {

SelectFileDialog::FileTypeInfo::FileTypeInfo()
    : include_all_files(false),
      support_drive(false) {}

SelectFileDialog::FileTypeInfo::~FileTypeInfo() {}

void SelectFileDialog::Listener::FileSelectedWithExtraInfo(
    const ui::SelectedFileInfo& file,
    int index,
    void* params) {
  // Most of the dialogs need actual local path, so default to it.
  FileSelected(file.local_path, index, params);
}

void SelectFileDialog::Listener::MultiFilesSelectedWithExtraInfo(
    const std::vector<ui::SelectedFileInfo>& files,
    void* params) {
  std::vector<base::FilePath> file_paths;
  for (size_t i = 0; i < files.size(); ++i)
    file_paths.push_back(files[i].local_path);

  MultiFilesSelected(file_paths, params);
}

// static
void SelectFileDialog::SetFactory(ui::SelectFileDialogFactory* factory) {
  delete dialog_factory_;
  dialog_factory_ = factory;
}

// static
scoped_refptr<SelectFileDialog> SelectFileDialog::Create(
    Listener* listener,
    ui::SelectFilePolicy* policy) {
  if (dialog_factory_) {
    SelectFileDialog* dialog = dialog_factory_->Create(listener, policy);
    if (dialog)
      return dialog;
  }

#if defined(USE_AURA) && !defined(USE_ASH) && defined(OS_LINUX)
  const ui::LinuxShellDialog* shell_dialogs = ui::LinuxShellDialog::instance();
  if (shell_dialogs)
    return shell_dialogs->CreateSelectFileDialog(listener, policy);
#endif

#if defined(OS_WIN)
  // TODO(ananta)
  // Fix this for Chrome ASH on Windows.
  return CreateWinSelectFileDialog(listener, policy);
#elif defined(OS_MACOSX) && !defined(USE_AURA)
  return CreateMacSelectFileDialog(listener, policy);
#elif defined(TOOLKIT_GTK)
  return CreateLinuxSelectFileDialog(listener, policy);
#elif defined(OS_ANDROID)
  return CreateAndroidSelectFileDialog(listener, policy);
#endif

  return NULL;
}

void SelectFileDialog::SelectFile(
    Type type,
    const base::string16& title,
    const base::FilePath& default_path,
    const FileTypeInfo* file_types,
    int file_type_index,
    const base::FilePath::StringType& default_extension,
    gfx::NativeWindow owning_window,
    void* params) {
  DCHECK(listener_);

  if (select_file_policy_.get() &&
      !select_file_policy_->CanOpenSelectFileDialog()) {
    select_file_policy_->SelectFileDenied();

    // Inform the listener that no file was selected.
    // Post a task rather than calling FileSelectionCanceled directly to ensure
    // that the listener is called asynchronously.
    base::MessageLoop::current()->PostTask(
        FROM_HERE,
        base::Bind(&SelectFileDialog::CancelFileSelection, this, params));
    return;
  }

  // Call the platform specific implementation of the file selection dialog.
  SelectFileImpl(type, title, default_path, file_types, file_type_index,
                 default_extension, owning_window, params);
}

bool SelectFileDialog::HasMultipleFileTypeChoices() {
  return HasMultipleFileTypeChoicesImpl();
}

// static
void SelectFileDialog::SetShellDialogsDelegate(ShellDialogsDelegate* delegate) {
  g_shell_dialogs_delegate_ = delegate;
}

SelectFileDialog::SelectFileDialog(Listener* listener,
                                   ui::SelectFilePolicy* policy)
    : listener_(listener),
      select_file_policy_(policy) {
  DCHECK(listener_);
}

SelectFileDialog::~SelectFileDialog() {}

void SelectFileDialog::CancelFileSelection(void* params) {
  if (listener_)
    listener_->FileSelectionCanceled(params);
}

ShellDialogsDelegate* SelectFileDialog::GetShellDialogsDelegate() {
  return g_shell_dialogs_delegate_;
}

}  // namespace ui
