#include "global.h" 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "config.h"
#include "varmacro.h"
#include CURSES_HEADER

#ifdef OLDGCCVARMACRO
#define DEBUGGING(var...) 
#else
#define DEBUGGING(...) 
#endif

#define MAXLEN 50
BEDPLUGIN
#define minnum(x,y) ((x)<(y)?(x):(y))
extern Editor *getselectioneditor(void);

class Editor {
#include "faked.h"
public:
int	searchclip(void) {
	char *ptr;
	int len=getselbuf(	&ptr);
	OFFTYPE startpos=getfilepos()+geteditpos();
	OFFTYPE fsize=filesize();
	if(len<=0) {
		message("Nothing in copy buffer");
		beep();
		return -1;
		}
	BLOCKTYPE BLOCKSIZE=blocksize();
	int takelen=minnum(len,BLOCKSIZE);
//	searchregex(0);
	for(;;){
		further:
		OFFTYPE res=dosearch(ptr,takelen);
		 if(res==OFFTYPEINVALID) {
		 	DEBUGGING("Not found");	
		 	topos(startpos);
			message("Content copy buffer not found");
			beep();
			return -1;
		 	}
		DEBUGGING("Found start "OFFPRINT,res);	
		char buf[BLOCKSIZE];
		int max=minnum(len,fsize-res);
		for(int pos=takelen;pos<max;pos+=BLOCKSIZE) {
			int size=minnum(BLOCKSIZE,max-pos);
			getmem(res+pos,buf,size);
			if(memcmp(buf,ptr+pos,size)) {
				DEBUGGING("partial match "OFFPRINT" to " OFFPRINT,res,pos );	
				gotolastsearchpos();
				goto further;	
				}
			}
		if(max<len) {
			message("Reached end of file matched for %ld bytes at "OFFPRINT,max,res);
			beep();
			return -1;
			}
		else 
			message("Found content copy buffer at "OFFPRINT " (#%ld)",res,len);
		topos(res);
		return 0;
		}
	
	}
int compare(void) {
	Editor *ed;
	if((ed=getselectioneditor())) {
		OFFTYPE len,start;
		if((len=ed->getselregion(&start))) {
			BLOCKTYPE BLOCKSIZE=blocksize();
			OFFTYPE curpos=getfilepos()+geteditpos();
			OFFTYPE fsize=filesize(),left=fsize-curpos;
			OFFTYPE end=minnum(len,left);
			for(OFFTYPE pos=0;pos<end;pos+=BLOCKSIZE) {
				char bufhere[BLOCKSIZE],bufthere[BLOCKSIZE];
				int size=minnum(BLOCKSIZE,end-pos);
				ed->getmem(start+pos,bufthere,size);
				getmem(curpos+pos,bufhere,size);
				if(memcmp(bufhere,bufthere,size)) {
					int j=0;
					for(;bufhere[j]==bufthere[j];j++)
						;
					message("Differ at offset " OFFPRINT " in selection, offset " OFFPRINT " in this file",pos+j,curpos+pos+j);
					return -1;
					}
				}
			if(len>left) {
				message("End of file reached in current file " OFFPRINT " bytes equal",fsize-curpos);
				return -2;
				}
			char name[512];
			message("Selection %s ("OFFPRINT") equal to "OFFPRINT"-"OFFPRINT".",ed->getfilename(name),start,curpos,curpos+len-1);
			return 0;

			}
		else 
			message("Can't find nonzero selection");
		}
	message("Can only used last made selection");
	return -3;
	}
#ifdef TEST
int testsclip(void) {
	int BLOCKSIZE=blocksize();
	char buf[BLOCKSIZE];
	OFFTYPE size=filesize(),iter;
	int error=0;
	srandom(time(NULL));
	for(iter=(OFFTYPE)0;iter<size;iter+=random()%100) {
		int len= minnum(random()%BLOCKSIZE,size-iter);
		getmem(iter,buf,(OFFTYPE)len);
		putselbuf(buf,len);
		topos((OFFTYPE)0);
		if(searchclip()<0) {
			getkeyinput("Didn't find "OFFPRINT "#%ld <press return>",iter,len);
			error++;
			}
		}
	message("%d errors",error);
	return error;
	}
#endif
};
sethelp(compare,"Compares last made selection with current file at current cursor\nposition for the length of that selection.\nIf some variant of klipper isn't running, there is no limit on selection\nsize (As long as they say to be of class klipper they form no problem,\nbecause I don't give the content of the whole selection to programs of\nclass klipper).")
call(compare)


sethelp(searchclip,"Searches in current file for the content the bed's copy buffer.\nIt takes over the search settings (direction, case sensitivity, regex or not,\non boundaries or not, from current position or from edge of file) of Alt-m,s.\nCurrently it repeatedly searches for the first block of the copy buffer\nand then compares it with the whole copy buffer.") 
call(searchclip)
#ifdef TEST
call(testsclip)
#endif
