/**********************************************************************
 
	Copyright (C) 2003 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 "kibandata.h"
#include "arc_data.h"
#include <string.h>

void Arc2SVG(FILE *fp, ARC_ID_RECORD *pArcRecord, const char *szStrokeColor){
	fprintf(fp,"<path id=\"%s_%d\" style=\"fill:none;stroke:%s;\" d=\"",
			pArcRecord->code, pArcRecord->id, szStrokeColor);
	PrintArc(fp, pArcRecord, 0, PA_START);
	fprintf(fp,"\" />\n");
}

void ArcData2SVG(FILE *fp, ARC_DATA *pArc, const char *szStrokeColor){
	int i;
	for(i=0;i<pArc->header.record_count;++i){
		if(!(pArc->record[i].flags & AF_REMOVED))
			Arc2SVG(fp, &(pArc->record[i]), szStrokeColor);
	}
}

/* load from arc file */
int ReadArc(const char *filename, FILE *fp, ARC_DATA *pData, int Flags){
	char szBuff[256];
	KIBAN_FILE_HEADER *pHeader=&(pData->header);
	int nReturn;
	char seps[]  = " ,\t\n";
	char *token;
	ARC_ID_RECORD *pRecord;
	int i;
	int line_no=0;

	nReturn = ReadKibanFileHeader(fp, pHeader);
	if(nReturn!=ID_ERR_NOERROR){
		printf("::header error at %s\n", filename);
		return nReturn;
	}
	pData->record = (ARC_ID_RECORD *)calloc(pHeader->record_count*sizeof(ARC_ID_RECORD), 1);
	pRecord = pData->record ;
	line_no=1;
	for(i=0;i<pHeader->record_count;){
		GB_POINT *pt;
		int j;
		++line_no;
		if(!fgets(szBuff,sizeof(szBuff),fp)){		
			pHeader->record_count=i;
			printf("::record count error at %s:%d\n", pData->header.file_name, line_no);
			return ID_ERR_NOERROR;
		}
		chop(szBuff);

		/* 書式分類レコード ：L2110 */
		token = strtok( szBuff, seps );
		if(token==NULL){
			printf("::record format error at %s:%d\n", pData->header.file_name, line_no);
			return ID_ERR_FILE_FORMAT;
		}
		strcpy(pRecord->code,token);
		
		/* 線種タグ：0 */
		token = strtok( NULL, seps );
		if(token==NULL){
			printf("::record format error at %s:%d\n", pData->header.file_name, line_no);
			return ID_ERR_FILE_FORMAT;
		}
		pRecord->kind = atoi(token);
		
		/* 個別番号：9 */
		token = strtok( NULL, seps );
		if(token==NULL){
			printf("::record format error at %s:%d\n", pData->header.file_name, line_no);
			return ID_ERR_FILE_FORMAT;
		}
		pRecord->id = atoi(token);
		
		/* 座標レコード数：24 */
		token = strtok( NULL, seps );
		if(token==NULL){
			printf("::record format error at %s:%d\n", pData->header.file_name, line_no);
			return ID_ERR_FILE_FORMAT;
		}
		pRecord->point_count = atoi(token);
		pRecord->points = (GB_POINT*)malloc(pRecord->point_count * sizeof(GB_POINT));
		
		pt=pRecord->points;
		for(j=0;j<pRecord->point_count;++j){
			++line_no;
			if(!fgets(szBuff,sizeof(szBuff),fp)){
				break;
			}
			chop(szBuff);
			token = strtok(szBuff,seps);
			if(Flags & RKF_ABSOLUTE){
				if(!token)
					break;
				pt->x = atof(token) + pHeader->r.left;
				token = strtok(NULL,seps);
				if(!token)
					break;
				pt->y = atof(token) + pHeader->r.top;
			}
			else{
				if(!token)
					break;
				pt->x = atof(token);
				token = strtok(NULL,seps);
				if(!token)
					break;
				pt->y = atof(token);
			}
			++pt;
		}
		if(pRecord->point_count!=j){
			printf("::point count error at %s:%d\n", pData->header.file_name, line_no);
			pRecord->point_count=j;
		}
		++pRecord;
		++i;
	}
	return ID_ERR_NOERROR;
}

ARC_ID_RECORD *GetArcIDRecord(ARC_DATA *pArc, int nArcID){
	int i;
	for(i=0;i<pArc->header.record_count;++i){
		if(pArc->record[i].id == nArcID)
			return &(pArc->record[i]);
	}
	return NULL;
}

// 0...success
// 1...pArcID has no point for print
int PrintArc(FILE *fp, ARC_ID_RECORD *pArcID, int bDirection, int nOption){

	int i;
	GB_POINT *pt;
	GB_POINT *ptLast=0;
	if(pArcID->point_count<=0){
		return 1;
	}

	if(bDirection){
		i=0;
		if(nOption & PA_START){
			pt = &(pArcID->points[0]);
			fprintf(fp, "M %.1f %.1f", pt->x, pt->y);
			ptLast = pt;
			++i;
		}
		for(;i<pArcID->point_count;++i){
			pt = &(pArcID->points[i]);
			if(!ptLast || memcmp(ptLast,pt,sizeof(GB_POINT)))
				fprintf(fp, " L %.1f %.1f", pt->x, pt->y);
			ptLast = pt;
		}
	}
	else{
		i = pArcID->point_count-1;
		if(nOption & PA_START){
			pt = &(pArcID->points[pArcID->point_count-1]);
			fprintf(fp, "M %.1f %.1f", pt->x, pt->y);
			ptLast = pt;
			--i;
		}
		for(;i>=0;--i){
			pt = &(pArcID->points[i]);
			if(!ptLast || memcmp(ptLast,pt,sizeof(GB_POINT)))
				fprintf(fp, " L %.1f %.1f", pt->x, pt->y);
			ptLast = pt;
		}
	}
	
	return 0;
}


ARC_DATA *malloc_arc_data(){
	ARC_DATA *pData = (ARC_DATA*)(malloc(sizeof(ARC_DATA)));
	memset(pData,0,sizeof(ARC_DATA));
	return pData;
}

void free_ark_id_record(ARC_ID_RECORD *pRecord){
	if(pRecord->points != NULL){
		free(pRecord->points);
		pRecord->points = NULL;
	}
}

void free_arc_data(ARC_DATA *pData){
	if(!pData)
		return ;
	if(pData->record != NULL){
		int i;
		for(i=pData->header.record_count-1;i>=0;--i){
			free_ark_id_record(&pData->record[i]);
		}
		free(pData->record);
	}
	free(pData);
}
