/*====================================================
                      ARTemis
                   (version 1.3)
             FM-TOWNS 用ペイントツール

                 by 松内 良介 1994
====================================================*/
#if 0
  // モジュール初期化
	int imagewin_init(void);

  // 生成・消滅
	IMWIN *imagewin_new(int pixelsize,int width, int height);
	void imagewin_destroy(IMWIN *win);

  // リンク関連
	IMWIN *imagewin_getfirst(void);
	IMWIN *imagewin_getnext(void);
	void imagewin_link(IMWIN *win);
	void imagewin_unlink(IMWIN *win);
	void imagewin_show(IMWIN *win);
	IMWIN *imagewin_getWinFromPart(int objId);
		// オブジェクトＩＤからウィンドウを検索する
	IMWIN *imagewin_getCurrentWin(void);
	void imagewin_setCurrentWin(IMWIN *win);

  // 座標変換
	void imagewin_getScrFrame(IMWIN *win, FRAME *frPic, FRAME *frBitmap);
		// PIC領域(x,y,wid,ht)から、SCRBITMAP領域(x,y,wid,ht)へと変換
	void imagewin_getDispFrame(IMWIN *win,FRAME* frPic);
		// ウィンドウのユーザー領域を、表示画像の PIC 領域(x,y,wid,ht)に変換
	void imagewin_getPosFromMos(IMWIN *win, POINT *mos, POINT *pos);
		// 画面上のマウス座標から、画像内での位置を得る
	BOOL imagewin_PtInPic(IMWIN* win, POINT* pt);
		// 画面座標 pt がウィンドウ内の画像領域にあるかどうか

  // 表示内容更新
	void imagewin_updateBuf(IMWIN *win);
		// PIC内容から、SCRBITMAP全体を再生成する
	void imagewin_updateScr(IMWIN *win);
		// SCRBITMAPの内容を画面に表示。同時にラバー描画も行う
	void imagewin_updateScrPart(IMWIN *win, FRAME *updatefr);
		// PIC領域 updatefr に対応する SCRBITMAP / 画面を更新する

  // ラバー制御
	void imagewin_setBoxRubber(IMWIN* win, FRAME *fr);
		// fr : PIC領域(x,y,wid,ht)
	void imagewin_setBoxRubber2(IMWIN* win, FRAME *fr);
	void imagewin_clearBoxRubber(IMWIN* win);
	void imagewin_clearBoxRubber2(IMWIN* win);
	void imagewin_resetLineRubber(IMWIN* win);
	void imagewin_addLineRubber(IMWIN* win,POINT* p1,POINT* p2);
		// p1,p2 : PIC 座標   p2 が NULL のとき、リストの最初の点とむすぶ
	int imagewin_nLineRubber(IMWIN* win);
	void imagewin_clearLineRubber(IMWIN* win);
	void imagewin_resetLineRubber2(IMWIN* win);
	void imagewin_addLineRubber2(IMWIN* win,POINT* p1,POINT* p2);
		// p1,p2 : PIC 座標   p2 が NULL のとき、リストの最初の点とむすぶ
	int imagewin_nLineRubber2(IMWIN* win);
	void imagewin_clearLineRubber2(IMWIN* win);

  // リサイズ、表示倍率変更など
	void imagewin_setFileName(IMWIN *win, char *fname, BOOL fShow);
	void imagewin_updateTitle(IMWIN *win, BOOL fShow);
	int imagewin_resize(IMWIN *win, BOOL fRedraw);
		// 子ウィンドウの再配置
	void imagewin_setZoom(IMWIN *win, int zoom);

  // 画像編集
	void imagewin_storeUndo(IMWIN* win);
	void imagewin_recoverUndo(void)
	void imagewin_copy(IMWIN* srcwin,FRAME* frSrc,
					   IMWIN* destwin,POINT *ptDest);
		// frSrc:PIC領域(x,y,wid,ht)
		// ptDest:PIC座標
	void imagewin_copyarea(IMWIN* srcwin,AREA areaSrc,
						   IMWIN* destwin,POINT *ptDest);
#endif

#define	MODULE_IMWIN

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <egb.h>
#include <wgb.h>
#include <msdos.cf>

