/*

	Noctis galactic guide / IMPORTGD command.
	GOES Net Module.
	
	TODO: Actually write this. It's just a copy of cast now.

*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <io.h>
#include "defs.h"
#include "modshare.hpp"

double 	object_id = 12345;
char   	object_label[25];
double 	s_object_id = 12345;
char   	s_object_label[25];

double	subject_id = 12345;

Dword	round;
Word 	i, mlen;
FILE * fh; FILE * gh; FILE *oldgh;
char	*file = "..\\DATA\\starmap3.map";
char	*guide = "..\\DATA\\starmap3.gd";
char	*oldguide = "..\\DATA\\GUIDE.BIN";

char	outbuffer[40];
char	textbuffer[40];
char	parbuffer[160];
char	nullbuffer[128];
char	objectname[21];
char	subjectname[21];
double	mblock_subject;
char	mblock_message[77];
double  idscale = 0.00001;

Dword nearstar_sx	  	= 0x7fffffff;		//53
Dword nearstar_sy	  	= 0x7fffffff;		//57
Dword nearstar_sz	  	= 0x7fffffff;		//61
Uword obj_pNum;
Uword obj_mNum;
#define new_data_start 245+5+120

Uchar flags;
Udword discoverer;
char name[21];
char lastname[21];
Dword sx, sy, sz;
Uword data;
Udword nextAlternateFP;
Udword starFP;
Bool exactMatch = 0;

char find (char *tgtname, Udword starmap3Len)
{
	Word p, n, ctc, found;
	ctc = strlen (tgtname);
	if (ctc > 20 || ctc <= 0) {
		msg ("INVALID OBJECT NAME.");
		return(0);
	}
	n = 0;
	found = 0;
	exactMatch=0;
	fseek (fh, 10, SEEK_SET);
	while (ftell(fh)<starmap3Len) {
		fread(&flags, 1, 1, fh);
		fread(&discoverer, 4, 1, fh);
		fread(&name, 20, 1, fh);
		if (flags&0x8) {
			fread(&sx, 4, 1, fh);
			fread(&sy, 4, 1, fh);
			fread(&sz, 4, 1, fh);
			fread(&data, 2, 1, fh);
			fread(&nextAlternateFP, 4, 1, fh);
			if (memcmp(name, tgtname, ctc)==0 && !(flags&0x20)) {
				if (ctc<20 && ctc>=2 && name[ctc]==32 && name[ctc-1]!=32) {
					exactMatch=2;
					if (n>0) {
						msg("NEVERMIND, FOUND EXACT MATCH");
						msg(name);
						n=1;
					}
				}
				if (!exactMatch) {
					//found it
					if (n==1) {	//If this is the second match
						msg ("AMBIGUOUS SEARCH KEY:");
						msg ("PLEASE EXPAND NAME...");
						msg (divider);
						msg ("POSSIBLE RESULTS ARE:");
						msg (divider);
						lastname[20]=0;
						msg (object_label);
					}
					if (n>0) {
						msg (name);
					}
					n++;
				}
				if (exactMatch!=1) {
					memcpy(object_label, name, 20);
					memcpy(subjectname, object_label, 20);
					//memcpy(starname, subjectname, 20);
					//printf("FOUND. SX=%li SY=%li SZ=%li. ", sx, sy, sz);
					nearstar_sx = sx;
					nearstar_sy = sy;
					nearstar_sz = sz;
					//printf("FOUND. NSX=%li NSY=%li NSZ=%li. ", nearstar_sx, nearstar_sy, nearstar_sz);
					obj_pNum=0x1F;
					obj_mNum=0x1F;
					found=1;
					while (p >= 0) {
						if (name[p] != 32) {
							if (name[p] == tgtname[p])
								return (found);
							else
								break;
						}
						p--;
					}
					if (exactMatch==2) return found;
				}
			}
		} else {
			fread(&starFP, 4, 1, fh);
			fread(&data, 2, 1, fh);
			fread(&nextAlternateFP, 4, 1, fh);
			if (memcmp(name, tgtname, ctc)==0 && !(flags&0x20)) {
				if (ctc<20 && ctc>=2 && name[ctc]==32 && name[ctc-1]!=32) {
					exactMatch=2;
					if (n>0) {
						msg("NEVERMIND, FOUND EXACT MATCH");
						msg(name);
						n=1;
					}
				}
				if (!exactMatch) {
					//found it
					if (n==1) {	//If this is the second match
						msg ("AMBIGUOUS SEARCH KEY:");
						msg ("PLEASE EXPAND NAME...");
						msg (divider);
						msg ("POSSIBLE RESULTS ARE:");
						msg (divider);
						lastname[20]=0;
						msg (object_label);
					}
					if (n>0) {
						msg (name);
					}
					n++;
				}
				if (exactMatch!=1) {
					memcpy(object_label, name, 20);
					memcpy(subjectname, object_label, 20);
					
					Dword pos = ftell(fh);
					fseek(fh, starFP+5, SEEK_SET);
					//fread(starname, 20, 1, fh);
					fseek(fh, starFP+25, SEEK_SET);
					fread(&nearstar_sx, 4, 1, fh);
					fread(&nearstar_sy, 4, 1, fh);
					fread(&nearstar_sz, 4, 1, fh);
					fseek(fh, pos, SEEK_SET);
					
					obj_pNum = ((data>>4)&0x1F);
					obj_mNum = ((data>>9)&0x1F);
					found=2;
					while (p >= 0) {
						if (name[p] != 32) {
							if (name[p] == tgtname[p])
								return (found);
							else
								break;
						}
						p--;
					}
					if (exactMatch==2) return found;
				}
			}
		}
	}
	
	if (!n)
		msg ("OBJECT NOT FOUND.");
	return (found);
}
/*
char find (char *starname)
{
	Word p, n, ctc, found;
	ctc = strlen (starname);
	if (ctc > 20 || ctc <= 0) {
		msg ("INVALID OBJECT NAME.");
		return(0);
	}
	n = 0;
	found = 0;
	lseek (fh, 4, SEEK_SET);
	while (_read (fh, &s_object_id, 8) && _read (fh, &s_object_label, 24) == 24) {
		if (memcmp (&s_object_id, "Removed:", 8)) {
			if (!memcmp (s_object_label, starname, ctc)) {
				n++;
				memcpy (object_label, s_object_label, 24);
				object_id = s_object_id;
				memcpy (subjectname, object_label, 20);
				subject_id = object_id;
				if (object_label[21] == 'S') found = 1;
				if (object_label[21] == 'P') found = 2;
				p = 20;
				while (p >= 0) {
					if (s_object_label[p] != 32) {
						if (s_object_label[p] == starname[p])
							return (found);
						else
							break;
					}
					p--;
				}
			}
		}
	}
	if (!n)
		msg ("OBJECT NOT FOUND.");
	if (n > 1) {
		msg ("AMBIGUOUS SEARCH KEY:");
		msg ("PLEASE EXPAND NAME...");
		msg (divider);
		msg ("POSSIBLE RESULTS ARE:");
		msg (divider);
		lseek (fh, 4, SEEK_SET);
		while (_read (fh, &s_object_id, 8) && _read (fh, &s_object_label, 24) == 24) {
		if (memcmp (&s_object_id, "Removed:", 8) && !memcmp (s_object_label, starname, ctc)) {
			s_object_label[21] = 0;
			msg (s_object_label);
		}}
		msg (divider);
		found = 0;
	}
	return (found);
}
*/

