
registerType('appdoo.iOSGenerator', (function () { function PluginCodeConfigurator() {} var __super = setSupertypeFromDomain(PluginCodeConfigurator, 'BasicObject', 'Core');

	Object.defineProperty(PluginCodeConfigurator.prototype, "files", {
	outlet: true, 
	synthesized: true, get:function () { return this._files; }, set:function (v) {if (!Object.hasOwnProperty(this, "_files")) Object.defineProperty(this, "_files", { writable: true, configurable: true }); this._files = v; }});
	
	
	Object.defineProperty(PluginCodeConfigurator.prototype, "productGenerator", {
	outlet: true, 
	synthesized: true, get:function () { return this._productGenerator; }, set:function (v) {if (!Object.hasOwnProperty(this, "_productGenerator")) Object.defineProperty(this, "_productGenerator", { writable: true, configurable: true }); this._productGenerator = v; }});
	

PluginCodeConfigurator.prototype.configureObject = function PluginCodeConfigurator_configureObject(obj) {
		var rules = this.rulesForObject(obj);
		var pluginIdentifier = this.pluginIdentifierForObject(obj);
		var fileContext = this.fileContextForObject(obj);
		if (Array.isArray(rules)) rules.every(function (rule) {
			this.applyRuleInFileContext(rule, fileContext, pluginIdentifier, obj);return true; }, this);
		};
	

	
PluginCodeConfigurator.prototype.fileContextForObject = function PluginCodeConfigurator__fileContextForObject(obj) {
	
		var projectName = this.productGenerator.projectName;
	
		var implementationId;

		if (obj.cell)
			implementationId = obj.cell.customClass;
		else
			implementationId = this.productGenerator.codeIDForViewControllerID(obj.viewController.$id);
		
		var fileContext = {
			header: projectName+'/'+implementationId+'.h',
			implementation: projectName+'/'+implementationId+'.m',
			masterViewController: {
				header: '',
				implementation: ''
			},
		}
		
		if (obj.viewController.masterViewControllerId) {
		
			var masterVCImplementationId = this.productGenerator.codeIDForViewControllerID(obj.viewController.masterViewControllerId);
			
			fileContext.masterViewController.header = projectName+'/'+masterVCImplementationId+'.h';
			fileContext.masterViewController.implementation = projectName+'/'+masterVCImplementationId+'.m';
			
		}
	
		return fileContext;};
	
	
PluginCodeConfigurator.prototype.rulesForObject = function PluginCodeConfigurator__rulesForObject(obj) {
		var pluginIdentifier = this.pluginIdentifierForObject(obj);
		var plugin = window.availablePlugins[pluginIdentifier];
		var rules = JSON.parse(this.context.nativeProxy.sendMessage('stringFromFile', plugin.path+'/Rules.json'));
		return rules;};
	

PluginCodeConfigurator.prototype.pluginIdentifierForObject = function PluginCodeConfigurator__pluginIdentifierForObject(obj) {
		if (obj.pluginIdentifier) return obj.pluginIdentifier;
		var UTI = obj.data.$domain + '.' + obj.data.$type;
		var proto = getType(UTI).prototype;
		return proto.pluginIdentifier;};
	

PluginCodeConfigurator.prototype.getFileInContext = function PluginCodeConfigurator__getFileInContext(keyPath, fileContext) {
		var fileId = this.context.dissolveKeyPathWithContextObject(keyPath, fileContext);
		return this.files[fileId];};
	

PluginCodeConfigurator.prototype.setFileInContext = function PluginCodeConfigurator__setFileInContext(newFile, keyPath, fileContext) {
		var segments = keyPath.split('.');
		if (segments.length === 1) {
			var fileId = fileContext[segments[0]];
			this.files[fileId] = newFile;
		}
		else if (segments.length === 2) {
			var fileId = fileContext[segments[0]][segments[1]];
			this.files[fileId] = newFile;
		}
		else {
			console.error('Unsupported keyPath:', keyPath);
		}};
	
	
PluginCodeConfigurator.prototype.applyRuleInFileContext = function PluginCodeConfigurator__applyRuleInFileContext(rule, fileContext, pluginIdentifier, obj) {

		var file = this.getFileInContext(rule.fileKeyPath, fileContext);

		if (!file) {
			console.warn('Could not apply rule, file not available.', rule);
			return;
		}
		
		if (rule.selector) {

			
	
			var symbol = rule.selector.split(':')[0],
				position = this.positionInMethodForInsertion(symbol, file);
			
			if (position < 0) {
				console.warn('Could not apply rule, selector not found.', rule);
				return;
			}
			
			var newFile = file.slice(0,position);
			newFile += this.prepareCode(rule.code, obj);
			newFile += file.slice(position,file.length);
			file = newFile;
		}

		if (rule.importPlugin)
			file = this.fileWithPluginImportDirective(file, pluginIdentifier);
		
		this.setFileInContext(file, rule.fileKeyPath, fileContext);
		};
	
	
PluginCodeConfigurator.prototype.positionInMethodForInsertion = function PluginCodeConfigurator__positionInMethodForInsertion(symbol, file) {
		var pos = file.indexOf(symbol),
			length = file.length,
			level = 0;
		
		while (pos++ < length) {
			if (file[pos] == '}') {
			 	if (level === 1) return pos;
			 	level--;
			}
			if (file[pos] == '{') level++;
		}
		
		return -1;};
	
	
PluginCodeConfigurator.prototype.fileWithPluginImportDirective = function PluginCodeConfigurator__fileWithPluginImportDirective(file, pluginIdentifier) {
	
		var directive = '#import "'+pluginIdentifier+'/'+pluginIdentifier+'.h"';

		file = directive+"\n"+file;
	
		return file;};
	
	
	var functions = {
		"NSString": function (str) {
			if (!str) return "@\"\"";
			return "@\""+str.replace("\"","\\\"").replace("\n", "\\\n")+"\"";
		}
	};

	function replaceVariable(str, context) {
		
		
		if (str.indexOf('(') !== -1) {
			var pieces = str.match(/(.*?)\((.*?)\)/);
			var str = replaceVariable.call(this, pieces[2], context);
			var func = functions[pieces[1]];
			return func.call(this, str);
		}
		
		return this.context.dissolveKeyPathWithContextObject(str, context);

	}

PluginCodeConfigurator.prototype.prepareCode = function PluginCodeConfigurator__prepareCode(code, obj) {
	
		var re = /\$\{.*?\}/g,
			str = code,
			context = {
				instance: obj.symbol,
				properties: obj.data
			};
		
		while ((match = re.exec(str)) != null) {
			var pos = match.index;
	
			var symbol = match[0].substr(2, match[0].length-3);
			
			str = str.slice(0, pos) + replaceVariable.call(this, symbol, context) + str.slice(pos+match[0].length);
		}
		
		return str;
	};
	
	
PluginCodeConfigurator.prototype.initPropertiesFromData = function PluginCodeConfigurator_initPropertiesFromData(data) {
try { __super.prototype.initPropertiesFromData.call(this, data); } catch (err) {}
if (data.hasOwnProperty("files")) this.files = data.files;
if (data.hasOwnProperty("productGenerator")) this.productGenerator = data.productGenerator;
};

PluginCodeConfigurator.prototype.decodeData = function PluginCodeConfigurator_decodeData(data) { var decoded;
try { decoded = __super.prototype.decodeData.call(this, data); } catch (err) { console.warn(err); decoded = clone(data); }
return decoded; };

PluginCodeConfigurator.prototype.encode = function PluginCodeConfigurator_encode() { var encoded;
try { encoded = __super.prototype.encode.call(this); } catch (err) { console.warn(err); encoded = this.context.encodeObject(this); }
return encoded; };

PluginCodeConfigurator.prototype.encodeCloned = function PluginCodeConfigurator_encodeCloned() { var encoded;
try { encoded = __super.prototype.encodeCloned.call(this); } catch (err) { console.warn(err); encoded = {}; }
return encoded; };

PluginCodeConfigurator.prototype.expectedTypeForProperty = function PluginCodeConfigurator_expectedTypeForProperty(key) {
	if (key === "files") return "";
	if (key === "productGenerator") return "";
	if (__super) return __super.prototype.expectedTypeForProperty(key);
};

return PluginCodeConfigurator; }()));