// --------------------------------------------------------------------
// Overlay factory for object creators
// --------------------------------------------------------------------
/*

    This file is part of the extensible drawing editor Ipe.
    Copyright (C) 1993-2004  Otfried Cheong

    Ipe 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.

    As a special exception, you have permission to link Ipe with the
    CGAL library and distribute executables, as long as you follow the
    requirements of the Gnu General Public License in regard to all of
    the software in the executable aside from CGAL.

    Ipe 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 Ipe; if not, you can find it at
    "http://www.gnu.org/copyleft/gpl.html", or write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#include "ipemark.h"

#include "ipecanvas.h"
#include "ipeoverlay.h"
#include "ipecreatepath.h"
#include "ipecreatearc.h"
#include "ipecreatetext.h"

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

static const char *strings[4 * IpeOverlayFactory::Num] = {
  QT_TR_NOOP("Select objects (with Shift: non-destructively)"),
  "s", "Mode|Select",
  "select",
  QT_TR_NOOP("Move objects (with Shift: horizontal/vertical)"),
  "m", "Mode|Move",
  "move",
  QT_TR_NOOP("Rotate objects"),
  "r", "Mode|Rotate",
  "rotate",
  QT_TR_NOOP("Stretch objects (with Shift: scale objects)"),
  "e", "Mode|Stretch",
  "stretch",
  QT_TR_NOOP("Pan the canvas"),
  "none", "Mode|Pan",
  "pan",
  QT_TR_NOOP("Text labels"),
  "t", "Mode|Text labels",
  "label",
  QT_TR_NOOP("Mathematical symbols"),
  "$", "Mode|Mathematical symbols",
  "math",
  QT_TR_NOOP("Paragraphs"),
  "g", "Mode|Paragraphs",
  "paragraph",
  QT_TR_NOOP("Marks"),
  "k", "Mode|Marks",
  "marks",
  QT_TR_NOOP("Rectangles (with Shift: squares)"),
  "b", "Mode|Rectangles",
  "rectangles",
  QT_TR_NOOP("Lines and polylines"),
  "l", "Mode|Lines",
  "lines",
  QT_TR_NOOP("Polygons"),
  "p", "Mode|Polygons",
  "polygons",
  QT_TR_NOOP("Circular arcs (by center, right and left point)"),
  "a", "Mode|Circular arcs (center, right, left)",
  "arc1",
  QT_TR_NOOP("Circular arcs (by center, left and right point)"),
  "Shift+A", "Mode|Circular arcs (center, left, right)",
  "arc2",
  QT_TR_NOOP("Circular arcs (by 3 points)"),
  "Shift+Y", "Mode|Circular arcs (3 points)",
  "arc3",
  QT_TR_NOOP("Circles (by center and radius)"),
  "c", "Mode|Circles (center, radius)",
  "circle1",
  QT_TR_NOOP("Circles (by diameter)"),
  "Shift+D", "Mode|Circles (diameter)",
  "circle2",
  QT_TR_NOOP("Circles (by 3 points)"),
  "y", "Mode|Circles (3 points)",
  "circle3",
  QT_TR_NOOP("Splines"),
  "i", "Mode|Splines",
  "splines",
  QT_TR_NOOP("Splinegons"),
  "Shift+I", "Mode|Splinegons",
  "splinegons" };

const char *whatsThisText = QT_TR_NOOP(
"<qt>With these buttons you select the current Ipe <em>mode</em>. "
"The current mode determines the function of the left mouse button. "
"<p>The leftmost five buttons set modes for selecting and transforming "
"objects.  The remaining buttons set modes for creating various kinds "
"of objects.</p></qt>");

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

/*! \class IpeOverlayFactory
  \brief Creates the various overlays for creating objects.
*/

IpeOverlayFactory::IpeOverlayFactory(QMouseEvent *ev, IpeCanvas *canvas,
				     IpePage *page, int view,
				     IpeOverlayServices *services)
  : iEvent(ev), iCanvas(canvas), iPage(page), iView(view),
    iServices(services)
{
  // nothing
}

