#!/usr/bin/env python
##########################################################################
#
#  border.py           --  Add a border to an image in GIMP
#
#  $Id: border.py,v 1.1.0.1 2008/07/20 05:19:23 floyd Exp floyd $
#
#  See the ChangeLog for the RCS history log.
#
##########################################################################
#
#  Copyright 2008 by Floyd L. Davidson, floyd@apaflo.com
#  File created:  Mon Jul 10 23:51:27 2008
#  Last updated:  Mon Nov 21 23:27:42 2011
#
##########################################################################
#
#  This program is based on a similar Python script by Alexander Darovsky.
#
##########################################################################
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##########################################################################

from gimpfu import *

def python_borders(image, layer, \
                    inner,  inner_color,  inner_width, inner_height, \
                    median, median_color, median_width, median_height, \
                    outer,  outer_color,  outer_width, outer_height, \
                    offset_auto, offset_mag, offset_dir, \
                    outer_fill ):

    def create_border(name, width, height, color, off_auto, off_mag, off_dir, fill):
        original_layer = image.active_layer
        old_width      = pdb.gimp_image_width(image)
        old_height     = pdb.gimp_image_height(image)

        # Negative values do work, but this eliminates confusion
        if width < 0 or height < 0 or off_mag < 0:
          return
 
        if fill:
          # width and height are new image size, convert to border sizes
          width  = ( max( width,  old_width )  - old_width  ) / 2
          height = ( max( height, old_height ) - old_height ) / 2

          # width and height are border sizes
          new_width      = old_width   + (width  * 2)
          new_height     = old_height  + (height * 2)

          if offset_auto:
            if off_dir == "R":
              width      = max(height, 0)
            if off_dir == "B":
              height     = max(width, 0)
            if off_dir == "L":
              width      = width  + max(width - height, 0)
            if off_dir == "T":
              height     = height + max(height - width, 0)

          else:
            if off_dir == "R":
              width      = max(width   - off_mag, 0)
            if off_dir == "B":
              height     = max(height  - off_mag, 0)
            if off_dir == "L":
              width      = width  + off_mag
            if off_dir == "T":
              height     = height + off_mag

        else:

          # prevent insane values that lock up the cpu
          if width > (old_width / 3):
            width = old_width / 3

          if height > (old_height / 3):
            height = old_height / 3

          if off_mag > (max(old_width, old_height) / 3):
            off_mag = max(old_width, old_height) / 3

          # width and height are border sizes
          new_height     = old_height  + (height * 2)
          new_width      = old_width   + (width  * 2)

          if off_auto:
            if off_dir == "B":
              height     = width
            if off_dir == "R":
              width      = height
            if off_dir == "T":
              height     = height + height - width
            if off_dir == "L":
              width      = width + width - height
          else:
            if off_dir == "L" or off_dir == "R":
              new_width  = new_width  + off_mag
            if off_dir == "T" or off_dir == "B":
              new_height = new_height + off_mag
            if off_dir == "T":
              height     = height + off_mag
            if off_dir == "L":
              width      = width  + off_mag


        # new_width and new_height:    new image size
        # width and height:            border sizes

        pdb.gimp_image_resize(image, new_width, new_height, width, height)
        border = gimp.Layer(image, name, new_width, new_height, RGBA_IMAGE,
                           100, NORMAL_MODE)
        pdb.gimp_image_add_layer(image, border, 1)
#        pdb.gimp_image_insert_layer(image, border, None, 1)
        pdb.gimp_rect_select(image, 0, 0, new_width, new_height, CHANNEL_OP_REPLACE,  0, 0.0)

        pdb.gimp_context_set_foreground(color)
        pdb.gimp_edit_fill(border, FOREGROUND_FILL)
        pdb.gimp_selection_none(image)
        pdb.gimp_image_merge_down(image, original_layer, 0)

#
#  Process borders
#
    image.undo_group_start()

    mode = pdb.gimp_drawable_is_rgb(layer)

    if mode == False:
        pdb.gimp_image_convert_rgb(image)

    old_color = pdb.gimp_context_get_foreground()

    if inner and (inner_width > 0 or inner_height > 0):
        create_border('Inner Border', inner_width, inner_height, inner_color, 0, 0, "N", 0)

    if median and (median_width > 0 or median_height > 0):
        create_border('Median Border', median_width, median_height, median_color, 0, 0, "N", 0)

    if outer and (outer_width > 0 or outer_height > 0):
            create_border('Outer Border', outer_width, outer_height, outer_color, offset_auto, offset_mag, offset_dir, outer_fill)

    pdb.gimp_image_flatten(image)

    image.undo_group_end()

register(
        "python_fu_borders",
        N_("Add Borders"),
        """Add inner, median and outer border for image""",
        "Floyd Davidson",
        "GPL",
        "2008",
        N_("Borders-1"),
        "*",
        [
          (PF_IMAGE, "image",        "Input image", None),
          (PF_DRAWABLE, "layer",     "Input drawable", None),

          (PF_BOOL,  "inner",        "Use inner border",    True),
          (PF_COLOR, "inner_color",  "Inner Border Color", (255,  255,  255)),
          (PF_INT,   "inner_width",  "Inner Border Width",  3),
          (PF_INT,   "inner_height", "Inner Border Height", 3),

          (PF_BOOL,  "median",        "Use Median border",    True),
          (PF_COLOR, "median_color",  "Median Border Color", (0,  0,  0)),
          (PF_INT,   "median_width",  "Median Border Width",  5),
          (PF_INT,   "median_height", "Median Border Height", 5),

          (PF_BOOL,  "outer",        "Use outer border",    True),
          (PF_COLOR, "outer_color",  "Outer Border Color", (255,  255,  255)),
          (PF_INT,   "outer_width",  "Outer Border Width",  20),
          (PF_INT,   "outer_height", "Outer Border Height", 45),

          (PF_BOOL,  "offset_auto",  "Auto adjust offset",    True),
          (PF_INT,   "offset_mag",   "Outer Border Extension", 30),
          (PF_RADIO, "offset_dir",   "Direction of Extension", "B",
          (("Top",    "T"), ("Bottom", "B"), ("Left",   "L"), ("Right",  "R"))),

          (PF_BOOL,  "outer_fill",   "Outer border sizes are sizes of an image", False),
        ],
        [],
        python_borders,
        menu="/Python-Fu",
        domain=("gimp20-python", gimp.locale_directory)
  )

main()