#include "art.h"
#include "guisub.h"
#include "wgbmac.H"
#include "alert.h"
#include "subgrp.h"

#include "imagewin.h"
#include "imgwin.h"
#include "desktop.h"

#define	PIXELSIZE	2

BOOL art_IntersectRect(FRAME* frdest, FRAME* fr1, FRAME* fr2)
	// (x,y,wid,ht) で表された FRAME の intersect を得る
{
	FRAME fr;
	fr.X = _max(fr1->X, fr2->X);
	fr.Y = _max(fr1->Y, fr2->Y);
	fr.X2 = _min(fr1->X+fr1->WID, fr2->X+fr2->WID);
	fr.Y2 = _min(fr1->Y+fr1->HT, fr2->Y+fr2->HT);
	fr.WID = fr.X2 - fr.X;
	fr.HT  = fr.Y2 - fr.Y;
	if (fr.WID <= 0 || fr.HT <= 0)
		return FALSE;
	else
	{
		if (frdest != NULL)
			*frdest = fr;
		return TRUE;
	}
}

/*--------------------------------------------------------*/
/*                 モジュール内データ構造                 */
/*--------------------------------------------------------*/

IMWIN *winlist = NULL;
IMWIN *curptr;

/*--------------------------------------------------------*/
/*                   モジュールの初期化                   */
/*--------------------------------------------------------*/

int imagewin_init(void)
{
	winlist = NULL;
	return NOERR;
}

/*--------------------------------------------------------*/
/*                       生成・消滅                       */
/*--------------------------------------------------------*/

IMWIN *imagewin_new(int pixelsize,int width, int height)
{
	IMWIN *w ;
	if ((w = TL_calloc(1, sizeof(IMWIN))) == NULL)
		return NULL;
  // PIC 部品の生成
	if ((w->pic = pic_new(pixelsize,width,height)) == NULL)
		{ TL_free(w);  return NULL; }
  // データ構造の初期化
	w->fBoxRubber = FALSE;
	w->fBoxRubber2 = FALSE;
	w->zoom = 1;
  /* ひな型部品の複製をつくる */
	w->win      = MMI_SendMessage( idImageWin, MM_NEW, 0 ) ;
	w->sbar_h   = MMI_SendMessage( idImageHSBar, MM_NEW, 0 ) ;
	w->sbar_v   = MMI_SendMessage( idImageVSBar, MM_NEW, 0 ) ;
	w->titlebar = MMI_SendMessage( idImageTitleDBtn, MM_NEW, 0 );
	w->titlemsg = MMI_SendMessage( idImageTitleMsg, MM_NEW, 0 );
	w->erasebtn = MMI_SendMessage( idImageEraseDBtn, MM_NEW, 0 );
  /* それぞれの部品をくっつける */
	MMI_SendMessage( w->sbar_h,   MM_ATTACH, 1, w->win ) ;
	MMI_SendMessage( w->sbar_v,   MM_ATTACH, 1, w->win ) ;
	MMI_SendMessage( w->titlebar, MM_ATTACH, 1, w->win ) ;
	MMI_SendMessage( w->titlemsg, MM_ATTACH, 1, w->win ) ;
	MMI_SendMessage( w->erasebtn, MM_ATTACH, 1, w->win ) ;
  // ウィンドウのタイトルを作成
	imagewin_updateTitle(w, FALSE);
  // 各部品の配置(画面バッファも同時に確保)
	if (imagewin_resize(w, FALSE) != NOERR)
	{
		imagewin_destroy(w);
		return NULL;
	}
  // おわり
	return w;
}

void imagewin_destroy(IMWIN *win)
{
	MMI_SendMessage( win->win, MM_DESTROY, 0 );
	if (win->bm != NULL)
		scrbitmap_delete(win->bm);
	if (win->pic != NULL)
		pic_destroy(win->pic);
	TL_free(win);
}

/*--------------------------------------------------------*/
/*                       リンク関連                       */
/*--------------------------------------------------------*/

IMWIN	*imagewin_getfirst(void)
{
	curptr = winlist;
	return curptr;
}

IMWIN	*imagewin_getnext(void)
{
	if (curptr == NULL)
		return NULL;
	curptr = curptr->next;
	return curptr;
}

