# -*- coding: utf-8 -*-
# Copyright 2010-2014, 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.

"""Utilities to create Mozc's .pic file from .svg file.

This module provides some utilities to create a .pic file, which is interpreted
in MechaMozc, from .svg files.
.pic file is a Mozc original format to represent vector image data shared by
all android platforms.
Note: another idea was to use binary data which is saved via PictureDrawable
on Android, but it seems that there are some differencces between devices,
and it'd cause an crash error, unfortunately.
"""

__author__ = "hidehiko"

import cStringIO as StringIO
import logging
import optparse
import os
import re
import struct
import sys
from xml.etree import cElementTree as ElementTree

from build_tools import util

# State const values defined in android.R.attr.
STATE_PRESSED = 0x010100a7
STATE_SELECTED = 0x010100a1
STATE_CHECKED = 0x010100a0

DRAWABLE_PICTURE = 1
DRAWABLE_STATE_LIST = 2

CMD_PICTURE_EOP = 0
CMD_PICTURE_DRAW_PATH = 1
CMD_PICTURE_DRAW_POLYLINE = 2
CMD_PICTURE_DRAW_POLYGON = 3
CMD_PICTURE_DRAW_LINE = 4
CMD_PICTURE_DRAW_RECT = 5
CMD_PICTURE_DRAW_CIRCLE = 6
CMD_PICTURE_DRAW_ELLIPSE = 7
CMD_PICTURE_DRAW_GROUP_START = 8
CMD_PICTURE_DRAW_GROUP_END = 9

CMD_PICTURE_PATH_EOP = 0
CMD_PICTURE_PATH_MOVE = 1
CMD_PICTURE_PATH_LINE = 2
CMD_PICTURE_PATH_HORIZONTAL_LINE = 3
CMD_PICTURE_PATH_VERTICAL_LINE = 4
CMD_PICTURE_PATH_CURVE = 5
CMD_PICTURE_PATH_CONTINUED_CURVE = 6
CMD_PICTURE_PATH_CLOSE = 7

CMD_PICTURE_PAINT_EOP = 0
CMD_PICTURE_PAINT_STYLE = 1
CMD_PICTURE_PAINT_COLOR = 2
CMD_PICTURE_PAINT_SHADOW = 3
CMD_PICTURE_PAINT_STROKE_WIDTH = 4
CMD_PICTURE_PAINT_STROKE_CAP = 5
CMD_PICTURE_PAINT_STROKE_JOIN = 6
CMD_PICTURE_PAINT_SHADER = 7

CMD_PICTURE_SHADER_LINEAR_GRADIENT = 1
CMD_PICTURE_SHADER_RADIAL_GRADIENT = 2

STYLE_CATEGORY_TAG = 128
STYLE_CATEGORY_KEYICON_MAIN = 0
STYLE_CATEGORY_KEYICON_GUIDE = 1
STYLE_CATEGORY_KEYICON_GUIDE_LIGHT = 2
STYLE_CATEGORY_KEYICON_MAIN_HIGHLIGHT = 3
STYLE_CATEGORY_KEYICON_GUIDE_HIGHLIGHT = 4
STYLE_CATEGORY_KEYICON_BOUND = 5
STYLE_CATEGORY_KEYICON_FUNCTION = 6
STYLE_CATEGORY_KEYICON_FUNCTION_DARK = 7
STYLE_CATEGORY_KEYICON_QWERTY_SHIFT_ON_ARROW = 8
STYLE_CATEGORY_KEYICON_QWERTY_CAPS_ON_ARROW = 9
STYLE_CATEGORY_KEYPOPUP_HIGHLIGHT = 10
STYLE_CATEGORY_KEYICON_POPUP_FUNCTION = 11
STYLE_CATEGORY_KEYICON_POPUP_FUNCTION_DARK = 12
# We may be able to reuse same resources for symbol major/minor icons.
STYLE_CATEGORY_SYMBOL_MAJOR = 13
STYLE_CATEGORY_SYMBOL_MAJOR_SELECTED = 14
STYLE_CATEGORY_SYMBOL_MINOR = 15
STYLE_CATEGORY_SYMBOL_MINOR_SELECTED = 16
STYLE_CATEGORY_KEYBOARD_FOLDING_BUTTON_BACKGROUND = 17

