/* jslint node: true */ 'use strict'; var TextView = require('./text_view.js').TextView; var EditTextView = require('./edit_text_view.js').EditTextView; var ButtonView = require('./button_view.js').ButtonView; var VerticalMenuView = require('./vertical_menu_view.js').VerticalMenuView; var HorizontalMenuView = require('./horizontal_menu_view.js').HorizontalMenuView; var SpinnerMenuView = require('./spinner_menu_view.js').SpinnerMenuView; var ToggleMenuView = require('./toggle_menu_view.js').ToggleMenuView; var MaskEditTextView = require('./mask_edit_text_view.js').MaskEditTextView; var StatusBarView = require('./status_bar_view.js').StatusBarView; var MultiLineEditTextView = require('./multi_line_edit_text_view.js').MultiLineEditTextView; var getMessageAreaByName = require('./message_area.js').getMessageAreaByName; var Config = require('./config.js').config; var ansi = require('./ansi_term.js'); var packageJson = require('../package.json'); var assert = require('assert'); var os = require('os'); var _ = require('lodash'); var moment = require('moment'); exports.MCIViewFactory = MCIViewFactory; function MCIViewFactory(client) { this.client = client; } // :TODO: This portion should be made more generic so pipe code formatting can use it! // e..g MCIPrint() -> enigmaToAnsi() -> MCIViewFactory.prototype.getPredefinedViewLabel = function(code) { var self = this; function getMessageAreaDescription() { var area = getMessageAreaByName(self.client.user.properties.message_area_name); return area ? area.desc : ''; } function getCurrentMenuDescription() { return _.has(self, 'client.currentMenuModule.menuConfig.desc') ? self.client.currentMenuModule.menuConfig.desc : ''; } try { return { BN : Config.general.boardName, VL : 'ENiGMA½ v' + packageJson.version, VN : packageJson.version, UN : this.client.user.username, UI : this.client.user.userId.toString(), UG : _.values(this.client.user.groups).join(', '), UR : this.client.user.properties.real_name, LO : this.client.user.properties.location, UA : this.client.user.getAge().toString(), UB : moment(this.client.user.properties.birthdate).format(this.client.currentTheme.helpers.getDateFormat()), US : this.client.user.properties.sex, UE : this.client.user.properties.email_address, UW : this.client.user.properties.web_address, UF : this.client.user.properties.affiliation, UT : this.client.user.properties.theme_id, UC : this.client.user.properties.login_count.toString(), MS : moment(this.client.user.properties.account_created).format(this.client.currentTheme.helpers.getDateFormat()), CS : this.client.currentStatus, MD : getCurrentMenuDescription(), MA : getMessageAreaDescription(), SH : this.client.term.termHeight.toString(), SW : this.client.term.termWidth.toString(), ND : this.client.node.toString(), // :TODO: change to CD for 'Current Date' DT : moment().format(this.client.currentTheme.helpers.getDateFormat()), CT : moment().format(this.client.currentTheme.helpers.getTimeFormat()), OS : { linux : 'Linux', darwin : 'Mac OS X', win32 : 'Windows', sunos : 'SunOS', freebsd : 'FreeBSD', }[os.platform()] || os.type(), OA : os.arch(), SC : os.cpus()[0].model, IP : this.client.address().address, }[code]; } catch(e) { this.client.log.warn( { code : code, exception : e.message }, 'Exception caught attempting to construct predefined label'); } }; /* MCIViewFactory.getUserViewClass = function(code) { return { TL : TextView, ET : EditTextView, ME : MaskEditTextView, MT : MultiLineEditTextView, PL : TextView, BT : ButtonView, VM : VerticalMenuView, HM : HorizontalMenuView, SM : SpinnerMenuView, TM : ToggleMenuView, }[code]; }; */ MCIViewFactory.UserViewCodes = [ 'TL', 'ET', 'ME', 'MT', 'PL', 'BT', 'VM', 'HM', 'SM', 'TM' ]; MCIViewFactory.prototype.createFromMCI = function(mci) { assert(mci.code); assert(mci.id > 0); assert(mci.position); var view; var options = { client : this.client, id : mci.id, ansiSGR : mci.SGR, ansiFocusSGR : mci.focusSGR, position : { row : mci.position[0], col : mci.position[1] }, }; // :TODO: These should use setPropertyValue()! function setOption(pos, name) { if(mci.args.length > pos && mci.args[pos].length > 0) { options[name] = mci.args[pos]; return true; } return false; } function setWidth(pos) { if(mci.args.length > pos && mci.args[pos].length > 0) { if(!_.isObject(options.dimens)) { options.dimens = {}; } options.dimens.width = parseInt(mci.args[pos], 10); return true; } return false; } function setFocusOption(pos, name) { if(mci.focusArgs && mci.focusArgs.length > pos && mci.focusArgs[pos].length > 0) { options[name] = mci.focusArgs[pos]; } return false; } // // Note: Keep this in sync with UserViewCodes above! // switch(mci.code) { // Text Label (Text View) case 'TL' : setOption(0, 'textStyle'); setOption(1, 'justify'); setWidth(2); view = new TextView(options); break; // Edit Text case 'ET' : setWidth(0); setOption(1, 'textStyle'); setFocusOption(0, 'focusTextStyle'); view = new EditTextView(options); break; // Masked Edit Text case 'ME' : setOption(0, 'textStyle'); setFocusOption(0, 'focusTextStyle'); view = new MaskEditTextView(options); break; // Multi Line Edit Text case 'MT' : // :TODO: apply params view = new MultiLineEditTextView(options); break; // Pre-defined Label (Text View) case 'PL' : if(mci.args.length > 0) { options.text = this.getPredefinedViewLabel(mci.args[0]); if(options.text) { setOption(1, 'textStyle'); setOption(2, 'justify'); setWidth(3); view = new TextView(options); } } break; // Button case 'BT' : if(mci.args.length > 0) { options.dimens = { width : parseInt(mci.args[0], 10) }; } setOption(1, 'textStyle'); setOption(2, 'justify'); setFocusOption(0, 'focusTextStyle'); view = new ButtonView(options); break; // Vertial Menu case 'VM' : setOption(0, 'itemSpacing'); setOption(1, 'justify'); setOption(2, 'textStyle'); setFocusOption(0, 'focusTextStyle'); view = new VerticalMenuView(options); break; // Horizontal Menu case 'HM' : setOption(0, 'itemSpacing'); setOption(1, 'textStyle'); setFocusOption(0, 'focusTextStyle'); view = new HorizontalMenuView(options); break; case 'SM' : setOption(0, 'textStyle'); setOption(1, 'justify'); setFocusOption(0, 'focusTextStyle'); view = new SpinnerMenuView(options); break; case 'TM' : if(mci.args.length > 0) { var styleSG1 = { fg : parseInt(mci.args[0], 10) }; if(mci.args.length > 1) { styleSG1.bg = parseInt(mci.args[1], 10); } options.styleSG1 = ansi.getSGRFromGraphicRendition(styleSG1, true); } setFocusOption(0, 'focusTextStyle'); view = new ToggleMenuView(options); break; default : options.text = this.getPredefinedViewLabel(mci.code); if(_.isString(options.text)) { setWidth(0); setOption(1, 'textStyle'); setOption(2, 'justify'); view = new TextView(options); } else { // :TODO: log this } break; } return view; };