/**********************************************************************
 
	Copyright (C) 2005- Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/

#include	"k2m.h"


/*
CHANNEL		0		attribute plet of color

CANNNEL		8		compressed data CHANNEL corresponding to Kiban layer
CANNNEL		9
CANNNEL		10
CANNNEL		11
CANNNEL		12
CANNNEL		13
CANNNEL		14
CANNNEL		15

CHANNEL		16		unsigned 8 bit original data
CHANNEL		17
CHANNEL		18
CHANNEL		19
CHANNEL		20
CHANNEL		21
CHANNEL		22
CHANNEL		23

CHANNEL		24		unsigned 8 bit work data
CHANNEL		25
CHANNEL		26
CHANNEL		27
CHANNEL		28
CHANNEL		29
CHANNEL		30
CHANNEL		31

*/

#define ACC_NOS 8
MX_CACHE write_cache;
int access_ch[ACC_NOS] = {16,17,18,19,20,21,22,23};
MX_CACHE_PARAM wcp;
MX_CACHE_PARAM_IX wcp_ix[ACC_NOS] = {
	{0,0},
	{0,1},
	{0,2},
	{0,3},
	{0,4},
	{0,5},
	{0,6},
	{0,7}
};

MATRIX *
matrix_open_kiban(char * filename,INTEGER64 x,INTEGER64 y)
{
MATRIX * m;
int er;
MATRIX_PARAM p;
MATRIX_CHANNEL_INFO inf;
int i;
XL_SEXP * edit_com;
int err;

	m = open_matrix(
		0,				// open URL name (ignore)
		l_string(std_cm,filename),	// save filename
		0,				// KEY name for searching
		0,
		0);

	if ( m == 0 )
		goto error;

	err = load_matrix_header(m,O_CREAT|O_RDWR,0644);
	if ( err == 0 )
		goto exist_file;
	memset(&p,0,sizeof(p));
	p.channel_nos = 32;
	p.dim = 2;
	p.pri_area[MI_FETCH_1_TP] = PR_STRT + 0x20000;
	p.pri_area[MI_FETCH_1_MD] = PR_STRT + 0x20000;
	p.pri_area[MI_FETCH_1_BT] = PR_STRT + 0x20000;
	p.pri_area[MI_EDIT_1_TP] = PR_UP + 0x10000;
	p.pri_area[MI_EDIT_1_MD] = PR_UP + 0x10000;
	p.pri_area[MI_EDIT_1_BT] = PR_UP + 0x10000;
	p.pri_area[MI_EDIT_2_TP] = PR_UP + 0x00000;
	p.pri_area[MI_EDIT_2_MD] = PR_UP + 0x00000;
	p.pri_area[MI_EDIT_2_BT] = PR_UP + 0x00000;
	p.pri_area[MI_SAVE_TP] = PR_STRT + 0x20000;
	p.write_file = matrix_standard_write_file;
	p.read_file = matrix_standard_read_file;
	p.close_file = close_matrix_file;

	er = set_matrix_param(m,&p);
	if ( er < 0 )
		goto error;
	er = set_matrix_dim_divide(m,0,1);		// divide 2^1
	if ( er < 0 )
		goto error;
	er = set_matrix_block_size(m,0,7);		// blocksize = 2^7
	if ( er < 0 )
		goto error;
	er = set_matrix_dim_divide(m,1,1);
	if ( er < 0 )
		goto error;
	er = set_matrix_block_size(m,1,7);
	if ( er < 0 )
		goto error;

	er = set_matrix_pixel_size(m,0,x);
	if ( er < 0 )
		goto error;
	er = set_matrix_pixel_size(m,1,y);
	if ( er < 0 )
		goto error;
	
	inf.data_type = &mx_type_uint32_v;
	inf.flags = MF_SEND|MF_FILE;
	er = set_matrix_channel_info(m,0,&inf);
	if ( er < 0 )
		goto error;

	for ( i = 8 ; i < 16 ; i ++ ) {

		inf.data_type = &mx_type_block;
		inf.flags = MF_SEND|MF_FILE;
		er = set_matrix_channel_info(m,i,&inf);
		if ( er < 0 )
			goto error;

	}
	for ( i = 16 ; i < 32 ; i ++ ) {

		inf.data_type = &mx_type_uint8_v;
		inf.flags = MF_FILE;
		er = set_matrix_channel_info(m,i,&inf);
		if ( er < 0 )
			goto error;
	}


exist_file:

	edit_com = 
		sexp_commands(
			std_cm,
		"(Define ch 16)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		"(Define ch 17)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		"(Define ch 18)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		"(Define ch 19)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		"(Define ch 20)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		"(Define ch 21)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		"(Define ch 22)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		"(Define ch 23)",
		"(mxSet ch ([mxThinnedOut",
			"type=\"average\"",
			"channel = \"^ch\"]",
			"([mxCH type=\"children\"] ch)))",
		0);

	set_matrix_cal(m,MI_EDIT_1_BT,
		append(edit_com,
			sexp_commands(std_cm,
			"<mxTrigger type=\"parent\"/>",
			0)));
	set_matrix_cal_equ(m,MI_EDIT_1_MD,MI_EDIT_1_BT);
	set_matrix_cal(m,MI_EDIT_1_TP,
		append(edit_com,
			sexp_commands(std_cm,
			"<mxTrigger type=\"children\"",
				"access=\"MI_EDIT_2\"/>",
			0)));


	edit_com =
		sexp_commands(
			std_cm,
		"(Define ch 8)\n",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",
		"(Define ch 9)\n",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",
		"(Define ch 10)\n",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",
		"(Define ch 11)\n",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",
		"(Define ch 12)\n",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",
		"(Define ch 13)",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",
		"(Define ch 14)",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",
		"(Define ch 15)",
		"(mxSet ch (mxCompressJPEG ([mxDiff option=\"CURVE\"]\n",
		"([mxCH type=\"parent\"] (+ ch 16)) (mxCH (+ ch 8)) )))\n",

		"(Define ch 8)\n",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		"(Define ch 9)",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		"(Define ch 10)",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		"(Define ch 11)",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		"(Define ch 12)",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		"(Define ch 13)",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		"(Define ch 14)",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		"(Define ch 15)",
		"(mxSet (+ ch 16) ([mxAdd option=\"CURVE\"\n",
			"([mxCH type=\"parent\"] (+ ch 16))\n",
			"(mxUncompressJPEG (mxCH ch)) ))\n",
		0);

	set_matrix_cal(m,MI_EDIT_2_MD,
		append(edit_com,
			sexp_commands(std_cm,
			"<mxTrigger type=\"children\"/>",
			0)));
	set_matrix_cal(m,MI_EDIT_2_BT,edit_com);


	set_matrix_cal(m,MI_SAVE_TP,
		sexp_commands(
			std_cm,
			"(mxSave)",
		0));
	set_matrix_cal_equ(m,MI_SAVE_MD,MI_SAVE_TP);
	set_matrix_cal_equ(m,MI_SAVE_BT,MI_SAVE_TP);
	
	set_matrix_cal(m,MI_FETCH_1_TP,
		sexp_commands(
			std_cm,
			"<mxFinish\n",
			"	normal-jump-status=\"MS_OK\"\n",
			"	err-jump-status=\"MS_OK\"/>\n",
			"<mxLoad target=\"file\"/>",
		0));
	set_matrix_cal_equ(m,MI_FETCH_1_MD,MI_FETCH_1_TP);
	set_matrix_cal_equ(m,MI_FETCH_1_BT,MI_FETCH_1_TP);
	
	if ( err == ME_DESTROY_FILE )
		save_matrix_header(m);


	set_matrix_mode(m,MM_STANBY);

	write_cache.m = m;
	write_cache.gn_tree_node = GN_TREE;
	write_cache.gn_create = GN_LIST_CREATE;
	write_cache.gn_wait = GN_LIST_CREATE;
	write_cache.access_ch = &access_ch[0];
	write_cache.ds_len = ACC_NOS;
	mxc_setup(&write_cache);

	wcp.c = &write_cache;
//	wcp.dc = src;
	wcp.ofs = 0;
	wcp.data_ix = &wcp_ix[0];
//	cp.data_ptrs[0] = &bit;



error:
	return m;
}


void
write_pixel(INTEGER64 * src,unsigned char * d)
{
	wcp.dc = src;
	wcp.data_ptrs[0] = d;
	write_mx_cache(&wcp);
}

void
flush_write_pixel()
{
	flush_mx_cache(&write_cache,1);
}

