// 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 "content/common/mac/attributed_string_coder.h"

#include <AppKit/AppKit.h>

#include "base/logging.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/render_process_messages.h"
#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_utils.h"

namespace mac {

// static
const AttributedStringCoder::EncodedString* AttributedStringCoder::Encode(
    NSAttributedString* str) {
  // Create the return value.
  EncodedString* encoded_string =
      new EncodedString(base::SysNSStringToUTF16([str string]));
  // Iterate over all the attributes in the string.
  NSUInteger length = [str length];
  for (NSUInteger i = 0; i < length; ) {
    NSRange effective_range;
    NSDictionary* ns_attributes = [str attributesAtIndex:i
                                          effectiveRange:&effective_range];
    // Convert the attributes to IPC-friendly types.
    FontAttribute attrs(ns_attributes, gfx::Range(effective_range));
    // Only encode the attributes if the filtered set contains font information.
    if (attrs.ShouldEncode()) {
      encoded_string->attributes()->push_back(attrs);
    }
    // Advance the iterator to the position outside of the effective range.
    i = NSMaxRange(effective_range);
  }
  return encoded_string;
}

// static
NSAttributedString* AttributedStringCoder::Decode(
    const AttributedStringCoder::EncodedString* str) {
  // Create the return value.
  NSString* plain_text = base::SysUTF16ToNSString(str->string());
  base::scoped_nsobject<NSMutableAttributedString> decoded_string(
      [[NSMutableAttributedString alloc] initWithString:plain_text]);
  // Iterate over all the encoded attributes, attaching each to the string.
  const std::vector<FontAttribute> attributes = str->attributes();
  for (std::vector<FontAttribute>::const_iterator it = attributes.begin();
       it != attributes.end(); ++it) {
    // Protect against ranges that are outside the range of the string.
    const gfx::Range& range = it->effective_range();
    if (range.GetMin() > [plain_text length] ||
        range.GetMax() > [plain_text length]) {
      continue;
    }
    [decoded_string addAttributes:it->ToAttributesDictionary()
                            range:range.ToNSRange()];
  }
  return [decoded_string.release() autorelease];
}

// Data Types //////////////////////////////////////////////////////////////////

AttributedStringCoder::EncodedString::EncodedString(base::string16 string)
    : string_(string) {
}

AttributedStringCoder::EncodedString::EncodedString()
    : string_() {
}

AttributedStringCoder::EncodedString::~EncodedString() {
}

AttributedStringCoder::FontAttribute::FontAttribute(NSDictionary* dict,
                                                    gfx::Range effective_range)
    : font_descriptor_(),
      effective_range_(effective_range) {
  NSFont* font = [dict objectForKey:NSFontAttributeName];
  if (font) {
    font_descriptor_ = FontDescriptor(font);
  }
}

AttributedStringCoder::FontAttribute::FontAttribute(FontDescriptor font,
                                                    gfx::Range range)
    : font_descriptor_(font),
      effective_range_(range) {
}

AttributedStringCoder::FontAttribute::FontAttribute()
    : font_descriptor_(),
      effective_range_() {
}

AttributedStringCoder::FontAttribute::~FontAttribute() {
}

NSDictionary*
AttributedStringCoder::FontAttribute::ToAttributesDictionary() const {
  DCHECK(ShouldEncode());
  NSFont* font = font_descriptor_.ToNSFont();
  if (!font)
    return [NSDictionary dictionary];
  return [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
}

bool AttributedStringCoder::FontAttribute::ShouldEncode() const {
  return !font_descriptor_.font_name.empty();
}

}  // namespace mac

// IPC ParamTraits specialization //////////////////////////////////////////////

namespace IPC {

using mac::AttributedStringCoder;

void ParamTraits<AttributedStringCoder::EncodedString>::Write(
    Message* m, const param_type& p) {
  WriteParam(m, p.string());
  WriteParam(m, p.attributes());
}

bool ParamTraits<AttributedStringCoder::EncodedString>::Read(
    const Message* m,
    base::PickleIterator* iter,
    param_type* p) {
  bool success = true;

  base::string16 result;
  success &= ReadParam(m, iter, &result);
  *p = AttributedStringCoder::EncodedString(result);

  success &= ReadParam(m, iter, p->attributes());
  return success;
}

void ParamTraits<AttributedStringCoder::EncodedString>::Log(
    const param_type& p, std::string* l) {
  l->append(base::UTF16ToUTF8(p.string()));
}

void ParamTraits<AttributedStringCoder::FontAttribute>::Write(
    Message* m, const param_type& p) {
  WriteParam(m, p.font_descriptor());
  WriteParam(m, p.effective_range());
}

bool ParamTraits<AttributedStringCoder::FontAttribute>::Read(
    const Message* m,
    base::PickleIterator* iter,
    param_type* p) {
  bool success = true;

  FontDescriptor font;
  success &= ReadParam(m, iter, &font);

  gfx::Range range;
  success &= ReadParam(m, iter, &range);

  if (success) {
    *p = AttributedStringCoder::FontAttribute(font, range);
  }
  return success;
}

void ParamTraits<AttributedStringCoder::FontAttribute>::Log(
    const param_type& p, std::string* l) {
}

}  // namespace IPC
