// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Class functions to be used for output by the Session class.

#ifndef MOZC_SESSION_INTERNAL_SESSION_OUTPUT_H_
#define MOZC_SESSION_INTERNAL_SESSION_OUTPUT_H_

#include <string>

#include "base/port.h"
#include "session/commands.pb.h"

namespace mozc {

class Segment;
class Segments;

namespace composer {
class Composer;
}

namespace session {

class CandidateList;
class Candidate;

class SessionOutput {
 public:
  // Fill the Candidates_Candidate protobuf with the contents of candidate.
  static void FillCandidate(const Segment &segment,
                            const Candidate &candidate,
                            commands::Candidates_Candidate *candidate_proto);

  // Fill the Candidates protobuf with the contents of candidate_list.
  static void FillCandidates(const Segment &segment,
                             const CandidateList &candidate_list,
                             size_t position,
                             commands::Candidates *candidates_proto);

  // Fill the CandidateList protobuf with the contents of
  // candidate_list.  Candidates in the candidate_list are flatten
  // even if the candidate_list contains sub-candidate lists.
  static void FillAllCandidateWords(
      const Segment &segment,
      const CandidateList &candidate_list,
      const commands::Category category,
      commands::CandidateList *candidate_list_proto);

  // Check if the usages should be rendered on the current CandidateList status.
  static bool ShouldShowUsages(const Segment &segment,
                               const CandidateList &cand_list);

  // Fill the usages of Candidates protobuf with the contents of candidate_list.
  static void FillUsages(const Segment &segment,
                         const CandidateList &candidate_list,
                         commands::Candidates *candidates_proto);

  // Fill the access key of Candidates protobuf with the sequence of shortcuts.
  static void FillShortcuts(const string &shortcuts,
                            commands::Candidates *candidates_proto);

  // Fill the sub_label of footer_proto.  This function should be
  // called on dev_channel and unittest.
  static void FillSubLabel(commands::Footer *footer_proto);

  // Fill the footer contents of Candidates protobuf.  If category is
  // modified, true is returned.  Otherwise false is returned.
  static bool FillFooter(commands::Category category,
                         commands::Candidates *candidates_proto);

  // Fill the Preedit protobuf with the contents of composer as a preedit.
  static void FillPreedit(const composer::Composer &composer,
                          commands::Preedit *preedit);

  // Fill the Preedit protobuf with the contents of segments as a conversion.
  static void FillConversion(const Segments &segments,
                             size_t segment_index,
                             int candidate_id,
                             commands::Preedit *preedit);

  enum SegmentType {
    PREEDIT = 1,
    CONVERSION = 2,
    FOCUSED = 4,
  };
  // Add a Preedit::Segment protobuf to the Preedit protobuf with key
  // and value.  Return true iff. new segment is added to preedit.
  static bool AddSegment(const string &key,
                         const string &value,
                         uint32 segment_type_mask,
                         commands::Preedit *preedit);

  // Fill the Result protobuf with the key and result strings
  // for a conversion result without any text normalization.
  static void FillConversionResultWithoutNormalization(
      const string &key,
      const string &result,
      commands::Result *result_proto);

  // Fill the Result protobuf with the key and result strings
  // nomalizing the string for a conversion result.
  static void FillConversionResult(const string &key,
                                   const string &result,
                                   commands::Result *result_proto);

  // Fill the Result protobuf with the preedit string nomalizing the
  // string for a preedit result.
  static void FillPreeditResult(const string &preedit,
                                commands::Result *result_proto);


 private:
  DISALLOW_COPY_AND_ASSIGN(SessionOutput);
};

}  // namespace session
}  // namespace mozc

#endif  // MOZC_SESSION_INTERNAL_SESSION_OUTPUT_H_