void imagewin_link(IMWIN *win)
{
	win->next = winlist;
	winlist = win;
	MMI_SendMessage(win->win, MM_ATTACH, 1, idDesktopWinAttachHyper);
	MMI_SendMessage(win->win, MM_WAKE, 0 );
}

void imagewin_show(IMWIN *win)
{
	WINCLIP *clipStack;
	WIN_beginUpDateObj(win->win, &clipStack);
	MMI_SendMessage(win->win, MM_SHOW, 0);
	WIN_endUpDateObj(clipStack);
}

void imagewin_unlink(IMWIN *win)
{
	IMWIN *w,*prev;
	for (w=winlist,prev=NULL; w!=NULL; prev=w,w=w->next)
	{
		if (w == win)
		{
			if (prev==NULL)
				winlist = w->next;
			else
				prev->next = w->next;
		}
	}
	MMI_SendMessage(win->win, MM_ERASE, 0);
	MMI_SendMessage(win->win, MM_DETACH, 0);
}

IMWIN *imagewin_getWinFromPart(int objId)
/* 部品IDからどの IMWIN であるかを得る */
{
	IMWIN *win;
	for (win=imagewin_getfirst(); win!=NULL; win=imagewin_getnext())
	{
		if (	win->win == objId      || win->sbar_h == objId   ||
				win->sbar_v == objId   || /* win->btn == objId      || */
				win->erasebtn == objId || win->titlebar == objId ||
				win->titlemsg == objId		)
			return win;
	}
	return NULL;
}

static IMWIN *curwin = NULL;

IMWIN *imagewin_getCurrentWin(void)
{
	return curwin;
}

void imagewin_setCurrentWin(IMWIN *win)
{
	curwin = win;
}

/*--------------------------------------------------------*/
/*                        座標変換                        */
/*--------------------------------------------------------*/

void imagewin_getDispFrame(IMWIN *win, FRAME *fr)
// ウィンドウのユーザー領域を、表示画像の PIC 領域(x,y,wid,ht)に変換
{
	FRAME frUser, ret;
	RM_getWinUserFrame(win->win, &frUser);
	ret.X = RM_getScrollPos(win->sbar_h);
	ret.Y = RM_getScrollPos(win->sbar_v);
	ret.WID = (frUser.X2 - frUser.X + 1 + win->zoom-1) / win->zoom;
	ret.HT = (frUser.Y2 - frUser.Y + 1 + win->zoom-1) / win->zoom;
	if (fr!=NULL)
		*fr = ret;
}

void imagewin_getScrFrame(IMWIN *win, FRAME *picfr, FRAME *scrfr)
// PIC領域(x,y,wid,ht)から、SCRBITMAP領域(x,y,wid,ht)へと変換
{
	FRAME ret, pfr;
	imagewin_getDispFrame(win, &pfr);
	ret.X = (picfr->X - pfr.X) * win->zoom;
	ret.Y = (picfr->Y - pfr.Y) * win->zoom;
	ret.WID = picfr->WID * win->zoom;
	ret.HT = picfr->HT * win->zoom;
	*scrfr = ret;
}

void imagewin_getPosFromMos(IMWIN *win, POINT *mos, POINT *pos)
/* マウスカーソル位置が画像内のどこであるかを得る */
/*
[引数]
	win : 画像ウィンドウ
	mos : マウス座標
[結果]
	pos : 画像内での座標
*/
{
	FRAME frUser;
	RM_getWinUserFrame(win->win, &frUser);
	FRAME frDisp;
	imagewin_getDispFrame(win, &frDisp);
	pos->x = frDisp.X + (mos->x - frUser.X) / win->zoom;
	pos->y = frDisp.Y + (mos->y - frUser.Y) / win->zoom;
}

BOOL imagewin_PtInPic(IMWIN* win, POINT* pt)
// pt :画面座標
{
	FRAME frUser;
	RM_getWinUserFrame(win->win, &frUser);
	if (PtInRect((Rect*)&frUser,(Point*)pt))
		return TRUE;
	else
		return FALSE;
}

/*--------------------------------------------------------*/
/*                 SCRBITMAP / 画面の更新                 */
/*--------------------------------------------------------*/

