/* -*- Mode: Vala; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */
/*
    Multiplication Puzzle
    Copyright (C) 2008,2011 Michael Terry <mike@mterry.name>

    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 3 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, see <http://www.gnu.org/licenses/>.
*/

using GLib;

public class DigitBox : CharBox
{
  public Canvas canvas { get; construct; }
  
  public DigitBox (Canvas canvas, string letter)
  {
    Object(canvas: canvas, letter: letter);
  }
  
  construct
  {
    this.border = Gtk.ShadowType.OUT;
    
    Gtk.TargetEntry[] entries = new Gtk.TargetEntry[1];
    entries[0].target = "STRING";
    entries[0].flags = Gtk.TargetFlags.SAME_APP;
    entries[0].info = 0;
    Gtk.drag_source_set (this, Gdk.ModifierType.BUTTON1_MASK, entries, Gdk.DragAction.MOVE);
    
    drag_data_get.connect(handle_drag_get);
    drag_begin.connect(handle_drag_begin);
    drag_end.connect(handle_drag_end);
    
    // Translators: If there's a better alternative to Arabic numerals for
    // your language, please use it instead of these digits.  Note
    // that it still has to make sense when used as part of the math puzzle.
    N_("0");
    N_("1");
    N_("2");
    N_("3");
    N_("4");
    N_("5");
    N_("6");
    N_("7");
    N_("8");
    N_("9");
  }
  
  private void handle_drag_begin (Gdk.DragContext context)
  {
    // Set mode, immediately invalidate/redraw ourselves to get new highlight
    canvas.set_mode (CanvasMode.DIGIT, this);
    get_window().invalidate_region (get_window().get_visible_region (), true);
    get_window().process_updates (true);
    
    // Make drag icon be identical to this widget
    int width, height;
    width = get_window().get_width();
    height = get_window().get_height();

    var surface = get_window().create_similar_surface(Cairo.Content.COLOR, width, height);
    Cairo.Context ctx = new Cairo.Context(surface);
    Gdk.cairo_set_source_window(ctx, get_window(), 0, 0);
    ctx.paint();

    int x, y;
    get_pointer (out x, out y);
    // Sometimes, if pointer has moved a lot since it started moving with drag,
    // x or y can be out of range.  This causes the drag icon to look odd.
    // So we clamp values to be safe.
    x = x.clamp(0, width);
    y = y.clamp(0, height);
    surface.set_device_offset(-x, -y);

    Gtk.drag_set_icon_surface (context, surface);
    
    hide ();
  }
  
  private void handle_drag_end (Gdk.DragContext context)
  {
    show ();
  }
  
  private void handle_drag_get (Gdk.DragContext context,
                                 Gtk.SelectionData data, uint info, uint time_)
  {
    data.set_text (letter, (int)letter.length);
  }
}