# We'll check the category id by reverse sorted order, to resolve prefix match
# confliction.
STYLE_CATEGORY_MAP = sorted(
    [
        ('style-keyicon-main', STYLE_CATEGORY_KEYICON_MAIN),
        ('style-keyicon-guide', STYLE_CATEGORY_KEYICON_GUIDE),
        ('style-keyicon-guide-light', STYLE_CATEGORY_KEYICON_GUIDE_LIGHT),
        ('style-keyicon-main-highlight', STYLE_CATEGORY_KEYICON_MAIN_HIGHLIGHT),
        ('style-keyicon-guide-highlight',
         STYLE_CATEGORY_KEYICON_GUIDE_HIGHLIGHT),
        ('style-keyicon-bound', STYLE_CATEGORY_KEYICON_BOUND),
        ('style-keyicon-function', STYLE_CATEGORY_KEYICON_FUNCTION),
        ('style-keyicon-function-dark', STYLE_CATEGORY_KEYICON_FUNCTION_DARK),
        ('style-keyicon-qwerty-shift-on-arrow',
         STYLE_CATEGORY_KEYICON_QWERTY_SHIFT_ON_ARROW),
        ('style-keyicon-qwerty-caps-on-arrow',
         STYLE_CATEGORY_KEYICON_QWERTY_CAPS_ON_ARROW),
        ('style-keypopup-highlight', STYLE_CATEGORY_KEYPOPUP_HIGHLIGHT),
        ('style-keyicon-popup-function',
         STYLE_CATEGORY_KEYICON_POPUP_FUNCTION),
        ('style-keyicon-popup-function-dark',
         STYLE_CATEGORY_KEYICON_POPUP_FUNCTION_DARK),
        ('style-symbol-major', STYLE_CATEGORY_SYMBOL_MAJOR),
        ('style-symbol-major-selected', STYLE_CATEGORY_SYMBOL_MAJOR_SELECTED),
        ('style-symbol-minor', STYLE_CATEGORY_SYMBOL_MINOR),
        ('style-symbol-minor-selected', STYLE_CATEGORY_SYMBOL_MINOR_SELECTED),
        ('style-keyboard-folding-button-background',
         STYLE_CATEGORY_KEYBOARD_FOLDING_BUTTON_BACKGROUND),
    ],
    reverse=True)


# Format of PictureDrawable:
# 1, width, height, {CMD_PICTURE_XXX sequence}.
#
# Format of StateListDrawable:
# 2, [[state_list], drawable]
COLOR_PATTERN = re.compile(r'#([0-9A-Fa-f]{6})')
PIXEL_PATTERN = re.compile(r'(\d+)(?:px)?')
FLOAT_PATTERN = re.compile(r'^\s*,?\s*([+-]?\d+(?:\.\d*)?(:?e[+-]\d+)?)')
SHADER_PATTERN = re.compile(r'url\(#(.*)\)')
TRANSFORM_PATTERN = re.compile(r'(matrix|translate)\((.*)\)')
MATRIX_PATTERN = re.compile(r'matrix\((.*)\)')
STOP_COLOR_PATTERN = re.compile(r'stop-color:(.*)')

NO_SHADOW = 0
HAS_SHADOW = 1
HAS_BELOW_SHADOW = 2

class _OutputStream(object):
  """Simple wrapper of output stream by by packing value in big endian."""
  def __init__(self, output):
    self.output = output

  def WriteByte(self, value):
    if not (0 <= value <= 255):
      logging.critical('overflow')
      sys.exit(1)
    self.output.write(struct.pack('>B', value & 0xFF))

  def WriteInt16(self, value):
    if not (0 <= value <= 65535):
      logging.critical('overflow')
      sys.exit(1)
    self.output.write(struct.pack('>H', value & 0xFFFF))

  def WriteInt32(self, value):
    self.output.write(struct.pack('>I', value & 0xFFFFFFFF))

  def WriteFloat(self, value):
    # TODO(hidehiko): Because the precision of original values is thousandth,
    # so we can compress the data by using fixed-precision values.
    self.output.write(struct.pack('>f', value))

  def __enter__(self):
    self.output.__enter__()

  def __exit__(self):
    self.output.__exit__()


