// inputdialog.cp
//  by apj
// 画面上にtextboxを配置し、入出力を行う
#define INPUTDIALOG_SRC

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Strings.h>

#include "debugs.h"
#include "inputdialog.h"


//********************* functions for EditItem ***********************
// call after determine Rect values
void  EIinit(EditItem *ei)
{
	ei->te = TENew(&(ei->t_rect), &(ei->t_rect));
	TEAutoView(FALSE, ei->te);
}

// draw 1 Item

void  EIDraw(EditItem ei)
{
	
	// Draw label
	MoveTo(ei.lx, ei.ly);
	DrawString(C2PStr(ei.label));

	//Draw Etitable
	EraseRect(&(ei.t_rect));
	TEUpdate(&(ei.t_rect), ei.te);
	FrameRect(&(ei.f_rect));

}



//********************* functions for EditPanel ************************
// Get window using window resource ID
// and set EditItems
// Setitems function is application dependent. Its return value must be number of Items
// Be careful Item number(inum) must be less than N_ITEMS. 
// If not, We are in great trouble.
void  EPInit(EditPanel *ep, short winID, short (*SetItems)(EditItem ei[]) )
{
	GrafPtr cptr;
	
	GetPort(&cptr);
	ep->w = GetNewCWindow(winID, NULL, (WindowPtr)-1);
	SetPort(ep->w);
	SetWRefCon(ep->w, (long)ep);
	ep->ObjectID = EDIT_OBJECT_ID;
	ep->inum = (*SetItems)(ep->item);
	ep->curte = (TEHandle)-1;
	SetPort(cptr);
}

void  EPDraw(EditPanel *ep)
{
	short i;
	GrafPtr cptr;
	
	GetPort(&cptr);
	SetPort(ep->w);
	for(i = 0 ; i < ep->inum ; i++){
		EIDraw(ep->item[i]);
	}
	SetPort(cptr);
}

WindowPtr  EPQuerywin(EditPanel *ep)
{
	return ep->w;
}

// GO-AWAY Box Clicked
void  EPGoAway(EditPanel *ep, EventRecord ev)
{
	if(ep->w == FrontWindow() ){
		if(TrackGoAway(ep->w, ev.where)){
			HideWindow(ep->w);
		}
	}
}

// Call by mouse move
// if pointer in editable regon, change pointer form to I-beam
void  EPDoMouseMove(EditPanel *ep, EventRecord ev)
{
	short n;
	GrafPtr curptr;
	
	if(ep->w == FrontWindow() ){
		GetPort(&curptr);
		SetPort(ep->w);	
		// check mouse in editable region
		n = EPChekInEditable(ep);
		if(n != -1){
			SetCursor(*(GetCursor(iBeamCursor)));
		}
		else{
			InitCursor();
		}
		EPIdle(ep);
		SetPort(curptr);
	}
}

// If pointer is in editable region , return the number correspond to EditItem
// else return -1
short  EPChekInEditable(EditPanel *ep)
{
	Point mpt;
	short i;
	GrafPtr cptr;

	GetPort(&cptr);
	SetPort(ep->w);
	GetMouse(&mpt);

	for(i = 0 ; i < ep->inum  ; i++){
		if(PtInRect(mpt, &(ep->item[i].f_rect)) ){
				SetPort(cptr);
				return i;
		}
	}
	SetPort(cptr);
	return -1;
}


// Idling
void  EPIdle(EditPanel *ep)
{
	if(ep->curte != (TEHandle)-1){
		TEIdle(ep->curte);
	}
}

// Deactivate current text
void  EPDeactivate(EditPanel *ep)
{
	if(ep->curte != (TEHandle)-1){
		TEDeactivate(ep->curte);
		ep->curte = (TEHandle)-1;
	}
}

// call when mouse clicked
void  EPClicked(EditPanel *ep, EventRecord ev)
{
	Point mouse;
	short n;
	Boolean shiftdown;
	GrafPtr cptr;
	
	if(ep->w != FrontWindow()){
		SelectWindow(ep->w);
		return;
	}

	GetPort(&cptr);
	SetPort(ep->w);
	mouse = ev.where;
	GlobalToLocal(&mouse);

	n = EPChekInEditable(ep);
	if(n == -1){
		SetPort(cptr);
		return;         /* click point is not in editable region */
	}
	ep->curte = ep->item[n].te;
	TEActivate(ep->curte);
	shiftdown = (ev.modifiers == shiftKey);
	TEClick(mouse, shiftdown, ep->curte);
	SetPort(cptr);
}


void  EPHandleKeyDown(EditPanel *ep, EventRecord ev)
{
	char key;
	GrafPtr cptr;
	
	if(ep->curte == (TEHandle)-1) return;    /* No textedit is activated */
	
	GetPort(&cptr);
	SetPort(ep->w);
	
	key = (char)(ev.message & charCodeMask);
	if(key == kCR) {
		SetPort(cptr);
		return;
	}
	if(key != kDel || key != kRightArrow || key != kLeftArrow
	   || key != kUpArrow || key != kDownArrow
	   ||(((*(ep->curte))->teLength - getTESelLength(**(ep->curte))+ 1) < kMaxTELength) ){
	   	TEKey(key, ep->curte);
	}
	SetPort(cptr);
}


short  getTESelLength(TERec te)
{
	return te.selEnd - te.selStart;
}

// Get the string of nth contents
void  EPGetContent(EditPanel *ep, short n, char *str)
{
	Str255 pstr;

	if (n < 0 || n > ep->inum) return;
		
	TERectToStr(ep->item[n].te, pstr);
	strcpy(str, P2CStr(pstr));
}

// Set the string of nth contents
void  EPSetContent(EditPanel *ep, short n, char *str)
{
	if(strlen(str) > 255) return;
	if (n < 0 || n > ep->inum) return;
	
	StrToTERec(C2PStr(str), ep->item[n].te);
}


// テキストボックスと文字列のデータの受け渡し	
void  TERectToStr(TEHandle te, Str255 str)
{
	GetDialogItemText((*te)->hText, str);
}

void  StrToTERec(Str255 str, TEHandle te)
{
	TESetText( (Ptr) &str[1], long (str[0]), te);
}