Word    nearstar_nop       = 0;		// 37
Word    nearstar_nob;
double ap_target_x        = 0;
double ap_target_y        = 1E9;
double ap_target_z        = 0;
Word    ap_target_class    = 0;		// 31
float  ap_target_ray      = 0;		// 63
char   ap_target_spin     = 0;          // 14
char   ap_target_r        = 0;          // 15
char   ap_target_g        = 0;          // 16
char   ap_target_b        = 0;          // 17
Word    nearstar_class     = 0;		// 35
float  nearstar_ray       = 1000;	// 67
char   nearstar_spin      = 0;          // 18
float  zrandom (Word range) { return (random(range) - random(range)); }
double nearstar_identity;
double nearstar_x         = 0;
double nearstar_y         = 1E9;
double nearstar_z         = 0;
char   nearstar_r         = 0;          // 19
char   nearstar_g         = 0;          // 20
char   nearstar_b         = 0;          // 21

const double deg = M_PI / 180;

#define qt_M_PI   4*M_PI/3

#define star_classes    12
#define planet_types    10
#define avgmoons        4
#define log2avgmoons	2
#define maxbodies	20 * avgmoons

char class_rgb[3*star_classes] = {
	63, 58, 40,
	30, 50, 63,
	63, 63, 63,
	63, 30, 20,
	63, 55, 32,
	32, 16, 10,
	32, 28, 24,
	10, 20, 63,
	63, 32, 16,
	48, 32, 63,
	40, 10, 10,
	00, 63, 63
};