void imagewin_updateBuf(IMWIN *win)
/* 画像内容の変更があった場合に、ユーザー領域バッファの内容を更新 */
{
	FRAME frDisp;
	imagewin_getDispFrame(win, &frDisp);
	if (win->pic != NULL && win->bm != NULL)
		pic_getScrBitmap(win->pic, win->bm, 0,0, &frDisp, win->zoom);
}

void imagewin_updateScr(IMWIN *win)
{
	BEGINPAINT(win->win)
	FRAME frUser;
	RM_getWinUserFrame(win->win, &frUser);
	if (win->bm != NULL)
		scrbitmap_draw(win->bm, frUser.X, frUser.Y);
  // ラバーを上書きする
	FRAME frDisp;
	imagewin_getDispFrame(win, &frDisp);
  // ボックスラバー描画関数
	void boxrubber(FRAME* fr)
	 // fr:PIC領域(x,y,wid,ht)
	{
		if (win->zoom == 1)
		{
			WGB_RBOXLINE(guiEgbPtr,
						 frUser.X + (fr->X - frDisp.X),
						 frUser.Y + (fr->Y - frDisp.Y),
						 fr->WID, fr->HT, RMcol(WHITE), 4);
		}
		else
		{
			FRAME frBitmap;
			void draw(void)
			{
				WGB_RBOXFILL(guiEgbPtr,
							 frUser.X + frBitmap.X,
							 frUser.Y + frBitmap.Y,
							 frBitmap.WID, frBitmap.HT, RMcol(WHITE),4);
			}
			{ FRAME frPic = {fr->X,fr->Y,fr->WID,1};
			  imagewin_getScrFrame(win, &frPic, &frBitmap); }
			draw();
			if (fr->HT >= 2)
			{
				{ FRAME frPic = {fr->X,fr->Y+fr->HT-1,fr->WID,1};
				  imagewin_getScrFrame(win, &frPic, &frBitmap); }
				draw();
			}
			if (fr->HT >= 3)
			{
				{ FRAME frPic = {fr->X,fr->Y+1,1,fr->HT-2};
				  imagewin_getScrFrame(win, &frPic, &frBitmap); }
				draw();
				if (fr->WID >= 2)
				{
					{ FRAME frPic = {fr->X+fr->WID-1,fr->Y+1,1,fr->HT-2};
					  imagewin_getScrFrame(win, &frPic, &frBitmap); }
					draw();
				}
			}
		}
	}
	if (win->fBoxRubber)
		boxrubber(&win->frBoxRubber);
	if (win->fBoxRubber2)
		boxrubber(&win->frBoxRubber2);
  // 直線ラバー描画関数
	void linerubber(LIST* list)
	{
		for (list_top(list); !list_isOut(list); list_next(list))
		{
			FRAME fr;
			list_getData(list, &fr);
			if (win->zoom == 1)
			{
				WGB_LINE(guiEgbPtr,
					frUser.X + (fr.X - frDisp.X),
					frUser.Y + (fr.Y - frDisp.Y),
					frUser.X + (fr.X2 - frDisp.X),
					frUser.Y + (fr.Y2 - frDisp.Y), RMcol(WHITE), 4);
			}
			else
			{
				void putpixel(int x,int y)
				{
					if (frDisp.X <= x && x < frDisp.X + frDisp.WID &&
					    frDisp.Y <= y && y < frDisp.Y + frDisp.HT)
					{
						int tx = frUser.X + (x - frDisp.X) * win->zoom;
						int ty = frUser.Y + (y - frDisp.Y) * win->zoom;
						WGB_RBOXFILL(guiEgbPtr, tx,ty,win->zoom,win->zoom,
									 RMcol(WHITE), 4);
					}
				}
				do_line(fr.X,fr.Y,fr.X2,fr.Y2,putpixel);
			}
		}
	}
	if (win->fLineRubber)
		linerubber(win->listLineRubber);
	if (win->fLineRubber2)
		linerubber(win->listLineRubber2);
	ENDPAINT
}

