///////////////////////////////////////////////////////////////////////////////////////////
// Authors: Jonathan Poole, Jonathan Fazakerley
// canvas.h
// JPC36 Wx-View
// July 25th 2000
// Technical Advisor : Carlos Moreno
///////////////////////////////////////////////////////////////////////////////////////////

#ifndef __CANVAS_H__
#define __CANVAS_H__

#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "wx/file.h"
#include <wx/image.h>
#include <wx/bitmap.h>
#include <wx/dc.h>

#include <algorithm>
#include <cmath>
#include <cctype>
using namespace std;


const double pi = 3.1415926535897932384626433832795;


class Canvas : public wxPanel
{
public:
	Canvas(wxFrame* parent, wxWindowID id, wxSize s);
	~Canvas();
		
	void on_paint (wxPaintEvent &);
	void undraw_rectangle();

	void on_size (wxSizeEvent &);	
	void on_left_up(wxMouseEvent& event);
	void on_left_down(wxMouseEvent& event);	
	void on_motion(wxMouseEvent& event);
    void on_move(wxMouseEvent& event);
	void on_leaving(wxMouseEvent& event);	

	void adjust_working_image();
		
	bool zoom_into_point(wxPoint & zoom_point);
	bool set_effective_zoom_point(wxPoint & zoom_point);
	bool set_point_zoom_sub_image_frame(double new_magnification);
	bool set_sub_image_with_rect_zoom(double scaling_factor);		
	wxImage * interpolate_image(wxImage * img, double extra_mag_factor);
	void set_working_image_to_sub_image();
	void magnify_working_image(double new_magnification, wxRect rect);
	void zoom_out_original(double new_magnification);	
	
	void load_file(const wxString & file);	
	void change_zoom_type(bool);
	void change_zoom_factor(double new_user_zoom);				
	void original();					
	void zoom_out();				
	void zoom_center();			
	void on_rotate();
	void on_h_flip();
	void on_v_flip();
	void on_bright();
	void on_dim ();
	void on_plus_contrast();
	void on_minus_contrast();	
	
	wxRect get_image_frame(const wxImage & img, double scale_to_screen);
	double get_scale_to_screen_factor(const wxImage & img);
	void scale_current_frame(double scaling_factor, const wxRect & frame);
	void shift_rect_into_rect(wxRect & small_rect, const wxRect & big_rect);
		
	void adjust_rotation_angle();	
	void switch_h_flip();
	void recreate_working_image();
	void flip_working_image();
	void rotate_working_image();	
	void resize_working_image();
	void draw_image(const wxImage & zoom, int x, int y);	
	void reset_image_parameters();
	void reset_initial_frame();
	
	void adjust_contrast_on_working_image();
	void adjust_brightness_on_working_image();	
	void reset_working_image_with_colour_settings();	
	
	void shift_left(double shift_percentage = 0);
	void shift_right(double shift_percentage = 0);	
	void shift_up(double shift_percentage = 0);	
	void shift_down(double shift_percentage = 0);
	
	void display_image(const wxString & file);
	void draw_rest_of_shifted_image (const wxRect & missing_area, const wxPoint & bm_pos);
	void draw_current_bitmap(int x, int y);
	
	void pop_up_menu(wxMouseEvent &event);
 	void on_key_down(wxKeyEvent & event);

private:
	int client_height, client_width;	

	wxImage* original_image;		
	wxImage* working_image;			
	wxBitmap* bm;		
		
	wxRect subimage_frame;				
	wxRect initial_frame;					
	wxRect current_frame;						
	wxRect drag_rect;				

	wxPoint prev_zoom_point;
	wxPoint subimage_center;
	wxPoint click_down;			
	
	double magnification;
	double scale_original_to_screen;
	double user_zoom;
			
	bool dragging_event;
	bool interpolating;
	bool h_flipped;
	bool point_zoom;
	
	int rotation_angle;
	int brightness;
	int clarity;	
			
	DECLARE_EVENT_TABLE()	
};

#endif