Word class_ray[star_classes] = { 5000, 15000, 300, 20000, 15000, 1000, 3000,
				2000, 4000, 1500, 30000, 250 };

Word class_rayvar[star_classes] = { 2000, 10000, 200, 15000, 5000, 1000, 3000,
				   500, 5000, 10000, 1000, 10 };

Word class_act[star_classes] = { 2, 4, 1, 6, 5, 10, 100, 1, 2, 1, 10, 1 };

char class_planets[star_classes] = { 12, 18, 8, 15, 20, 3, 0, 1, 7, 20, 2, 5 };

char   nearstar_p_type       [maxbodies];
Word    nearstar_p_owner	     [maxbodies];
char   nearstar_p_moonid     [maxbodies];
double nearstar_p_ring       [maxbodies];
double nearstar_p_tilt       [maxbodies];
double nearstar_p_ray        [maxbodies];
double nearstar_p_orb_ray    [maxbodies];
double nearstar_p_orb_seed   [maxbodies];
double nearstar_p_orb_tilt   [maxbodies];
double nearstar_p_orb_orient [maxbodies];
double nearstar_p_orb_ecc    [maxbodies];

Word planet_possiblemoons[] = { 1, 1, 2, 3, 2, 2, 18, 2, 3, 20, 20 };

const double planet_orb_scaling=  5.0;
const double avg_planet_sizing =  2.4;
const double moon_orb_scaling  = 12.8;
const double avg_moon_sizing   =  1.8;

double avg_planet_ray[] = { 0.007, 0.003, 0.010, 0.011, 0.010,
			    0.008, 0.064, 0.009, 0.012, 0.125,
			    2.000 };

Uchar Nearstar_BodyNumber(Uchar pN, Uchar mN) {
	Uchar retval = 0;
	if (mN==0x1F) {
		retval = pN;
	} else {
		for (Uchar body = nearstar_nop; body<nearstar_nob; body++) {
			if (nearstar_p_owner[body]==pN && nearstar_p_moonid[body]==mN) {
				retval=body;
				break;
			}
		}
	}
	return retval;
}

void extract_ap_target_infos ()
{
	srand (ap_target_x/100000*ap_target_y/100000*ap_target_z/100000);

	ap_target_class = random (star_classes);
	ap_target_ray = ((float)class_ray[ap_target_class] + (float)random(class_rayvar[ap_target_class])) * 0.001;

	ap_target_r = class_rgb[3*ap_target_class+0];
	ap_target_g = class_rgb[3*ap_target_class+1];
	ap_target_b = class_rgb[3*ap_target_class+2];

	ap_target_spin = 0;
	if (ap_target_class==11) ap_target_spin = random (30) + 1;
	if (ap_target_class==7) ap_target_spin = random (12) + 1;
	if (ap_target_class==2) ap_target_spin = random (4) + 1;
}

