/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/**
 * @file RectDrawer.cpp
 * @brief RectDrawer.h の実装
 */
#include "stdafx.h"
#include "Common/RectDrawer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
//Implements mgRectDrawer Class.
//mgRectDrawer is a class to select(pick) objects.
//

//////////Constructor//////////

mgRectDrawer::mgRectDrawer(
	const MGColor& lineColor,
	float lineWidth
):mgVBOByScreen(-1.f),
m_targetWindow(0),m_lineColor(lineColor), m_lineWidth(lineWidth){
	;
}

mgRectDrawer::~mgRectDrawer(){
	detachFromWindow();
}

///pViewのwindowにこのmgRectDrawerをattachすると同時にmgVBOByScreenの
///set_viewport()を発信し、対象windowを確定する
void mgRectDrawer::attatchToWindow(
	fugenView* pView
){
	detachFromWindow();
	int vp[4];
	MGOpenGLView& glv=*pView;
	glv.get_viewport(vp);
	set_viewport(vp);

	bool nonCommon=false;
	glv.detach_drawer(this,nonCommon);//to avoid double attaching.
	glv.attach_drawer(this,nonCommon);
	set_no_display();
	m_targetWindow=pView;
}

bool mgRectDrawer::detachFromWindow(
){
	bool detached=false;
	if(m_targetWindow){
		bool nonCommon=false;
		m_targetWindow->detach_drawer(this,nonCommon);
		detached=true;
	}
	m_targetWindow=0;
	return detached;
}

///windowのbutton_down_point()とmousemove_new_point()により四角形の点をupdateする
void mgRectDrawer::updateRectangle(
){
	const CPoint& start=m_targetWindow->button_down_point();
	const CPoint& end=m_targetWindow->mousemove_new_point();
	updateRectangle(start,end);
}

///左上を原点とするwindow座標系の2点を入力して四角形の点をupdateする
void mgRectDrawer::updateRectangle(
	const CPoint& P1, const CPoint& P2
){
	int height=int(getHeight()+.5);
	int sxy1[2]={P1.x,height-P1.y};
	int sxy2[2]={P2.x,height-P2.y};
	updateRectangle(sxy1,sxy2);
}

///左下を原点とするwindow座標系の2点を入力して四角形の点をupdateする
void mgRectDrawer::updateRectangle(
	const int sxy1[2],	///<対象Windowの頂点のひとつを入力する
	const int sxy2[2]	///<対象Windowの頂点のふたつめを入力する
){
	int sx1=sxy1[0];
	int sy1=sxy1[1];
	int sx2=sxy2[0];
	int sy2=sxy2[1];

	///Compute factor and replace the min/max so that sx1<=sx2, sy1<=sy2;
	short int factor=0;
	if(sx1>sx2){
		factor=4;
		int sx1Save=sx1;
		sx1=sx2;
		sx2=sx1Save;
	}
	if(sy1>sy2){
		int sy1Save=sy1;
		sy1=sy2;
		sy2=sy1Save;
	}

	float x1,y1;
	convert2NormalizedWorld(float(sx1),float(sy1),x1,y1);
	float x2,y2;
	convert2NormalizedWorld(float(sx2),float(sy2),x2,y2);
	if(!is_made()){
		set_ZValue(-1.f);
		makeRectangle(x1,y1,x2,y2);
	}else{
		float rectData[12]={x1,y1,-1.f,x2,y1,-1.f,x2,y2,-1.f,x1,y2,-1.f};
		mgVBOLeaf* rectangle=static_cast<mgVBOLeaf*>(back().get());
		rectangle->updateVertices(0,4,rectData);
	}
	setLineStipple(factor,0x5555);
	set_display();
	setDirty(false);
}

///NDC座標値で左下(x1,y1)と右上(x2,y2)のデータを与えて四角形描画データを作成する
void mgRectDrawer::makeRectangle(float x1,float y1, float x2,float y2){
	Begin(GL_LINE_LOOP);
		mgVBO::Vertex(x1,y1);
		mgVBO::Vertex(x2,y1);
		mgVBO::Vertex(x2,y2);
		mgVBO::Vertex(x1,y2);
	End();
	setStaticAttribColor(m_lineColor);
	setStaticAttribLineWidth(m_lineWidth);
}