IpeOverlay *IpeOverlayFactory::StartTransforming(IpeTransforming::TType type)
{
  IpeTransforming *t = new IpeTransforming(iEvent, iPage, iView, iCanvas,
					   type, iServices);
  if (!t->FindObjects(iCanvas->SnapData().iSelectDistance)) {
    delete t;
    iCanvas->Message(QObject::tr("No object selected"));
    return 0;
  }
  return t;
}

//! Create a new overlay for the canvas.
void IpeOverlayFactory::CreateOverlay(int index)
{
  IpeOverlay *ov = MakeOverlay(index);
  // mark and label modes perform action immediately,
  // and return 0 for overlay
  if (ov)
    iCanvas->SetOverlay(ov);
}

//! Return appropriate object creator.
IpeOverlay *IpeOverlayFactory::MakeOverlay(int index)
{
  switch (index) {
  case ESelecting:
    return new IpeSelecting(iEvent, iPage, iView, iCanvas,
			    (iEvent->state() & QMouseEvent::ShiftButton),
			    iCanvas->SnapData().iSelectDistance,
			    iServices);
  case EPanning:
    return new IpePanning(iEvent, iPage, iCanvas);
  case EMoving:
    return StartTransforming(IpeTransforming::EMove);
  case ERotating:
    return StartTransforming(IpeTransforming::ERotate);
  case EStretching:
    if (iEvent->state() & QMouseEvent::ShiftButton)
      return StartTransforming(IpeTransforming::EScale);
    else
      return StartTransforming(IpeTransforming::EStretch);
  case ERectangle:
    return new IpeCreateRectangle(iEvent, iCanvas, iServices);
  case EPolyline:
    return new IpeCreatePath(iEvent, iCanvas, iServices, false, false);
  case EPolygon:
    return new IpeCreatePath(iEvent, iCanvas, iServices, true, false);
  case ESpline:
    return new IpeCreatePath(iEvent, iCanvas, iServices, false, true);
  case ESplinegon:
    return new IpeCreateSplinegon(iEvent, iCanvas, iServices);
  case ECircle1:
    return new IpeCreateCircle(iEvent, iCanvas, iServices,
			       IpeCreateCircle::ECenterRadius);
  case ECircle2:
    return new IpeCreateCircle(iEvent, iCanvas, iServices,
			       IpeCreateCircle::EDiameter);
  case ECircle3:
    return new IpeCreateCircle(iEvent, iCanvas, iServices,
			       IpeCreateCircle::E3Points);
  case EArc1:
    return new IpeCreateArc(iEvent, iCanvas, iServices,
			    IpeCreateArc::ECenterRightLeft);
  case EArc2:
    return new IpeCreateArc(iEvent, iCanvas, iServices,
			    IpeCreateArc::ECenterLeftRight);
  case EArc3:
    return new IpeCreateArc(iEvent, iCanvas, iServices,
			    IpeCreateArc::E3Points);
  case ELabel:
    IpeCreateText::New(iEvent, iCanvas, iServices, IpeCreateText::ELabel);
    return 0;
  case EMath:
    IpeCreateText::New(iEvent, iCanvas, iServices, IpeCreateText::EMath);
    return 0;
  case EParagraph:
    return new IpeCreateText(iEvent, iCanvas, iServices);
  case EMark:
    {
      iServices->OvSvcAddObject
	(new IpeMark(iServices->OvSvcAttributes(), iCanvas->Pos()));
      iCanvas->Update();
      return 0;
    }
  default:
    return 0;
  }
}

const char *IpeOverlayFactory::PixmapName(int index)
{
  return strings[4 * index + 3];
}

const char *IpeOverlayFactory::Tooltip(int index)
{
  return strings[4 * index + 0];
}

const char *IpeOverlayFactory::Shortcut(int index)
{
  return strings[4 * index + 1];
}

const char *IpeOverlayFactory::Context(int index)
{
  return strings[4 * index + 2];
}

const char *IpeOverlayFactory::WhatsThis(int)
{
  return whatsThisText;
}

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