/* 
 * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
 *
 * 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; version 2 of the
 * License.
 * 
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#include "image_figure.h"

using namespace wbfig;
using namespace base;

Image::Image(mdc::Layer *layer, FigureEventHub *hub, const model_ObjectRef &self) 
: BaseFigure(layer, hub, self), _image(layer)
{
  set_cache_toplevel_contents(false);
  set_accepts_focus();
  set_accepts_selection();
  set_allowed_resizing(true, true);

  add(&_image, true, true, false); 
  
  _image.set_auto_sizing(true);
  
  _keep_aspect_ratio= false;
}


static void constrain_aspect_ratio(mdc::ItemHandle *handle, Size &size, double ratio)
{
  if ((handle->get_tag() & (HDL_LEFT|HDL_RIGHT)) != 0)
    size.height= size.width/ratio;
  else
    size.width= size.height*ratio;
}


cairo_surface_t *Image::get_image()
{
  return _image.get_image();
}


void Image::keep_aspect_ratio(bool flag)
{
  _keep_aspect_ratio= flag;

  if (flag)
  {
    cairo_surface_t *surf= _image.get_image();

    if (surf)
    {
      double aspect= get_aspect_ratio();
      double width= _image.get_size().width;
      double new_height= width / aspect;

      if (fabs(_image.get_size().height-new_height) > 1)
        set_fixed_size(Size(width, new_height));

      set_drag_handle_constrainer(boost::bind(constrain_aspect_ratio, _1, _2, aspect));
    }
  }
  else
    set_drag_handle_constrainer(boost::function<void (mdc::ItemHandle*,Size&) >());
}


double Image::get_aspect_ratio()
{
  Size size= _image.get_image_size();

  return size.width / size.height;
}


void Image::set_image(cairo_surface_t *image)
{
  _image.set_image(image);
}


bool Image::set_image(const std::string &filename)
{
  return _image.set_image(filename);
}


void Image::set_allow_manual_resizing(bool flag)
{
  if (!flag && _image.auto_sizing())
  {
    // if auto-sizing is being disabled, set the fixed size to the current size, so that it 
    // has an initial size
    _image.set_fixed_size(_image.get_size());
  }
  _image.set_auto_sizing(!flag);

  if (!flag)
    relayout();
}

//--------------------------------------------------------------------------------------------------

bool Image::on_click(mdc::CanvasItem *target, const Point &point, mdc::MouseButton button, mdc::EventState state)
{
  if (!_hub->figure_click(represented_object(), target, point, button, state))
    return super::on_click(target, point, button, state);
  return false;
}

//--------------------------------------------------------------------------------------------------

bool Image::on_double_click(mdc::CanvasItem *target, const Point &point, mdc::MouseButton button, mdc::EventState state)
{
  if (!_hub->figure_double_click(represented_object(), target, point, button, state))
    return super::on_double_click(target, point, button, state);
  return false;
}

//--------------------------------------------------------------------------------------------------