void imagewin_updateScrPart(IMWIN *win, FRAME *updatefr)
// PIC領域updatefr(x,y,wid,ht) に対応する SCRBITMAP と画面を更新
{
  // 更新の必要な PIC 領域を得る
	FRAME frDisp;   // 画面に表示されている PIC 領域
	FRAME frUpdate; // 更新の必要な PIC 領域
	imagewin_getDispFrame(win, &frDisp);
	if (!art_IntersectRect(&frUpdate, &frDisp, updatefr))
		return;
  // その PIC 領域に対応した SCRBITMAP 領域を更新する
	FRAME frDraw; // 更新の必要な SCRBITMAP 領域
	imagewin_getScrFrame(win, &frUpdate, &frDraw);
	if (win->pic != NULL && win->bm != NULL)
		pic_getScrBitmap(win->pic,win->bm,frDraw.X,frDraw.Y,&frUpdate,
			win->zoom);
  // 画面に描画
	BEGINPAINT(win->win)
	FRAME frUser; RM_getWinUserFrame(win->win, &frUser);
	if (win->bm != NULL)
		scrbitmap_drawPart(win->bm, &frDraw, frUser.X, frUser.Y);
	ENDPAINT
}

/*--------------------------------------------------------*/
/*                       ラバー制御                       */
/*--------------------------------------------------------*/

void imagewin_setBoxRubber(IMWIN* win, FRAME *fr)
	// fr : PIC領域(x,y,wid,ht)
{
	win->fBoxRubber = TRUE;
	win->frBoxRubber = *fr;
	imagewin_updateScr(win);
}

void imagewin_setBoxRubber2(IMWIN* win, FRAME *fr)
	// fr : PIC領域(x,y,wid,ht)
{
	win->fBoxRubber2 = TRUE;
	win->frBoxRubber2 = *fr;
	imagewin_updateScr(win);
}

void imagewin_clearBoxRubber(IMWIN* win)
{
	win->fBoxRubber = FALSE;
	imagewin_updateScr(win);
}

void imagewin_clearBoxRubber2(IMWIN* win)
{
	win->fBoxRubber2 = FALSE;
	imagewin_updateScr(win);
}

void imagewin_resetLineRubber(IMWIN* win)
{
	if (!win->fLineRubber)
		return;
	LIST* list = win->listLineRubber;
	while (!list_isEmpty(list))
	  { list_top(list); list_deleteData(list); }
}

void imagewin_addLineRubber(IMWIN* win,POINT* p1,POINT* p2)
{
	if (!win->fLineRubber)
	{
		win->fLineRubber = TRUE;
		win->listLineRubber = list_new(sizeof(FRAME));
	}
	LIST* list = win->listLineRubber;
	FRAME fr;
	if (p2 == NULL)
	{
		list_top(list);  FRAME frTop;  list_getData(list,&frTop);
		fr.X2 = frTop.X;
		fr.Y2 = frTop.Y;
	}
	else
		fr.X2 = p2->x, fr.Y2 = p2->y;
	fr.X = p1->x, fr.Y = p1->y;
	list_moveTo(list, list_getDataNum(list));
	list_insertData(list,&fr);
	imagewin_updateScr(win);
}

int imagewin_nLineRubber(IMWIN* win)
{
	if (!win->fLineRubber)
		return 0;
	else
		return list_getDataNum(win->listLineRubber);
}

void imagewin_clearLineRubber(IMWIN* win)
{
	if (win->fLineRubber)
	{
		list_destroy(win->listLineRubber);
		win->listLineRubber = NULL;
		win->fLineRubber = FALSE;
	}
	imagewin_updateScr(win);
}

void imagewin_resetLineRubber2(IMWIN* win)
{
	if (!win->fLineRubber2)
		return;
	LIST* list = win->listLineRubber2;
	while (!list_isEmpty(list))
	  { list_top(list); list_deleteData(list); }
}

