var FRAME_ANSI					= (1<<1);

load('ansitex/load/frame-page.js');

// Our frame object
function FrameAnsi() {
	PageFrame.apply(this,arguments);

	/* File Extension used for frames */
	this.settings.ext = 'tex';

	/* Length of a frame */
	this.settings.FRAME_LENGTH			= 22;
	/* Width of a frame */
	this.settings.FRAME_WIDTH			= 80;
	/* Size of page owner (length) */
	this.settings.FRAME_HEADER			= 56;
	/* Size of page number (length with a-z) */
	this.settings.FRAME_PAGENUM			= 12;
	/* Size of cost	(length without unit) */
	this.settings.FRAME_COST				= 9;

	this.settings.MSG_SENDORNOT			= '\1n\1h\1GKEY 1 TO SEND, 2 NOT TO SEND';
	this.settings.MSG_LOGON				= '\1n\1h\1GKEY 1 TO LOGON, 2 TO RETURN';
	this.settings.MSG_SENT				= '\1n\1h\1GMESSAGE SENT - KEY # TO CONTINUE';
	this.settings.MSG_NOTSENT			= '\1n\1h\1GMESSAGE NOT SENT - KEY # TO CONTINUE';
	this.settings.ERR_NO_PARENT			= '\1n\1h\1RPARENT FRAME DOESNT EXIST';
	this.settings.ERR_NOT_IMPLEMENTED	= '\1n\1h\1RNOT IMPLEMENTED YET?';
	this.settings.ERR_ROUTE				= '\1n\1h\1WMISTAKE? \1GTRY AGAIN OR TELL US ON *08';
	this.settings.ERR_METHOD_NOT_EXIST	= '\1n\1h\1WMISTAKE? \1GTRY AGAIN OR TELL US ON *08';
	this.settings.ACCESS_DENIED			= '\1n\1h\1RACCESS DENIED. MISTAKE? TRY AGAIN OR TELL US *08';
	this.settings.ALREADY_MEMBER		= '\1n\1h\1RALREADY MEMBER OF CUG'
	this.settings.INACTIVITY			= '\1n\1h\1RINACTIVITY ALERT, DISCONNECT PENDING...';
	this.settings.INACTIVE				= '\1n\1h\1RINACTIVITY DISCONNECT';
	this.settings.NOACTION				= '\1n\1h\1RNO ACTION PERFORMED';
	this.settings.BASESTAR				= '\1N\1G\1H*';
	this.settings.INVALID_CODE			= '\1n\1h\1RINVAID CODE, PLEASE TRY AGAIN *00';
	this.settings.TOKEN_EMAIL			= '\1n\1h\1RTOKEN EMAILED TO YOU...';
	this.settings.TOKEN_SENT			= '\1n\1h\1RTOKEN SENT, PLEASE ENTER TOKEN';
	this.settings.INVALID_EMAIL			= '\1n\1h\1RINVAID EMAIL, PLEASE TRY AGAIN *00';
	this.settings.INVALID_UID			= '\1n\1h\1RINVAID USER ID, PLEASE TRY AGAIN *00';
	this.settings.CANNOT_SEND_TOKEN		= '\1n\1h\1RCANNOT SEND VALIDATION CODE, PLEASE TRY AGAIN *00';
	this.settings.USER_EXISTS			= '\1n\1h\1RERROR USER EXISTS, PLEASE TRY AGAIN *00';
	this.settings.USER_CREATE_ERROR		= '\1n\1h\1RERROR CREATING USER, PLEASE TRY AGAIN *00';
	this.settings.LOGIN_ERROR			= '\1n\1h\1RERROR LOGGING IN, PLEASE TRY AGAIN *00';
	this.settings.CANCEL_MSG			= '\1n\1h\1GPRESS 2 TO CANCEL';
	this.settings.SYS_ERROR				= '\1n\1h\1RSYSTEM ERROR DETECTED - TRY AGAIN OR TELL US *08';
	this.settings.LOADING				= '\1n\1h\1Wloading...';

	/**
	 * Set the attribute at the current position
	 */
	this.attr=function(field) {
		console.write(ascii(27)+'['+field.i+';'+field.f+';'+field.b+'m');
	}

	/**
	 * Turn off the cursor
	 */
	this.cursorOff=function() {
		ansi.send('ext_mode','clear','cursor');
		this.gotoxy(0,24);
	}

	this.cursorOn=function(x,y) {
		ansi.send('ext_mode','set','cursor');
		if (x && y)
			this.gotoxy(x,y);
	}

	// Field backspace, that leaves the field filler char
	this.fieldbs=function(char) {
		console.write(ascii(27)+'[D'+char+ascii(27)+'[D');
	}

	this.gotoxy=function(x,y) {
		console.gotoxy(x,y);
	}

	// Render the frame to the user
	this.render=function(context,withoutHeader) {
		log(LOG_DEBUG,'- ANSI FRAME');
		owner = base64_decode(this.owner);

		const frame = new Frame(1,1,this.settings.FRAME_WIDTH,this.settings.FRAME_LENGTH+2,LIGHTGRAY);
		frame.open();

		// Dont show the page number on system login page
		if ((! withoutHeader) && (user.number || (this.type !== FRAME_TYPE_LOGIN && NO_HISTORY_FRAMES.indexOf(this.page) === -1))) {
			log(LOG_DEBUG,'  - Owner: ['+this.pageowner+']');

			cost = (this.isAccessible ? this.cost+FRAME_COSTUNIT : ' -');

			header = '\1n'+this.pageownerlogo+' '.repeat(this.settings.FRAME_HEADER-console.strlen(this.pageownerlogo))+'\1n '+
				(this.isAccessible ? '\1W' : '\1R')+'\1H'+this.page+' '.repeat(this.settings.FRAME_PAGENUM-this.page.length)+' '+
				'\1G\1H'+' '.repeat(this.settings.FRAME_COST-cost.toString().length+1)+cost+'\1n'+
				(console.screen_columns > 80 ? '\n\r' : '');

			frame.putmsg(header);
		}

		contentgraphic = new Graphic(this.settings.FRAME_WIDTH);
		contentgraphic.auto_extend = true;
		contentgraphic.atcodes = false;
		contentgraphic.ANSI = this.parse(base64_decode(this.content),context);

		var contentframe = new Frame(1,2,this.settings.FRAME_WIDTH,this.settings.FRAME_LENGTH,LIGHTGRAY,frame);
		contentframe.open();
		contentframe.lf_strict = false;
		contentframe.atcodes = false;
		contentframe.word_wrap = false

		contentframe.putmsg(contentgraphic.MSG)
		contentframe.scrollTo(0,0);

		frame.cycle();

		return contentframe;
	};

	this.qrcode=function(qr,subframe) {
		// SMALL Image
		var full = ascii(0xdb);
		var top = ascii(0xdf);
		var bot = ascii(0xdc);
		var blank = ' ';

		var qrcode = '';

		/*
		// Render the top line
		var line = ascii(27)+'[1;37m'+bot;
		for (var y = 0; y < qr.size; y++) {
			line += bot;
		}
		qrcode += line+bot+bot+ascii(27)+'[0m'+"\r\n";
		*/

		// Render the body
		for (var x = -1; x < qr.size; x=x+2) {
			line = ascii(27)+'[1;37m'+full;

			for (var y = 0; y < qr.size; y++) {
				// Top is white
				if (! ((x===-1)? 0 : qr.getModule(x, y))) {
					line += (qr.getModule(x+1, y)) ? top : full;

				// Top is black
				} else {
					line += (qr.getModule(x+1, y)) ? blank : bot;
				}
			}

			qrcode += line+full+ascii(27)+'[0m'+"\r\n";
		}

		// Render the bottom
		line = ascii(27)+'[1;37m'+top;
		for (var y = 0; y < qr.size; y++) {
			line += top;
		}
		qrcode += line+top+ascii(27)+'[0m'+"\r\n";

		ans2bin(fo.parse(qrcode),subframe);
		subframe.open();
		subframe.cycle();
	};

	this.save=function() {
		file = system.mods_dir+'ansitex/text/'+this.page+'.tex';
		w = new File(file);
		if (! w.open('w')) {
			log(LOG_ERROR,'! ERROR: Unable to create TEX file for '+this.page);
			exit(1);
		}

		w.write(JSON.stringify(this));
		w.close();

		log(LOG_DEBUG,'Saved file: '+this.page+'.tex');
	}

	/**
	 * Send a message to the baseline.
	 *
	 * @param text
	 * @param reposition
	 */
	this.sendBaseline=function(text,reposition) {
		console.pushxy();
		console.gotoxy(0,24);
		console.print(this.getMessage(text));
		console.cleartoeol();

		if (! reposition) {
			console.popxy();
		}
	}

	this.clearBaseline=function(reposition) {
		console.pushxy();
		console.gotoxy(0,24);
		console.print('');
		console.cleartoeol();

		if (! reposition) {
			console.popxy();
		}
	}
}

FrameAnsi.prototype = PageFrame.prototype;
FrameAnsi.prototype.constructor = FrameAnsi;