void prepare_nearstar ()
{
	int    n, c, q, r, s, t;
	double key_radius;

	nearstar_class = ap_target_class;
	nearstar_x = ap_target_x;
	nearstar_y = ap_target_y;
	nearstar_z = ap_target_z;
	nearstar_ray = ap_target_ray;
	nearstar_spin = ap_target_spin;
	nearstar_r = ap_target_r;
	nearstar_g = ap_target_g;
	nearstar_b = ap_target_b;

	nearstar_identity = nearstar_x/100000*nearstar_y/100000*nearstar_z/100000;

	srand ((long)nearstar_x%10000*(long)nearstar_y%10000*(long)nearstar_z%10000);

	nearstar_nop = random (class_planets[nearstar_class] + 1);

	for (n=0; n<nearstar_nop; n++) {
		nearstar_p_owner[n]	 = -1;
		nearstar_p_orb_orient[n] = (double) deg * (double) random (360);
		nearstar_p_orb_seed[n]   = 3 * (n*n+1) * nearstar_ray + (float) random (300 * nearstar_ray) / 100;
		nearstar_p_tilt[n]       = zrandom (10*nearstar_p_orb_seed[n]) / 500;
		nearstar_p_orb_tilt[n]   = zrandom (10*nearstar_p_orb_seed[n]) / 5000;
		nearstar_p_orb_ecc[n]    = 1 - (double) random (nearstar_p_orb_seed[n] + 10*fabs(nearstar_p_orb_tilt[n])) / 2000;
		nearstar_p_ray[n]        = (double) random (nearstar_p_orb_seed[n]) * 0.001 + 0.01;
		nearstar_p_ring[n]	 = zrandom (nearstar_p_ray[n]) * (1 + (double) random (1000) / 100);
		if (nearstar_class != 8)
			nearstar_p_type[n] = random (planet_types);
		else {
			if (random(2)) {
				nearstar_p_type[n] = 10;
				nearstar_p_orb_tilt[n] *= 100;
			}
			else
				nearstar_p_type[n] = random (planet_types);
		}
		if (nearstar_class==2||nearstar_class==7||nearstar_class==15)
			nearstar_p_orb_seed[n] *= 10;
	}

	if (!nearstar_class) {
		if (random(4)==2) nearstar_p_type[2] = 3;
		if (random(4)==2) nearstar_p_type[3] = 3;
		if (random(4)==2) nearstar_p_type[4] = 3;
	}

	for (n=0; n<nearstar_nop; n++) {
		switch (nearstar_class) {
			case 2: while (nearstar_p_type[n]==3)
					nearstar_p_type[n] = random (10);
				break;
			case 5: while (nearstar_p_type[n]==6||
				       nearstar_p_type[n]==9)
					nearstar_p_type[n] = random (10);
				break;
			case 7:	nearstar_p_type[n] = 9;
				break;
			case 9: while (nearstar_p_type[n]!=0&&
				       nearstar_p_type[n]!=6&&
				       nearstar_p_type[n]!=9)
					nearstar_p_type[n] = random (10);
				break;
			case 11:while (nearstar_p_type[n]!=1&&
				       nearstar_p_type[n]!=7)
					nearstar_p_type[n] = random (10);
		}
	}

	for (n=0; n<nearstar_nop; n++) {
		switch (nearstar_p_type[n]) {
			case 0:
				if (random(8))
					nearstar_p_type[n] ++;
				break;
			case 3:
				if ((n<2)||(n>6)||(nearstar_class&&random(4))) {
					if (random(2))
						nearstar_p_type[n]++;
					else
						nearstar_p_type[n]--;
				}
				break;
			case 7:
				if (n<7) {
					if (random(2))
						nearstar_p_type[n] --;
					else
						nearstar_p_type[n] -= 2;
				}
				break;
		}
	}

	nearstar_nob = nearstar_nop;

	if (nearstar_class==2||nearstar_class==7||nearstar_class==15)
		goto no_moons;

	for (n=0; n<nearstar_nop; n++) {
		// (t=) Numero di satelliti per pianeta.
		s = nearstar_p_type[n];
		if (n < 2) {
			t = 0;
			if (s == 10)
				t = random (3);
		}
		else
			t = random (planet_possiblemoons[s] + 1);
		if (nearstar_nob + t > maxbodies)
			t = maxbodies - nearstar_nob;
		for (c=0; c<t; c++) {
			q 			 = nearstar_nob + c;
			nearstar_p_owner[q]	 = n;
			nearstar_p_moonid[q]	 = c;
			nearstar_p_orb_orient[q] = (double) deg * (double) random (360);
			nearstar_p_orb_seed[q]   = (c*c+4) * nearstar_p_ray[n] + (float) zrandom (300 * nearstar_p_ray[n]) / 100;
			nearstar_p_tilt[q]       = zrandom (10*nearstar_p_orb_seed[q]) / 50;
			nearstar_p_orb_tilt[q]   = zrandom (10*nearstar_p_orb_seed[q]) / 500;
			nearstar_p_orb_ecc[q]    = 1 - (double) random (nearstar_p_orb_seed[q] + 10*fabs(nearstar_p_orb_tilt[q])) / 2000;
			nearstar_p_ray[q]        = (double) random (nearstar_p_orb_seed[n]) * 0.05 + 0.1;
			nearstar_p_ring[q]	 = 0;
			nearstar_p_type[q]       = random (planet_types);
			r = nearstar_p_type[q];
			if (r==9 && s != 10) r = 2;
			if (r==6 && s < 9) r = 5;
			if (n > 7 && random(c)) r = 7;
			if (n > 9 && random(c)) r = 7;
			if (r==2 || r==3 || r==4 || r==8) {
				if (s != 6 && s < 9)
					r = 1;
			}
			if (r==3 && s < 9) {
				if (n > 7)
					r = 7;
				if (nearstar_class && random(4))
					r = 5;
				if (nearstar_class == 2 ||
				    nearstar_class == 7 ||
				    nearstar_class == 11)
					r = 8;
			}
			if (r==7 && n <= 5) r = 1;
			if ((nearstar_class==2||nearstar_class==5||
			     nearstar_class==7||nearstar_class==11)
			     && random(n)) r = 7;
			nearstar_p_type[q] = r;
		}
		nearstar_nob += t;
	}

no_moons:
	key_radius = nearstar_ray * planet_orb_scaling;
	if (nearstar_class == 8) key_radius *= 2;
	if (nearstar_class == 2) key_radius *= 16;
	if (nearstar_class == 7) key_radius *= 18;
	if (nearstar_class == 11) key_radius *= 20;
	for (n=0; n<nearstar_nop; n++) {
		nearstar_p_ray[n] = avg_planet_ray[nearstar_p_type[n]]
				  + avg_planet_ray[nearstar_p_type[n]] * zrandom (100) / 200;
		nearstar_p_ray[n] *= avg_planet_sizing;
		nearstar_p_orb_ray[n] = key_radius + key_radius * zrandom (100) / 500;
		nearstar_p_orb_ray[n] += key_radius * avg_planet_ray[nearstar_p_type[n]];
		if (n < 8)
			key_radius += nearstar_p_orb_ray[n];
		else
			key_radius += 0.22 * nearstar_p_orb_ray[n];
	}

	n = nearstar_nop;
	while (n < nearstar_nob) {
		q = 0;
		c = nearstar_p_owner[n];
		key_radius = nearstar_p_ray[c] * moon_orb_scaling;
		while (n<nearstar_nob && nearstar_p_owner[n] == c) {
			nearstar_p_ray[n] = avg_planet_ray[nearstar_p_type[n]]
					  + avg_planet_ray[nearstar_p_type[n]] * zrandom (100) / 200;
			nearstar_p_ray[n] *= avg_moon_sizing;
			nearstar_p_orb_ray[n] = key_radius + key_radius * zrandom (100) / 250;
			nearstar_p_orb_ray[n] += key_radius * avg_planet_ray[nearstar_p_type[n]];
			if (q < 2) key_radius += nearstar_p_orb_ray[n];
			if (q >= 2 && q < 8) key_radius += 0.12 * nearstar_p_orb_ray[n];
			if (q >= 8) key_radius += 0.025 * nearstar_p_orb_ray[n];
			q++;
			n++;
		}
	}

	for (n = 0; n < nearstar_nop; n++) {
		nearstar_p_ring[n] = 0.75 * nearstar_p_ray[n] * (2 + random(3));
		s = nearstar_p_type[n];
		if (s != 6 && s != 9) {
			if (random(5))
				nearstar_p_ring[n] = 0;
		}
		else {
			if (random(2))
				nearstar_p_ring[n] = 0;
		}
	}
}