void imagewin_addLineRubber2(IMWIN* win,POINT* p1,POINT* p2)
{
	if (!win->fLineRubber2)
	{
		win->fLineRubber2 = TRUE;
		win->listLineRubber2 = list_new(sizeof(FRAME));
	}
	LIST* list = win->listLineRubber2;
	FRAME fr;
	if (p2 == NULL)
	{
		list_top(list);  FRAME frTop;  list_getData(list,&frTop);
		fr.X2 = frTop.X;
		fr.Y2 = frTop.Y;
	}
	else
		fr.X2 = p2->x, fr.Y2 = p2->y;
	fr.X = p1->x, fr.Y = p1->y;
	list_moveTo(list, list_getDataNum(list));
	list_insertData(list,&fr);
	imagewin_updateScr(win);
}

int imagewin_nLineRubber2(IMWIN* win)
{
	if (!win->fLineRubber2)
		return 0;
	else
		return list_getDataNum(win->listLineRubber2);
}

void imagewin_clearLineRubber2(IMWIN* win)
{
	if (win->fLineRubber2)
	{
		list_destroy(win->listLineRubber2);
		win->listLineRubber2 = NULL;
		win->fLineRubber2 = FALSE;
	}
	imagewin_updateScr(win);
}

/*--------------------------------------------------------*/
/*                        リサイズ                        */
/*--------------------------------------------------------*/

int imagewin_resize(IMWIN *win, BOOL fRedraw)
// NOERR, -1(メモリ不足)
{
	#define XADD	((2+2) + (BAR_SIZE+2))		/* usr.wid + XADD = win.wid */
	#define YADD	((16+2) + (BAR_SIZE+2))		/* usr.ht + YADD = win.ht */
	static FRAME frAdj[] =
	{
		{ 2+2,16+2,-BAR_SIZE-1-2,-BAR_SIZE-1-2 },	// user 領域
		{ 1,1,-2,15 },		// タイトルバー
		{ 0, -BAR_SIZE, -BAR_SIZE, -1 },	// HSBAR
		{ -BAR_SIZE, 16, -1, -BAR_SIZE },	// VSBAR
		{ 0,0,0,0 }
	};
  // pic の大きさにあわせてウィンドウの大きさを制限
	if (win->pic != NULL)
	{
		FRAME fr;
		RM_getFrame(win->win, &fr);
		int maxwid = win->pic->wid * win->zoom + XADD;
		int maxht = win->pic->ht * win->zoom + YADD;
		if (fr.X2-fr.X+1 > maxwid)
			fr.X2 = fr.X + maxwid - 1;
		if (fr.Y2-fr.Y+1 > maxht)
			fr.Y2 = fr.Y + maxht - 1;
		MMI_SendMessage(win->win, MM_MOVE, 1, &fr);
	}
  // 各部品を配置
	RM_adjustWinUser(win->win, &frAdj[0]);
	RM_adjustFrame(win->titlebar, win->win, &frAdj[1]);
	RM_adjustFrame(win->sbar_h, win->win, &frAdj[2]);
	RM_adjustFrame(win->sbar_v, win->win, &frAdj[3]);
  // スクロールバーの更新
	FRAME frDisp;
	imagewin_getDispFrame(win, &frDisp);
	int ofsx,ofsy;
	ofsx = RM_getScrollPos(win->sbar_h);
	ofsy = RM_getScrollPos(win->sbar_v);
	RM_setScrollRange(win->sbar_h, frDisp.WID, win->pic->wid, FALSE);
	RM_setScrollRange(win->sbar_v, frDisp.HT, win->pic->ht, FALSE);
	ofsx = _min(ofsx, win->pic->wid - frDisp.WID);
	ofsy = _min(ofsy, win->pic->ht - frDisp.HT);
	RM_setScrollPos(win->sbar_h, ofsx, fRedraw);
	RM_setScrollPos(win->sbar_v, ofsy, fRedraw);
	if (!fRedraw)
	{
		// スクロールバーの表示フラグをクリア
		MMI_SendMessage(win->sbar_h, MM_ERASE, 0);
		MMI_SendMessage(win->sbar_v, MM_ERASE, 0);
	}
  // 画面出力バッファの再確保★
	if (win->bm != NULL)
		scrbitmap_delete(win->bm);
	FRAME frUser;
	RM_getWinUserFrame(win->win, &frUser);
	win->bm = scrbitmap_new(frUser.X2-frUser.X+1, frUser.Y2-frUser.Y+1);
	if (win->bm == NULL)
		return -1;
	imagewin_updateBuf(win);
	return NOERR;
}