class MozcDrawableConverter(object):
  """Converter from .svg file to .pic file."""
  def __init__(self):
    pass

  # Definitions of svg parsing utilities.
  def _ParseColor(self, color):
    """Parses color attribute and returns int32 value or None."""
    if color == 'none':
      return None

    m = COLOR_PATTERN.match(color)
    if not m:
      return None

    c = int(m.group(1), 16)
    if c < 0 or 0x1000000 <= c:
      logging.critical('Out of color range: %s', color)
      sys.exit(1)
    # Set alpha.
    return c | 0xFF000000

  def _ParseShader(self, color, shader_map):
    """Parses shader attribute and returns a shader name from the given map."""
    if color == 'none':
      return None

    m = SHADER_PATTERN.match(color)
    if not m:
      return None
    return shader_map[m.group(1)]

  def _ParsePixel(self, s):
    """Parses pixel size from the given attribute value."""
    m = PIXEL_PATTERN.match(s)
    if not m:
      return None
    return int(m.group(1))

  def _ConsumeFloat(self, s):
    """Returns one floating value from string.

    Args:
      s: the target of parsing.
    Return:
      A tuple of the parsed floating value and the remaining string.
    """
    m = FLOAT_PATTERN.search(s)
    if not m:
      logging.critical('failed to consume float: %s', s)
      sys.exit(1)
    return float(m.group(1)), s[m.end():]

  def _ConsumeFloatList(self, s, num):
    """Parses num floating values from s."""
    result = []
    for _ in xrange(num):
      value, s = self._ConsumeFloat(s)
      result.append(value)
    return result, s

  def _ParseFloatList(self, s):
    """Parses floating list from string."""
    s = s.strip()
    result = []
    while s:
      value, s = self._ConsumeFloat(s)
      result.append(value)
    return result

  def _ParseShaderMap(self, node):
    if node.tag in ['{http://www.w3.org/2000/svg}g',
                    '{http://www.w3.org/2000/svg}svg']:
      result = {}
      for child in node:
        result.update(self._ParseShaderMap(child))
      return result

    if node.tag == '{http://www.w3.org/2000/svg}linearGradient':
      element_id = node.get('id')
      x1 = float(node.get('x1'))
      y1 = float(node.get('y1'))
      x2 = float(node.get('x2'))
      y2 = float(node.get('y2'))
      gradientTransform = node.get('gradientTransform')
      if gradientTransform:
        m = MATRIX_PATTERN.match(gradientTransform)
        (m11, m21, m12, m22, m13, m23) = self._ParseFloatList(m.group(1))
        (x1, y1) = (m11 * x1 + m12 * y1 + m13, m21 * x1 + m22 * y1 + m23)
        (x2, y2) = (m11 * x2 + m12 * y2 + m13, m21 * x2 + m22 * y2 + m23)

      color_list = self._ParseStopList(node)
      return { element_id: ('linear', x1, y1, x2, y2, color_list) }

    if node.tag == '{http://www.w3.org/2000/svg}radialGradient':
      element_id = node.get('id')
      cx = float(node.get('cx'))
      cy = float(node.get('cy'))
      r = float(node.get('r'))
      gradientTransform = node.get('gradientTransform')
      if gradientTransform:
        m = MATRIX_PATTERN.match(gradientTransform)
        matrix = self._ParseFloatList(m.group(1))
      else:
        matrix = None

      color_list = self._ParseStopList(node)
      return { element_id: ('radial', cx, cy, r, matrix, color_list) }

    return {}

  def _ParseStyle(self, node, has_shadow, shader_map):
    """Parses style attribute of the given node."""
    result = {}
    for attr in node.get('style', '').split(';'):
      attr = attr.strip()
      if not attr:
        continue
      command, arg = attr.split(':')
      if command == 'fill' or command == 'stroke':
        shader = self._ParseShader(arg, shader_map)
        color = self._ParseColor(arg)

        if shader is None and color is None:
          if arg != 'none':
            logging.error('Unknown pattern: %s', arg)
          continue

        paint_map = {}
        paint_map['style'] = command
        if shader is not None:
          paint_map['shader'] = shader
        if color is not None:
          paint_map['color'] = color
        paint_map['shadow'] = has_shadow

        result[command] = paint_map
        continue

      if command == 'stroke-width':
        paint_map = result['stroke']
        paint_map['stroke-width'] = float(arg)
        continue

      if command == 'stroke-linecap':
        paint_map = result['stroke']
        paint_map['stroke-linecap'] = arg
        continue

      if command == 'stroke-linejoin':
        paint_map = result['stroke']
        paint_map['stroke-linejoin'] = arg
        continue

    return sorted(result.values(), key=lambda e: e['style'])

  def _ParseStopList(self, parent_node):
    result = []
    for stop in parent_node:
      if stop.tag != '{http://www.w3.org/2000/svg}stop':
        logging.critical('unknown elem: %s', stop.tag)
        sys.exit(1)
      offset = float(stop.get('offset'))
      color = self._ParseColor(
          STOP_COLOR_PATTERN.match(stop.get('style')).group(1))
      result.append((offset, color))
    return result

  # Definition of conversion utilities.
  def _ConvertSize(self, tree, output):
    node = tree.getroot()
    width = self._ParsePixel(node.get('width'))
    height = self._ParsePixel(node.get('height'))

    if width is None or height is None:
      logging.critical('Unknown size')
      sys.exit(1)
    output.WriteInt16(width)
    output.WriteInt16(height)

  def _MaybeConvertShadow(self, has_shadow, output):
    if has_shadow == HAS_SHADOW:
      output.WriteByte(CMD_PICTURE_PAINT_SHADOW)
      output.WriteFloat(2.)
      output.WriteFloat(0.)
      output.WriteFloat(-1.)
      output.WriteInt32(0xFF404040)
      return

    if has_shadow == HAS_BELOW_SHADOW:
      output.WriteByte(CMD_PICTURE_PAINT_SHADOW)
      output.WriteFloat(4.)
      output.WriteFloat(0.)
      output.WriteFloat(2.)
      output.WriteInt32(0xFF292929)

  def _ConvertStyle(self, style, output):
    if style == 'fill':
      output.WriteByte(CMD_PICTURE_PAINT_STYLE)
      output.WriteByte(0)
      return

    if style == 'stroke':
      output.WriteByte(CMD_PICTURE_PAINT_STYLE)
      output.WriteByte(1)
      return

    logging.critical('unknown style: %s', style)
    sys.exit(1)

  def _MaybeConvertColor(self, color, output):
    if color is None:
      return
    output.WriteByte(CMD_PICTURE_PAINT_COLOR)
    output.WriteInt32(color)

  def _MaybeConvertShader(self, shader, output):
    if shader is None:
      return

    output.WriteByte(CMD_PICTURE_PAINT_SHADER)
    if shader[0] == 'linear':
      output.WriteByte(CMD_PICTURE_SHADER_LINEAR_GRADIENT)
      for coord in shader[1:5]:
        output.WriteFloat(coord)

      output.WriteByte(len(shader[5]))
      for _, color in shader[5]:
        output.WriteInt32(color)
      for offset, _ in shader[5]:
        output.WriteFloat(offset)
      return

    if shader[0] == 'radial':
      output.WriteByte(CMD_PICTURE_SHADER_RADIAL_GRADIENT)
      for coord in shader[1:4]:
        output.WriteFloat(coord)

      # Output matrix.
      if shader[4] is None:
        output.WriteByte(0)
      else:
        output.WriteByte(1)
        for coord in shader[4]:
          output.WriteFloat(coord)

      output.WriteByte(len(shader[5]))
      for _, color in shader[5]:
        output.WriteInt32(color)
      for offset, _ in shader[5]:
        output.WriteFloat(offset)
      return

    logging.critical('unknown shader: %s', shader[0])
    sys.exit(1)

  def _MaybeConvertStrokeWidth(self, stroke_width, output):
    if stroke_width is None:
      return

    output.WriteByte(CMD_PICTURE_PAINT_STROKE_WIDTH)
    output.WriteFloat(stroke_width)

  def _MaybeConvertStrokeLinecap(self, stroke_linecap, output):
    if stroke_linecap is None:
      return

    if stroke_linecap == 'round':
      output.WriteByte(CMD_PICTURE_PAINT_STROKE_CAP)
      output.WriteByte(1)
      return
    if stroke_linecap == 'square':
      output.WriteByte(CMD_PICTURE_PAINT_STROKE_CAP)
      output.WriteByte(2)
      return

    logging.critical('unknown stroke-linecap: %s', stroke_linecap)
    sys.exit(1)

  def _MaybeConvertStrokeLinejoin(self, stroke_linejoin, output):
    if stroke_linejoin is None:
      return

    if stroke_linejoin == 'round':
      output.WriteByte(CMD_PICTURE_PAINT_STROKE_JOIN)
      output.WriteByte(1)
      return

    if stroke_linejoin == 'bevel':
      output.WriteByte(CMD_PICTURE_PAINT_STROKE_JOIN)
      output.WriteByte(2)
      return

    logging.critical('unknown stroke-linejoin: %s', stroke_linejoin)
    sys.exit(1)

  def _ConvertStyleMap(self, style_map, output):
    self._ConvertStyle(style_map['style'], output)
    self._MaybeConvertColor(style_map.get('color'), output)
    self._MaybeConvertShader(style_map.get('shader'), output)
    self._MaybeConvertShadow(style_map['shadow'], output)
    self._MaybeConvertStrokeWidth(style_map.get('stroke-width'), output)
    self._MaybeConvertStrokeLinecap(style_map.get('stroke-linecap'), output)
    self._MaybeConvertStrokeLinejoin(style_map.get('stroke-linejoin'), output)
    output.WriteByte(CMD_PICTURE_PAINT_EOP)

  def _ConvertStyleList(self, style_list, output):
    output.WriteByte(len(style_list))
    for style_map in style_list:
      self._ConvertStyleMap(style_map, output)

  def _ConvertStyleCategory(self, style_category, output):
    output.WriteByte(1)
    for id_prefix, category in STYLE_CATEGORY_MAP:
      if style_category.startswith(id_prefix):
        output.WriteByte(STYLE_CATEGORY_TAG + category)
        return
    logging.critical('unknown style_category: "%s"', style_category)
    sys.exit(1)

  def _ConvertPath(self, node, output):
    path = node.get('d')
    if path is None:
      logging.critical('Unknown path')
      sys.exit(1)

    prev_control = None
    prev = None
    command_list = []
    prev_command = None
    while True:
      path = path.strip()
      if not path:
        break

      if path[0] in 'mMcCsShHvVlLzZ':
        # If the head character of path is one of the command prefix
        # characters, use the character as the command and consume it.
        command = path[0]
        path = path[1:]
      else:
        # If not, use prev_command as command
        # in order to support continuous commands.
        command = prev_command

      if command == 'm' or command == 'M':
        # Move command.
        (x, y), path = self._ConsumeFloatList(path, 2)
        if command == 'm' and prev is not None:
          x += prev[0]
          y += prev[1]
        command_list.append((CMD_PICTURE_PATH_MOVE, x, y))
        prev = (x, y)
        prev_control = None
        start = (x, y)
        # Subsequent coordinates are treated as implicit
        # lineto (l or L) commands.
        prev_command = 'l' if command == 'm' else 'L'
        continue

      if command == 'c' or command == 'C':
        # Cubic curve.
        (x1, y1, x2, y2, x, y), path = self._ConsumeFloatList(path, 6)
        if command == 'c':
          x1 += prev[0]
          y1 += prev[1]
          x2 += prev[0]
          y2 += prev[1]
          x += prev[0]
          y += prev[1]
        command_list.append((CMD_PICTURE_PATH_CURVE, x1, y1, x2, y2, x, y))
        prev = (x, y)
        prev_control = (x2, y2)
        prev_command = command
        continue

      if command == 's' or command == 'S':
        # Continued cubic curve.
        (x2, y2, x, y), path = self._ConsumeFloatList(path, 4)
        if command == 's':
          x2 += prev[0]
          y2 += prev[1]
          x += prev[0]
          y += prev[1]
        # if prev_control is not None:
        #   x1 = 2 * prev[0] - prev_control[0]
        #   y1 = 2 * prev[1] - prev_control[1]
        # else:
        #   x1, y1 = prev
        command_list.append((CMD_PICTURE_PATH_CONTINUED_CURVE, x2, y2, x, y))
        prev = (x, y)
        prev_control = (x2, y2)
        prev_command = command
        continue

      if command == 'h' or command == 'H':
        # Horizontal line.
        x, path = self._ConsumeFloat(path)
        if command == 'h':
          x += prev[0]
        y = prev[1]
        command_list.append((CMD_PICTURE_PATH_HORIZONTAL_LINE, x))
        prev = (x, y)
        prev_control = None
        prev_command = command
        continue

      if command == 'v' or command == 'V':
        # Vertical line.
        y, path = self._ConsumeFloat(path)
        if command == 'v':
          y += prev[1]
        x = prev[0]
        command_list.append((CMD_PICTURE_PATH_VERTICAL_LINE, y))
        prev = (x, y)
        prev_control = None
        prev_command = command
        continue

      if command == 'l' or command == 'L':
        # Line.
        (x, y), path = self._ConsumeFloatList(path, 2)
        if command == 'l':
          x += prev[0]
          y += prev[1]
        command_list.append((CMD_PICTURE_PATH_LINE, x, y))
        prev = (x, y)
        prev_control = None
        prev_command = command
        continue

      if command == 'z' or command == 'Z':
        # Close the path.
        command_list.append((CMD_PICTURE_PATH_CLOSE,))
        path = path
        prev = start
        prev_control = None
        prev_command = command
        continue

      logging.critical('Unknown command: %s', path)
      sys.exit(1)

    command_list.append((CMD_PICTURE_PATH_EOP,))

    # Output.
    output.WriteByte(CMD_PICTURE_DRAW_PATH)
    for command in command_list:
      output.WriteByte(command[0])
      for coord in command[1:]:
        output.WriteFloat(coord)

  def _ConvertPathElement(
      self, node, style_category, has_shadow, shader_map, output):
    style_list = self._ParseStyle(node, has_shadow, shader_map)
    self._ConvertPath(node, output)
    if style_category is not None:
      self._ConvertStyleCategory(style_category, output)
    else:
      self._ConvertStyleList(style_list, output)

  def _ConvertPolylineElement(
      self, node, style_category, has_shadow, shader_map, output):
    point_list = self._ParseFloatList(node.get('points'))
    if len(point_list) < 2:
      logging.critical('Invalid point number.')
      sys.exit(1)
    style_list = self._ParseStyle(node, has_shadow, shader_map)

    output.WriteByte(CMD_PICTURE_DRAW_POLYLINE)
    output.WriteByte(len(point_list))
    for coord in point_list:
      output.WriteFloat(coord)
    if style_category is not None:
      self._ConvertStyleCategory(style_category, output)
    else:
      self._ConvertStyleList(style_list, output)

  def _ConvertPolygonElement(
      self, node, style_category, has_shadow, shader_map, output):
    style_list = self._ParseStyle(node, has_shadow, shader_map)
    point_list = self._ParseFloatList(node.get('points'))

    output.WriteByte(CMD_PICTURE_DRAW_POLYGON)
    output.WriteByte(len(point_list))
    for coord in point_list:
      output.WriteFloat(coord)
    if style_category is not None:
      self._ConvertStyleCategory(style_category, output)
    else:
      self._ConvertStyleList(style_list, output)

  def _ConvertLineElement(
      self, node, style_category, has_shadow, shader_map, output):
    style_list = self._ParseStyle(node, has_shadow, shader_map)
    x1 = float(node.get('x1'))
    y1 = float(node.get('y1'))
    x2 = float(node.get('x2'))
    y2 = float(node.get('y2'))
    output.WriteByte(CMD_PICTURE_DRAW_LINE)
    output.WriteFloat(x1)
    output.WriteFloat(y1)
    output.WriteFloat(x2)
    output.WriteFloat(y2)
    if style_category is not None:
      self._ConvertStyleCategory(style_category, output)
    else:
      self._ConvertStyleList(style_list, output)

  def _ConvertCircleElement(
      self, node, style_category, has_shadow, shader_map, output):
    style_list = self._ParseStyle(node, has_shadow, shader_map)
    cx = float(node.get('cx'))
    cy = float(node.get('cy'))
    r = float(node.get('r'))
    output.WriteByte(CMD_PICTURE_DRAW_CIRCLE)
    output.WriteFloat(cx)
    output.WriteFloat(cy)
    output.WriteFloat(r)
    if style_category is not None:
      self._ConvertStyleCategory(style_category, output)
    else:
      self._ConvertStyleList(style_list, output)

  def _ConvertEllipseElement(
      self, node, style_category, has_shadow, shader_map, output):
    style_list = self._ParseStyle(node, has_shadow, shader_map)
    cx = float(node.get('cx'))
    cy = float(node.get('cy'))
    rx = float(node.get('rx'))
    ry = float(node.get('ry'))
    output.WriteByte(CMD_PICTURE_DRAW_ELLIPSE)
    output.WriteFloat(cx)
    output.WriteFloat(cy)
    output.WriteFloat(rx)
    output.WriteFloat(ry)
    if style_category is not None:
      self._ConvertStyleCategory(style_category, output)
    else:
      self._ConvertStyleList(style_list, output)

  def _ConvertRectElement(
      self, node, style_category, has_shadow, shader_map, output):
    style_list = self._ParseStyle(node, has_shadow, shader_map)
    x = float(node.get('x', 0))
    y = float(node.get('y', 0))
    w = float(node.get('width'))
    h = float(node.get('height'))
    output.WriteByte(CMD_PICTURE_DRAW_RECT)
    output.WriteFloat(x)
    output.WriteFloat(y)
    output.WriteFloat(w)
    output.WriteFloat(h)
    if style_category is not None:
      self._ConvertStyleCategory(style_category, output)
    else:
      self._ConvertStyleList(style_list, output)

  def _ConvertGroupElement(
      self, node, style_category, has_shadow, shader_map, output):

    transform = node.get('transform')
    if transform:
      # Output order of 3x3 matrix;
      # [ 0 3 6
      #   1 4 7
      #   2 5 8 ]
      # - Combined transformation is not supported yet.
      # - Only 'matrix' and 'translate' transformation is supported.
      transform_match = TRANSFORM_PATTERN.match(transform)
      if transform_match is None:
        logging.critical('Unsupported transform: %s', transform)
        sys.exit(1)
      transformation = transform_match.group(1)
      coords = transform_match.group(2)

      output.WriteByte(CMD_PICTURE_DRAW_GROUP_START)

      if transformation == 'matrix':
        (m11, m21, m12, m22, m13, m23) = tuple(self._ParseFloatList(coords))
        output.WriteFloat(m11)
        output.WriteFloat(m21)
        output.WriteFloat(0)
        output.WriteFloat(m12)
        output.WriteFloat(m22)
        output.WriteFloat(0)
        output.WriteFloat(m13)
        output.WriteFloat(m23)
        output.WriteFloat(1)
      elif transformation == 'translate':
        (tx, ty) = tuple(self._ParseFloatList(coords))
        output.WriteFloat(1)
        output.WriteFloat(0)
        output.WriteFloat(0)
        output.WriteFloat(0)
        output.WriteFloat(1)
        output.WriteFloat(0)
        output.WriteFloat(tx)
        output.WriteFloat(ty)
        output.WriteFloat(1)
      else:
        # Never reach here. Just in case.
        logging.critical('Unsupported transform: %s', transform)
        sys.exit(1)

    for child in node:
      self._ConvertPictureSequence(
          child, style_category, has_shadow, shader_map, output)

    if transform:
      output.WriteByte(CMD_PICTURE_DRAW_GROUP_END)

  def _ConvertPictureSequence(
      self, node, style_category, has_shadow, shader_map, output):
    # Hack. To support shadow, we use 'id' attribute.
    # If the 'id' starts with 'shadow', it means the element and its children
    # has shadow.
    nodeid = node.get('id', '')
    if nodeid.startswith('shadow'):
      has_shadow = HAS_SHADOW
    elif nodeid.startswith('below_x5F_shadow'):
      has_shadow = HAS_BELOW_SHADOW

    if nodeid.startswith('style-'):
      style_category = nodeid

    if node.tag == '{http://www.w3.org/2000/svg}path':
      self._ConvertPathElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag == '{http://www.w3.org/2000/svg}polyline':
      self._ConvertPolylineElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag == '{http://www.w3.org/2000/svg}polygon':
      self._ConvertPolygonElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag == '{http://www.w3.org/2000/svg}line':
      self._ConvertLineElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag == '{http://www.w3.org/2000/svg}circle':
      self._ConvertCircleElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag == '{http://www.w3.org/2000/svg}ellipse':
      self._ConvertEllipseElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag == '{http://www.w3.org/2000/svg}rect':
      self._ConvertRectElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag in ['{http://www.w3.org/2000/svg}g',
                    '{http://www.w3.org/2000/svg}svg']:
      self._ConvertGroupElement(
          node, style_category, has_shadow, shader_map, output)
      return

    if node.tag in ['{http://www.w3.org/2000/svg}linearGradient',
                    '{http://www.w3.org/2000/svg}radialGradient']:
      return

    logging.warning('Unknown element: %s', node.tag)

  def _OutputEOP(self, output):
    output.WriteByte(CMD_PICTURE_EOP)

  def _ConvertPictureDrawableInternal(self, tree, output):
    output.WriteByte(DRAWABLE_PICTURE)
    shader_map = self._ParseShaderMap(tree.getroot())
    self._ConvertSize(tree, output)
    self._ConvertPictureSequence(
        tree.getroot(), None, NO_SHADOW, shader_map, output)
    self._OutputEOP(output)

  # Interface for drawable conversion.
  def ConvertPictureDrawable(self, path):
    output = _OutputStream(StringIO.StringIO())
    self._ConvertPictureDrawableInternal(ElementTree.parse(path), output)
    return output.output.getvalue()

  def ConvertStateListDrawable(self, drawable_source_list):
    output = _OutputStream(StringIO.StringIO())
    output.WriteByte(DRAWABLE_STATE_LIST)
    output.WriteByte(len(drawable_source_list))
    for (state_list, path) in drawable_source_list:
      # Output state.
      output.WriteByte(len(state_list))
      for state in state_list:
        output.WriteInt32(state)

      # Output drawable.
      self._ConvertPictureDrawableInternal(ElementTree.parse(path), output)
    return output.output.getvalue()


