#include "filterview.h"

#include <Window.h>
#include <Point.h>
#include <Message.h>
#include <math.h>
#include <Handler.h>

#define DEBUG 1
#include <Debug.h>

myFilter::myFilter(BView *newTarget) : BMessageFilter(B_MOUSE_DOWN) {
	target=newTarget;
}

filter_result myFilter::Filter(BMessage *msg, BHandler **handlr) {
	PRINT(("\nCAUGHT! | "));
	DEBUG_ONLY(fflush(stdout););
	//tell the filterview the intended target for comparison later
	dynamic_cast<filterview*>(target)->SetDestView(*handlr);
	//alter the pointer
	*handlr = target;
	//then send it along on its merry way
	return B_DISPATCH_MESSAGE;
}

filterview::filterview(BRect r, const char* name, long unsigned int type, long unsigned int flags) :
	BView(r, name, type, flags),
	mClickCount(0),
	mLastButton(0)
{
	myView = new BView(BRect(0,0,Bounds().right/2, Bounds().bottom), "nameless", B_FOLLOW_ALL, 0);
	AddChild(myView);
	notMyView = new BView(BRect(Bounds().right/2+1, 0, Bounds().right, Bounds().bottom), "nameless too", B_FOLLOW_ALL, 0);
	AddChild(notMyView);
}

void filterview::AttachedToWindow() {
	Looper()->AddCommonFilter(new myFilter(this));
	Looper()->Lock();
	notMyView->SetViewColor(200,200,200);
	Looper()->Unlock();
}

void filterview::MouseDown(BPoint point) {
	BMessage* msg = Window()->CurrentMessage();
	int32 clicks = msg->FindInt32("clicks");
	int32 button = msg->FindInt32("buttons");
	
	PRINT(("button: %d  clicks: %d\n", button, clicks));
	
	//test continuity -----
	
	//condition 1: the same view got both clicks
	bool viewsMatch = false;
	if (mLastView == mDestView) { 
		PRINT(("Condition 1 met: %x=%x | \n", mLastView, mDestView));
		viewsMatch = true;
	} else { //the views don't match
		mLastView = mDestView;	// reset the last view's address
		mClickCount = 1;		// it's the first click in that view
		firstclick = point;		// it's a new point within that view too
	}
	
	//condition 2: the buttons match 
	if (button == mLastButton) { 
		PRINT(("Condition 2 met: %d equaled %d | \n", button, mLastButton));
		//condition 3: the system reports a multiclick
		if ((clicks > 1) && viewsMatch) { 
			PRINT(("Condition 3 met: clicks=%d | \n", clicks));
			mClickCount++;
		}
	} else { //if the buttons don't match
		mLastButton = button;	// record it if it's different
		mClickCount = 1;		// no, it's the first click of a new button
		firstclick = point;		// record the point for comparison
	}

	//a test for bad aim
	bool closeenough = false; 
	if ((abs(int32(point.x - firstclick.x)) < 4)
		&& (abs(int32(point.y-firstclick.y)) < 4)) //condition: within 4 pixels
	{
		closeenough = true;
	} DEBUG_ONLY(else {
		PRINT(("Not close enough"));
	}
	);

	//combine the results
	if (closeenough && (mClickCount > 1)) {
		PRINT((" multiple click detected | \n"));
		BFont font;
		font.SetRotation(90.0);
		mDestView->SetFont(&font, B_FONT_ROTATION);
		mDestView->DrawString("MultipleClick detected", BPoint(16,60));
		//figure out how to erase
		
	} else { //either there was not a mutliple click going on, or they moved too far
		PRINT(("nope"));
	}
	DEBUG_ONLY(fflush(stdout););
}

void filterview::SetDestView(void* last) {
	mDestView=static_cast<BView*>(last);
	PRINT(("Last View set to %x | ", mDestView));
}