void main ()
{
	CHECK_SITUATION;
	char query;
	Word j, pre;
	Word is, rec, rec_start, rec_end;
	Word ghold;

	/*asm {	xor	ax, ax
		mov	es, ax
		cmp	byte ptr es:[0x449], 0x13
		je	startup }

	printf ("\nGalactic Organization of Explorers and Stardrifters (G.O.E.S)\n");
	printf ("-------------------------------------------------------------\n");
	printf ("This is a GOES NET module and must be run from a stardrifter.\n");
	printf ("Please use the onboard computer console to run this module.\n");
	printf ("\n\t- GOES NET onboard microsystem, EPOC 6011 REVISION 2\n");
	return;

	startup:*/
	if (_argc<2) {
		msg ("________USAGE________");
		msg ("IMPORTGD OBJECTNAME");
		msg ("IMPORTGD OBNAME:X..Y");
		msg ("^^^^^^^^^^^^^^^^^^^^^");
		msg ("PLEASE RUN AGAIN,");
		msg ("SPECIFYING PARAMETERS");
		return;
	}
	else {
		msg (" GOES GALACTIC GUIDE ");
		msg (divider);
	}

	fh = fopen (file, "rb");
	if (fh == NULL) {
		msg ("STARMAP NOT AVAILABLE");
		return;
	}
	Udword starmap3Len = 0;
	fseek(fh, 0, SEEK_END);
	starmap3Len = ftell(fh);
	fseek(fh, 0, SEEK_SET);
	Uword fileFormatVersion;
	Udword starmap3VersionHalf;
	fread(&fileFormatVersion, 2, 1, fh);
	fread(&starmap3VersionHalf, 4, 1, fh);
	fread(&starmap3VersionHalf, 4, 1, fh);
	
	i = 2;
	strcpy (parbuffer, _argv[1]);
	while (i < _argc) {
		strcat (parbuffer, " ");
		strcat (parbuffer, _argv[i]);
		i++;
	}

	i = 0;
	while (parbuffer[i]) {
		if (parbuffer[i] == '_')
			parbuffer[i] = 32;
		i++;
	}

	i = 0;
	while (i < 21 && parbuffer[i] != ':' && parbuffer[i] != 0) {
		objectname[i] = parbuffer[i];
		i++;
	}

	if (i == 21) {
		msg ("INVALID SUBJECT NAME.");
		fclose (fh);
		return;
	}

	if (parbuffer[i] == ':') {
		is = i+1; i++;
		while (parbuffer[i] != '.' && parbuffer[i] != 0) i++;
		parbuffer[i] = 0; rec_start = atoi (parbuffer + is);
		if (parbuffer[i+1] == '.') {
			rec_end = atoi (parbuffer + i + 2);
			if (rec_end==0) rec_end=32767;
		} else {
			rec_end = rec_start;
		}
	}
	else {
		rec_start = 1;
		rec_end = 32767;
	}
	
	if (parbuffer[i] != ':') {
		strupr (parbuffer);
		strupr (objectname);
		objectname[i] = 0;
		Dword matches = FindInStarmap (fh, starmap3Len, objectname, &sm3data);
		if (matches==0) {
			msg("OBJECT NOT FOUND");
			msg("IN STARMAP");
		} else {
			PrepareFromSectorCoords(sm3data.sx, sm3data.sy, sm3data.sz);
			ap_target_x = foundstar_x;
			ap_target_y = foundstar_y;
			ap_target_z = foundstar_z;
			nearstar_sx = foundstar_sx;
			nearstar_sy = foundstar_sy;
			nearstar_sz = foundstar_sz;
			obj_pNum = sm3data.pNum;
			obj_mNum = sm3data.mNum;
			//ap_target_id = foundstar_id;
			extract_ap_target_infos ();
			prepare_nearstar ();
			Word bn = 0;
			if (sm3data.retvalType==RETVAL_PLANET) {
				bn = Nearstar_BodyNumber(sm3data.pNum, sm3data.mNum)+1;
			}
			//printf("BN %i.", bn);
			subject_id = foundstar_id + bn;
		//if (query) {
			gh = fopen (guide, "a+b");
			Udword guide3Len = 0;
			fseek(gh, 0, SEEK_END);
			guide3Len = ftell(gh);
			oldgh = fopen (oldguide, "rb");
			if (gh == NULL) {
				msg("MISSING STARMAP3.GD");
				msg("(NEW GUIDE)");
			} else if (oldgh==NULL) {
				msg ("MISSING STARMAP.BIN");
				msg ("(OLD GUIDE)");
			} else {
				Udword oldguide3Len = 0;
				fseek(oldgh, 0, SEEK_END);
				oldguide3Len = ftell(oldgh);
				fseek(oldgh, 4, SEEK_SET);
				
				rec = 0;
				Udword recordsImported = 0;
				Udword preexistingRecords = 0;
				while (ftell(oldgh)<oldguide3Len) {
					fread (&mblock_subject, 84, 1, oldgh);
					if (mblock_subject > subject_id - idscale && mblock_subject < subject_id + idscale) {
						rec++;
						if (rec >= rec_start && rec <= rec_end) {
							Uchar flags;
							Udword writer;
							Dword tmp_sx, tmp_sy, tmp_sz;
							Uword tmp_pNum, tmp_mNum;
							char tmp_msg[77];
							fseek(gh, 10, SEEK_SET);
							int found = 0;
							while (ftell(gh)<guide3Len) {
								fread(&flags, 1, 1, gh);
								fread(&tmp_sx, 4, 1, gh);
								fread(&tmp_sy, 4, 1, gh);
								fread(&tmp_sz, 4, 1, gh);
								fread(&tmp_pNum, 2, 1, gh);
								fread(&tmp_mNum, 2, 1, gh);
								fread(&writer, 4, 1, gh);
								fread(msg, 76, 1, gh);
								if (!(flags&0x20) && tmp_sx==nearstar_sx && tmp_sy==nearstar_sy && tmp_sz==nearstar_sz && tmp_pNum==sm3data.pNum && tmp_mNum==sm3data.mNum && memcmp(msg, mblock_message, 76)==0) {
									//already exists
									preexistingRecords++;
									found=1;
									break;
								}
							}
							
							fseek(gh, 0, SEEK_END);
							if (found==0) {
								recordsImported++;
								flags = 0xC0;
								fwrite(&flags, 1, 1, gh);
								fwrite(&nearstar_sx, 4, 1, gh);
								fwrite(&nearstar_sy, 4, 1, gh);
								fwrite(&nearstar_sz, 4, 1, gh);
								fwrite(&obj_pNum, 2, 1, gh);
								fwrite(&obj_mNum, 2, 1, gh);
								writer=0xfffffffe;
								fwrite(&writer, 4, 1, gh);
								fwrite(mblock_message, 76, 1, gh);
							}
						}
					}
				}
				
				if (preexistingRecords>0) {
					sprintf(outbuffer, "%lu RECORDS ALREADY", preexistingRecords);
					msg(outbuffer);
					msg("EXISTED");
				}
				if (recordsImported>0) {
					sprintf(outbuffer, "%lu RECORDS IMPORTED", recordsImported);
					msg(outbuffer);
					msg("SUCCESSFULLY");
				} else {
					msg ("NO RECORDS IMPORTED");
				}
				fclose (oldgh);
				
				/*
				lseek (gh, 0, SEEK_END);	//already there, we opened it with "ab"
				_write (gh, &subject_id, 8);
				_write (gh, parbuffer + i + 1, mlen);
				
				round = filelength (gh) - 4;
				if (round >= 0) {
					round %= 84;
					if (round) {
						round = 84 - round;
						_write (gh, nullbuffer, round);
					}
					msg ("MESSAGE ACCEPTED.");
				}
				else {
					msg ("DATABASE ERROR;");
					msg ("MESSAGE REJECTED.");
					msg ("(ERROR CODE 1002)");
				}*/
				
				fclose (gh);
			}
		}
	}

	fclose (fh);
}