#include <stdio.h>
#include <cv.h>
#include <highgui.h>

int drawing,line;
CvPoint start;
IplImage *tmp,*screen;

void circle_with_flag(IplImage *image,int flag,CvPoint p){
	CvScalar color;
	// flagsでカラーを変更
	switch(flag){
	case CV_EVENT_FLAG_CTRLKEY:
		color = CV_RGB(255,0,0);
		break;
	case CV_EVENT_FLAG_SHIFTKEY:
		color = CV_RGB(0,255,0);
		break;
	case CV_EVENT_FLAG_ALTKEY:
		color = CV_RGB(0,0,255);
		break;
	default:
		color = CV_RGB(0,0,0);
	}
	// 円を半径5,中身を塗って描く
	return cvCircle(image,p,5,color,CV_FILLED,8,0);
}

void line_with_flag(IplImage *image,int flag,CvPoint p){
	CvScalar color;
	/*screenにlineモードに入る直前のイメージをコピー*/
	cvCopy(tmp,screen,NULL);

	switch(flag){
	case CV_EVENT_FLAG_CTRLKEY:
		// 赤で線を描く
		color = CV_RGB(255,0,0);
		cvLine(screen,start,p,color,2,8,0);
		break;
	case CV_EVENT_FLAG_SHIFTKEY:
		// 水色で四角を描く
		color = CV_RGB(0,255,255);
		cvRectangle(screen,start,p,color,2,8,0);
		break;
	default:  // 黒で線を描く
		color = CV_RGB(0,0,0);
		cvLine(screen,start,p,color,2,CV_AA,0);
	}
}

void onMouse(int event,int x,int y,int flags,void *param){
	IplImage *screen = (IplImage *)param;
	switch(event){
	case CV_EVENT_MOUSEMOVE:
		
		if (drawing) // drawingモードならば 点を描く
			circle_with_flag(screen,flags-1,cvPoint(x,y));
		else if(line) // lineモードならば 線 or 四角を描く
			line_with_flag(screen,flags - 2,cvPoint(x,y));
		break;
	case CV_EVENT_LBUTTONDOWN: 
		// drawingモードに入る
		drawing = 1; 
		break;
	case CV_EVENT_LBUTTONUP:
		//drawingモードから抜ける
		drawing = 0;
		break;
	case CV_EVENT_RBUTTONDOWN:
		/*lineモードに入る
		 lineが決定するまで(ドラッグ中)は、screenに書き込みたくないので
		 lineモードに入る前のscreenをtmpに保存しておく*/
		line = 1;
		start = cvPoint(x,y);
		cvCopy(screen,tmp,NULL);
		break;
	case CV_EVENT_RBUTTONUP:
		/*lineモードを終了する*/
		line = 0;
		break;
	}
	
}
int main(int argc,char *argv[]){
	CvFont font;
	int key;
	
	screen = cvCreateImage(cvSize(320,240),IPL_DEPTH_8U,3);
	tmp = cvCreateImage(cvSize(320,240),IPL_DEPTH_8U,3);
	

	//背景を白色にする
	cvSet(screen,cvScalarAll(255),NULL);

	cvNamedWindow("drawing",1);
	//マウスのイベントはonMouse関数へ飛ぶ
	cvSetMouseCallback("drawing",onMouse,(void*)screen);

	// フォントを初期化して、screenに対して書き込み
	cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX ,1.0f,1.0f,0,2,8);
	cvPutText(screen,"Hello,OpenCV",cvPoint(10,30),&font,CV_RGB(255,0,0));
	
	while(1){ // キーボードからqが入力されるまで動く
		cvShowImage("drawing",screen);
		key = cvWaitKey(10);
		if(key == 'q')
			break;
	}
	cvReleaseImage(&screen);
	cvReleaseImage(&tmp);
	cvDestroyWindow("drawing");
	return 0;
}