// -*- Mode: c++; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil -*-
// NOTE: the first line of this file sets up source code indentation rules
// for Emacs; it is also a hint to anyone modifying this file.

// File         : the_curve_proc_ui.hxx
// Author       : Paul A. Koshevoy
// Created      : Sun Nov 27 16:00:00 MDT 2005
// Copyright    : (C) 2005
// License      : GPL.
// Description  : UI for the curve tool procedure.

#ifndef THE_CURVE_PROC_UI_HXX_
#define THE_CURVE_PROC_UI_HXX_

// system includes:
#include <list>

// local includes:
#include "ui_curve_tool.h"

// the includes:
#include <ui/the_procedure_ui.hxx>
#include <eh/the_document_eh.hxx>
#include <doc/the_document.hxx>
#include <sel/the_pick_list.hxx>
#include <sel/the_curve_selset.hxx>
#include <utils/instance_method_call.hxx>

// Qt includes:
#include <QObject>
#include <QDialog>
#include <QTimer>

// forward declarations:
class the_point_t;
class the_hard_point_t;
class the_intcurve_t;
class the_polyline_t;
class the_interpolation_bspline_t;
class the_graph_t;
class the_curve_proc_t;
class the_pick_list_t;
class the_curve_proc_ui_t;


//----------------------------------------------------------------
// the_curve_proc_eh_t
// 
class the_curve_proc_eh_t : public the_document_eh_t<the_document_t>
{
public:
  the_curve_proc_eh_t(the_document_ui_t * doc_ui);
  
  // virtual:
  const char * name() const
  { return "the_curve_proc_eh_t"; }
  
  // virtual: check if a given modifier is currently active:
  bool is_modifier_active_locally(the_eh_modifier_t mod) const;
  
  // virtual:
  float ep_offset(the_view_t * view) const;
  
  // virtual:
  const v3x1_t ep_normal(the_view_t * view) const;
  const p3x1_t ep_origin(the_view_t * view) const;
  
  // the UI will call this:
  void delete_something();
  
  void delete_points();
  void delete_curves();
  
  // helpers, shortcuts:
  inline the_registry_t * registry() const
  { return selset().registry(); }
  
  // helper functions:
  the_curve_proc_ui_t * proc_ui() const;
  the_curve_proc_t * proc() const;
  
  // accessors:
  the_curve_selset_t & selset() const;
  
  inline the_disp_list_t & wacom_dl()
  { return wacom_dl_; }
  
  // helper functions for managing the undo stack:
  void maybe_save_undo();
  void reset_save_undo();
  
protected:
  // virtual: Override the processor function.
  bool processor(the_input_device_eh_t::the_event_type_t event_type);
  
  // processor helper functions:
  bool process_mouse();
  bool process_wacom();
  
  // helper functions:
  void snap(the_pick_list_t & snap_targets,
	    the_pick_list_t & snap_rejects);
  
  the_hard_point_t * make_point(const p2x1_t & scs_pt);
  void add_point(the_intcurve_t * c, const p2x1_t & scs_pt);
  void add_tail(the_intcurve_t * c, const p2x1_t & scs_pt);
  the_intcurve_t * make_curve(std::list<p2x1_t> & scs_pts,
			      std::vector<double> & straightness);
  
  // FIXME: this is just for debugging:
  the_disp_list_t wacom_dl_;
  
  // a flag which indicates whether and undo record
  // has already been created:
  bool undo_saved_;
};

//----------------------------------------------------------------
// the_curve_proc_ui_t
// 
class the_curve_proc_ui_t : public QDialog,
			    public Ui::curve_tool,
			    public the_procedure_ui_t
{
  Q_OBJECT
public:
  the_curve_proc_ui_t(the_document_ui_t & doc_ui);
  ~the_curve_proc_ui_t();
  
  // this is used to redefine a procedure:
  void install(the_curve_proc_t * proc);
  
  // virtual: start/stop the ui:
  void install();
  void uninstall();
  
  // a speedup attempt (buffers multiple repaint requests):
  void request_repaint();
  
  // virtual: ui update mechanism:
  void sync_ui();
  
public slots:
  // virtual:
  void slot_coord_x();
  void slot_coord_y();
  void slot_coord_z();
  void slot_absolute();
  void slot_relative();
  
  void slot_unlink();
  void slot_crv_t_param();
  void slot_srf_u_param();
  void slot_srf_v_param();
  
  void slot_accept();
  void slot_cancel();
  
  void slot_edit_delete();
  
private slots:
  // this slot will be connected to the repaint timer:
  void slot_repaint();
  
protected:
  // virtual:
  void closeEvent(QCloseEvent * e);
  void moveEvent(QMoveEvent * e);
  void resizeEvent(QResizeEvent * e);
  
private:
  // helper functions:
  the_curve_proc_t * proc();
  
  // the event handler that will update the procedure:
  the_curve_proc_eh_t eh_;
  
  // this timer will be used to buffer OpenGL updates -- instead of
  // executing each repaint immediately the repaint will be carried
  // out after a timeout event:
  QTimer repaint_timer_;
  
  DECLARE_INSTANCE(the_curve_proc_ui_t, instance_);
};


#endif // THE_CURVE_PROC_UI_HXX_