def ConvertFiles(svg_dir, output_dir):
  """Converts SVG files into MechaMozc specific *pic* files.

  Args:
    svg_dir: Path to a directory which has svg files (recursively).
    output_dir: Path of the destination directory.
  """
  logging.debug('Start SVG conversion. From:%s, To:%s', svg_dir, output_dir)
  # Ensure that the output directory exists.
  if not os.path.exists(output_dir):
    os.makedirs(output_dir)

  converter = MozcDrawableConverter()
  number_of_conversion = 0
  for dirpath, dirnames, filenames in os.walk(svg_dir):
    for filename in filenames:
      basename, ext = os.path.splitext(filename)
      if ext != '.svg':
        # Do nothing for files other than svg.
        continue

      # Filename hack to generate stateful .pic files.
      if basename.endswith('_release') or basename.endswith('_selected'):
        # 'XXX_release.svg' files will be processed with corresponding
        # '_center.svg' files. So just skip them.
        # As similar to it, '_selected.svg' files will be processed with
        # corresponding non-selected .svg files.
        continue

      if basename == 'keyboard_fold_tab_up':
        # 'keyboard_fold_tab_up.svg' file will be processed with
        # 'keyboard_fold_tab_down.svg.' Just skip it, too.
        continue

      logging.debug('Converting %s...', filename)

      if basename.endswith('_center'):
        # Process '_center.svg' file with '_release.svg' file to make
        # stateful drawable.
        center_svg_file = os.path.join(dirpath, filename)
        release_svg_file = os.path.join(
            dirpath, basename[:-7] + '_release.svg')
        pic_file = os.path.join(output_dir, basename + '.pic')
        pic_data = converter.ConvertStateListDrawable(
            [([STATE_PRESSED], center_svg_file), ([], release_svg_file)])
      elif os.path.exists(os.path.join(dirpath, basename + '_selected.svg')):
        # Process '_selected.svg' file at the same time if necessary.
        unselected_svg_file = os.path.join(dirpath, filename)
        selected_svg_file = os.path.join(dirpath, basename + '_selected.svg')
        pic_file = os.path.join(output_dir, basename + '.pic')
        pic_data = converter.ConvertStateListDrawable(
            [([STATE_SELECTED], selected_svg_file), ([], unselected_svg_file)])
      elif basename == 'keyboard_fold_tab_down':
        # Special hack for keyboard__fold__tab.pic.
        down_svg_file = os.path.join(dirpath, filename)
        up_svg_file = os.path.join(dirpath, 'keyboard_fold_tab_up.svg')
        pic_file = os.path.join(output_dir, 'keyboard__fold__tab.pic')
        pic_data = converter.ConvertStateListDrawable(
            [([STATE_CHECKED], up_svg_file), ([], down_svg_file)])
      else:
        # Normal .svg file.
        svg_file = os.path.join(dirpath, filename)
        pic_file = os.path.join(output_dir, basename + '.pic')
        pic_data = converter.ConvertPictureDrawable(svg_file)

      with open(pic_file, 'wb') as stream:
        stream.write(pic_data)
      number_of_conversion += 1
  logging.debug('%d files are converted.', number_of_conversion)


def ParseOptions():
  parser = optparse.OptionParser()
  parser.add_option('--svg_dir', dest='svg_dir',
                    help='Path to a directory containing .svg files.')
  parser.add_option('--output_dir', dest='output_dir',
                    help='Path to the output directory,')
  parser.add_option('--verbose', '-v', dest='verbose',
                    action='store_true', default=False,
                    help='Shows verbose message.')
  return parser.parse_args()[0]


def main():
  logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
  logging.getLogger().addFilter(util.ColoredLoggingFilter())

  options = ParseOptions()
  if options.verbose:
    logging.getLogger().setLevel(logging.DEBUG)
  ConvertFiles(options.svg_dir, options.output_dir)


if __name__ == '__main__':
  main()
