// 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 "ppapi/cpp/dev/file_chooser_dev.h"

#include <string.h>

#include "ppapi/c/dev/ppb_file_chooser_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/instance_handle.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/module_impl.h"

namespace pp {

namespace {

template <> const char* interface_name<PPB_FileChooser_Dev_0_5>() {
  return PPB_FILECHOOSER_DEV_INTERFACE_0_5;
}

template <> const char* interface_name<PPB_FileChooser_Dev_0_6>() {
  return PPB_FILECHOOSER_DEV_INTERFACE_0_6;
}

}  // namespace

FileChooser_Dev::FileChooser_Dev(const InstanceHandle& instance,
                                 PP_FileChooserMode_Dev mode,
                                 const Var& accept_types) {
  if (has_interface<PPB_FileChooser_Dev_0_6>()) {
    PassRefFromConstructor(get_interface<PPB_FileChooser_Dev_0_6>()->Create(
        instance.pp_instance(), mode, accept_types.pp_var()));
  } else if (has_interface<PPB_FileChooser_Dev_0_5>()) {
    PassRefFromConstructor(get_interface<PPB_FileChooser_Dev_0_5>()->Create(
        instance.pp_instance(), mode, accept_types.pp_var()));
  }
}

FileChooser_Dev::FileChooser_Dev(const FileChooser_Dev& other)
    : Resource(other) {
}

int32_t FileChooser_Dev::Show(
    const CompletionCallbackWithOutput< std::vector<FileRef> >& callback) {
  if (has_interface<PPB_FileChooser_Dev_0_6>()) {
    return get_interface<PPB_FileChooser_Dev_0_6>()->Show(
        pp_resource(),
        callback.output(),
        callback.pp_completion_callback());
  }
  if (has_interface<PPB_FileChooser_Dev_0_5>()) {
    // Data for our callback wrapper. The callback handler will delete it.
    ChooseCallbackData0_5* data = new ChooseCallbackData0_5;
    data->file_chooser = pp_resource();
    data->output = callback.output();
    data->original_callback = callback.pp_completion_callback();

    return get_interface<PPB_FileChooser_Dev_0_5>()->Show(
        pp_resource(), PP_MakeCompletionCallback(&CallbackConverter, data));
  }
  return callback.MayForce(PP_ERROR_NOINTERFACE);
}

// static
void FileChooser_Dev::CallbackConverter(void* user_data, int32_t result) {
  ChooseCallbackData0_5* data = static_cast<ChooseCallbackData0_5*>(user_data);

  // Get all of the selected file resources using the iterator API.
  std::vector<PP_Resource> selected_files;
  if (result == PP_OK) {
    const PPB_FileChooser_Dev_0_5* chooser =
        get_interface<PPB_FileChooser_Dev_0_5>();
    while (PP_Resource cur = chooser->GetNextChosenFile(data->file_chooser))
      selected_files.push_back(cur);
  }

  // Need to issue the "GetDataBuffer" even for error cases & when the
  // number of items is 0.
  void* output_buf = data->output.GetDataBuffer(
      data->output.user_data,
      selected_files.size(), sizeof(PP_Resource));
  if (output_buf) {
    if (!selected_files.empty()) {
      memcpy(output_buf, &selected_files[0],
             sizeof(PP_Resource) * selected_files.size());
    }
  } else {
    // Error allocating, need to free the resource IDs.
    for (size_t i = 0; i < selected_files.size(); i++)
      Module::Get()->core()->ReleaseResource(selected_files[i]);
  }

  // Now execute the original callback.
  PP_RunCompletionCallback(&data->original_callback, result);
  delete data;
}

}  // namespace pp