void imagewin_setZoom(IMWIN *win, int zoom)
{
	win->zoom = zoom;
	WINCLIP* clip;
	WIN_beginUpDateObj(win->win, &clip);
	imagewin_resize(win, FALSE);
	MMI_SendMessage(idBackDialog, MM_SHOW, 0);
	MMI_SendMessage(win->win, MM_SHOW, 0);
	WIN_endUpDateObj(clip);
}

void imagewin_updateTitle(IMWIN *win, BOOL fShow)
// ウィンドウタイトルを更新表示する
{
	if (win->fname[0] == 0)
	{
		strcpy(win->title, "<名称未定>");
	}
	else
	{
		char drive[_MAX_DRIVE],dir[_MAX_DIR];
		char basename[_MAX_FNAME],ext[_MAX_EXT];
		_splitpath(win->fname, drive, dir, basename, ext);
		sprintf(win->title, "%s%s%s",drive,basename,ext);
		_strupr(win->title);
	}
	char buf[40];
	sprintf(buf, " (%d×%d, %s colors) 倍率:×%d",
			win->pic->wid, win->pic->ht, 
			(win->pic->pixelsize == 16 ? "32K" : "16M"),
			win->zoom);
	strcat(win->title, buf);
	if (fShow)
	{
		WINCLIP *clip;
		WIN_beginUpDateObj(win->titlebar, &clip);
		MMI_SendMessage(win->titlemsg, MM_ERASE, 0);
		MMI_SendMessage(win->titlebar, MM_SHOW, 0);
		MMI_SendMessage(win->erasebtn, MM_SHOW, 0);
		MMI_SendMessage(win->titlemsg, MM_SETMSG, 1, win->title);
		MMI_SendMessage(win->titlemsg, MM_SHOW, 0);
		WIN_endUpDateObj(clip);
	}
	else
	{
		MMI_SendMessage(win->titlemsg, MM_SETMSG, 1, win->title);
	}
}

void imagewin_setFileName(IMWIN *win, char *fname, BOOL fShow)
{
	if (fname == NULL)
		win->fname[0] = 0;
	else
		strncpy(win->fname, fname, _MAX_PATH-1);
	imagewin_updateTitle(win, fShow);
}

/*--------------------------------------------------------*/
/*                        画像編集                        */
/*--------------------------------------------------------*/

static PIC* picUndo = NULL;
static IMWIN* undo_win = NULL;

void imagewin_storeUndo(IMWIN* win)
{
	if (picUndo != NULL)
		pic_destroy(picUndo);
	undo_win = win;
	if ((picUndo = pic_dup(win->pic)) == NULL)
	{
	#if 0
		dispAlertMessage("メモリが足りません",
			"メモリ不足のため、この描画コマンドはアンドゥすることが"
			"できません。ご注意ください");
	#endif
	}
}

void imagewin_recoverUndo(void)
{
	if (undo_win == NULL)
		return;
	if (picUndo == NULL)
		return;
	PIC* pic = undo_win->pic;
	undo_win->pic = picUndo;
	pic_destroy(pic);
	picUndo = NULL;
	imagewin_updateBuf(undo_win);
	imagewin_updateScr(undo_win);
	undo_win = NULL;
}

void imagewin_copy(IMWIN* srcwin, FRAME* frSrc, IMWIN* destwin, POINT *ptDest)
{
	FRAME frUpdate;
	imagewin_storeUndo(destwin);
	pic_beginUpDate(destwin->pic);
	pic_copy(srcwin->pic, frSrc, destwin->pic, ptDest);
	pic_endUpDate(destwin->pic, &frUpdate);
	imagewin_updateScrPart(destwin, &frUpdate);
}

void imagewin_copyarea(IMWIN* srcwin,AREA areaSrc,IMWIN* destwin,POINT *ptDest)
{
	FRAME frUpdate;
	imagewin_storeUndo(destwin);
	pic_beginUpDate(destwin->pic);
	pic_copyarea(srcwin->pic, areaSrc, destwin->pic, ptDest);
	pic_endUpDate(destwin->pic, &frUpdate);
	imagewin_updateScrPart(destwin, &frUpdate);
}
