/**********************************************************************
 
	Copyright (C) 2004 Tomohito Nakajima <nakajima@zeta.co.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.

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

#ifndef ADDRDB_H___
#define ADDRDB_H___

#include "long_char.h"
/*#include "csvparser.h" */
#include "xllisp_types.h"

#define ADDR_DB_MAIN_DBNAME 1
#define ADDR_DB_NAME_ALIAS_DBNAME 2
#define ADDR_DB_STR_DICT_DBNAME 3
#define ADDR_DB_INTERNAL_DBNAME 4


/*
	This struct define replaceable methods by locale.  
	If you want support other country address format,
	You must implement under methods.
*/
typedef struct tag_addrdb_locale{
	/* 
		normalize address number format. 
		for example: 1cyome2banchi3gou -> 1-2-3 
		
		return 0...success  negative...error
	*/
	int (*normalize_addr_number_format)(struct tag_addrdb_locale* locale, struct tag_addrdb *db, L_CHAR *normalized, int normalized_buff_size, const L_CHAR *original);
	
	/* 
		normalize address name format. 
		return 0...success  negative...error
	*/
	int (*normalize_addr_name_format)(struct tag_addrdb_locale* locale, struct tag_addrdb *db, L_CHAR *normalized, int normalized_buff_size, const L_CHAR *original);
	
	
	int (*init)(struct tag_addrdb_locale* locale, struct tag_addrdb *db);
	
	/* 
		specify the L_CHAR codeset of search-key.
		If you don't need specify the codeset, set this to 0.
	*/
	LCZ_SET *search_key_codeset;

	/*
		if you set this 0, utf-8 used.
	*/
	char *sexp_encoding_of_stored_file;
}ADDRDB_LOCALE;



/*
	main address database struct.
	Do not create this struct's instance direct.
	You must get this instance by addrdb_open() function.
	Use addrdb_close() to close database.
*/
typedef enum {
	ADOPT_INSERT_SKIP_ON_KEY_COLLISION=1,
	ADOPT_INSERT_OVERWRITE_ON_KEY_COLLISION=2
}ADDRDB_OPTION;
typedef struct tag_addrdb{
	/* database file handle */
	int file_handle;
	
	/* handle of main database */
	int main_handle;
	
	/* handle of database for address name aliases */
	int addr_name_alias_handle;
	
	/* This is used in order to make a character sequence regular in substitution.  */
	int str_dict_handle;
	
	/* addressdatabase internal management data */
	int internal_handle;
	
	/* pointer to locale object that treat data in this database. */
	ADDRDB_LOCALE *locale;
	
	ADDRDB_OPTION option;
}ADDRDB;

/*******************************************************
	 public functions 
*********************************************************/
/*
	open or create address database
	example: 
	ADDRDB *db;
	db = addrdb_open("addrdb_test/test.db", addrdb_kokudo_get_locale(), ADOPT_INSERT_SKIP_ON_KEY_COLLISION);
*/
ADDRDB *addrdb_open(const char* filename, ADDRDB_LOCALE *locale, ADDRDB_OPTION option);

/*
	free address database resource
*/
void addrdb_close(ADDRDB *db);

/*
insert address data record to database. 
if error return -1 
*/
int addrdb_insert2(ADDRDB *db, const L_CHAR *address_name_part, const L_CHAR *address_number_part, const XL_SEXP *record_data);

/*
insert address data record to database.
with auto detect dividing point of name and number using already registerd data.
before call this method, you must regist base address data to db.
*/
int addrdb_insert(ADDRDB *db, const L_CHAR *addr_string, const XL_SEXP *record_data);

/*
search data
*/
XL_SEXP *addrdb_search(ADDRDB *db, const L_CHAR *addr_string);

/* 
insert already normalized address-string(= address-name + address-number) to database
if error return -1 
*/
int addrdb_insert_direct(ADDRDB *db, const L_CHAR *address_string, const XL_SEXP *data);

/*
insert alias of address name
if error return -1
*/
int addrdb_insert_name_alias(ADDRDB *db, const L_CHAR *alias_name, const L_CHAR *full_name);

/*
insert simple replace word for normalization address name.
*/
int addrdb_insert_replace_dict(ADDRDB *db, const L_CHAR *from, const L_CHAR *to);

/*
convert csvfiles in a directory. output directory must be exists
*/
int addrdb_convert_csv_batch(ADDRDB *db, const char* input_dir, const char* output_dir, const char* input_file_encoding, int address_string_columun);

/*
convert csvfile
*/
int addrdb_convert_csv(ADDRDB *db, const char* input_file, const char* output_file, const char*input_file_encoding, int address_string_columun);

/* set option. it is same as addrdb_open parameter */
void addrdb_set_option(ADDRDB *db, ADDRDB_OPTION option);


/*******************************************************
	 protected functions (do not use from client program. this function is for implement ADDRDB_LOCALE )
*********************************************************/
L_CHAR *addrdb_convert_lcharcode(ADDRDB_LOCALE *locale, const L_CHAR *str);
BOOL addrdb_substitute_str_for_normalize(ADDRDB *db, L_CHAR *buff, int buff_size, const L_CHAR *addr_string);

#define ADDRDB_ASSERT(exp) if(!(exp)){ er_panic(""); }else{}

#endif
