#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#include <keyboard.h>
#include <frame.h>
#include <fcall.h>
#include <plumb.h>
#include "dat.h"
#include "fns.h"

static Image *scrtmp;

static
Rectangle
scrpos(Rectangle r, uint p0, uint p1, uint tot)
{
	Rectangle q;
	int h;

	q = r;
	h = q.max.y-q.min.y;
	if(tot == 0)
		return q;
	if(tot > 1024*1024){
		tot>>=10;
		p0>>=10;
		p1>>=10;
	}
	if(p0 > 0)
		q.min.y += h*p0/tot;
	if(p1 < tot)
		q.max.y -= h*(tot-p1)/tot;
	if(q.max.y < q.min.y+2){
		if(q.min.y+2 <= r.max.y)
			q.max.y = q.min.y+2;
		else
			q.min.y = q.max.y-2;
	}
	return q;
}

void
scrlresize(void)
{
	freeimage(scrtmp);
	scrtmp = allocimage(display, Rect(0, 0, 32, screen->r.max.y), screen->chan, 0, DNofill);
	if(scrtmp == nil)
		error("scroll alloc");
}

void
textscrdraw(Text *t)
{
	Rectangle r, r1, r2;
	Image *b;

	if(t->w==nil || t!=&t->w->body)
		return;
	if(scrtmp == nil)
		scrlresize();
	r = t->scrollr;
	b = scrtmp;
	r1 = r;
	r1.min.x = 0;
	r1.max.x = Dx(r);
	r2 = scrpos(r1, t->org, t->org+t->fr.nchars, t->file->b.nc);
	if(!eqrect(r2, t->lastsr)){
		t->lastsr = r2;
		draw(b, r1, t->fr.cols[BORD], nil, ZP);
		draw(b, r2, t->fr.cols[BACK], nil, ZP);
		r2.min.x = r2.max.x-1;
		draw(b, r2, t->fr.cols[BORD], nil, ZP);
		draw(t->fr.b, r, b, nil, Pt(0, r1.min.y));
/*flushimage(display, 1);*//*BUG?*/
	}
}

void
scrsleep(uint dt)
{
	Timer	*timer;
	static Alt alts[3];

	timer = timerstart(dt);
	alts[0].c = timer->c;
	alts[0].v = nil;
	alts[0].op = CHANRCV;
	alts[1].c = mousectl->c;
	alts[1].v = &mousectl->m;
	alts[1].op = CHANRCV;
	alts[2].op = CHANEND;
	for(;;)
		switch(alt(alts)){
		case 0:
			timerstop(timer);
			return;
		case 1:
			timercancel(timer);
			return;
		}
}

void
textscroll(Text *t, int but)
{
	uint p0, oldp0;
	Rectangle s;
	int x, y, my, h, first;

	s = insetrect(t->scrollr, 1);
	h = s.max.y-s.min.y;
	x = (s.min.x+s.max.x)/2;
	oldp0 = ~0;
	first = TRUE;
	do{
		flushimage(display, 1);
		my = mouse->xy.y;
		if(my < s.min.y)
			my = s.min.y;
		if(my >= s.max.y)
			my = s.max.y;
		if(!eqpt(mouse->xy, Pt(x, my))){
			moveto(mousectl, Pt(x, my));
			readmouse(mousectl);		/* absorb event generated by moveto() */
		}
		if(but == 2){
			y = my;
			p0 = (vlong)t->file->b.nc*(y-s.min.y)/h;
			if(p0 >= t->q1)
				p0 = textbacknl(t, p0, 2);
			if(oldp0 != p0)
				textsetorigin(t, p0, FALSE);
			oldp0 = p0;
			readmouse(mousectl);
			continue;
		}
		if(but == 1)
			p0 = textbacknl(t, t->org, (my-s.min.y)/t->fr.font->height);
		else
			p0 = t->org+frcharofpt(&t->fr, Pt(s.max.x, my));
		if(oldp0 != p0)
			textsetorigin(t, p0, TRUE);
		oldp0 = p0;
		/* debounce */
		if(first){
			flushimage(display, 1);
			sleep(200);
			nbrecv(mousectl->c, &mousectl->m);
			first = FALSE;
		}
		scrsleep(80);
	}while(mouse->buttons & (1<<(but-1)));
	while(mouse->buttons)
		readmouse(mousectl);
}
