<commit_before>/** 
 * @license Copyright 2010 <NAME> (<EMAIL>)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 * limitations under the License.
 * @author <EMAIL> (<NAME>)
 */
goog.provide("kemia.controller.ReactionEditor");
goog.provide("kemia.controller.ReactionEditor.EventType");
goog.require("kemia.view.ReactionRenderer");
goog.require("kemia.view.MoleculeRenderer");
goog.require("goog.graphics");
goog.require('goog.events');
goog.require('goog.fx.Dragger');
goog.require('goog.fx.Dragger.EventType');
goog.require('goog.editor.BrowserFeature');
goog.require('goog.async.Delay');
goog.require('kemia.controller.Plugin');
goog.require('kemia.model.NeighborList');
goog.require('goog.ui.Prompt');
// goog.require('goog.ui.KeyboardShortcutHandler');

/**
 * A graphical editor for reactions
 * 
 * 
 * @constructor
 * @extends {goog.events.EventTarget}
 */
kemia.controller.ReactionEditor = function(element, opt_config) {
	goog.events.EventTarget.call(this);
	this.originalElement = element;
	this.id = element.id;
	this.editableDomHelper = goog.dom.getDomHelper(element);
	this.models = [];
	/**
	 * Map of class id to registered plugin.
	 * 
	 * @type {Object}
	 * @private
	 */
	this.plugins_ = {};

	/**
	 * Plugins registered on this editor, indexed by the
	 * kemia.controller.Plugin.Op that they support.
	 * 
	 * @type {Object.<Array>}
	 * @private
	 */
	this.indexedPlugins_ = {};

	for ( var op in kemia.controller.Plugin.OPCODE) {
		this.indexedPlugins_[op] = [];
	}
	this.config = new goog.structs.Map(
			kemia.controller.ReactionEditor.defaultConfig);
	if (opt_config) {
		this.config.addAll(opt_config); // merge optional config into
		// defaults
	}

	this.graphics = goog.graphics.createGraphics(element.clientWidth,
			element.clientHeight);

	this.graphics.render(this.originalElement);

	this.reactionRenderer = new kemia.view.ReactionRenderer( this.graphics, this.config);
	this.isModified_ = false;
	this.isEverModified_ = false;

	/**
	 * @type {goog.events.EventHandler}
	 * @protected
	 */
	this.eventRegister = new goog.events.EventHandler(this);
	// this.shortcutHandler = new goog.ui.KeyboardShortcutHandler(document);

	// Wrappers around this editor, to be disposed when the editor is disposed.
	this.wrappers_ = [];

	this.handleEditorLoad();

	this.loadState_ = kemia.controller.ReactionEditor.LoadState_.EDITABLE;

	this.isModified_ = false;
	this.isEverModified_ = false;

	// currently selected model objects
	this.selected = [];

	this.neighborList = [];

};
goog.inherits(kemia.controller.ReactionEditor, goog.events.EventTarget);
goog.exportSymbol('kemia.controller.ReactionEditor', kemia.controller.ReactionEditor);

/**
 * Sets the active editor id.
 * 
 * @param {?string}
 *            editorId The active editor id.
 */
kemia.controller.ReactionEditor.setActiveEditorId = function(editorId) {
	kemia.controller.ReactionEditor.activeEditorId_ = editorId;
};

/**
 * @return {goog.dom.DomHelper?} The dom helper for the editable node.
 */
kemia.controller.ReactionEditor.prototype.getEditableDomHelper = function() {
	return this.editableDomHelper;
};

/**
 * @return {?string} The id of the active editor.
 */
kemia.controller.ReactionEditor.getActiveEditorId = function() {
	return kemia.controller.ReactionEditor.activeEditorId_;
};

kemia.controller.ReactionEditor.prototype.clear = function() {
	this.logger.info('clear');
	this.graphics.clear();
	this.models = [];
	//this.neighborList = new kemia.model.NeighborList([], 1, .5);
	var fill = new goog.graphics.SolidFill(this.config.get("background").color);

	this.graphics.drawRect(0, 0, this.graphics.getSize().width, this.graphics
			.getSize().height, null, fill);
}

kemia.controller.ReactionEditor.prototype.getScaleFactor = function() {
	return this.reactionRenderer.scale_factor;
}

kemia.controller.ReactionEditor.prototype.setScaleFactor = function(scale) {
	this.reactionRenderer.transform = undefined; // to force new transform
	this.reactionRenderer.scale_factor = scale;
}

kemia.controller.ReactionEditor.prototype.setModels = function(models) {
	this.clear();
	this.models = models;
	var objects = goog.array.flatten(goog.array.map(models, function(model) {
		if (model instanceof kemia.model.Reaction) {
			if (model.pluses.length == 0) {
				model.generatePlusCoords(model.reactants);
				model.generatePlusCoords(model.products);
			}
			if (model.arrows.length == 0 && model.reactants.length > 0
					&& model.products.length > 0) {
				model.generateArrowCoords(model.reactants, model.products);
			}
			return goog.array.concat(model.reactants, model.products,
					model.pluses, model.arrows);
		} else {
			return [ model ];
		}
	}));

	if (objects.length > 0) {
		this.neighborList = new kemia.model.NeighborList(objects, 1, .5);
	}
	this.render();
};
goog.exportSymbol('kemia.controller.ReactionEditor.prototype.setModels', kemia.controller.ReactionEditor.prototype.setModels);

kemia.controller.ReactionEditor.prototype.render = function() {
	goog.array.forEach(this.models, function(model) {

		if (model instanceof kemia.model.Reaction) {
			this.reactionRenderer.render(model);
		}
		if (model instanceof kemia.model.Molecule) {<commit_msg>reset neighborlist on clear<commit_after>/** 
 * @license Copyright 2010 <NAME> (<EMAIL>)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 * limitations under the License.
 * @author <EMAIL> (<NAME>)
 */
goog.provide("kemia.controller.ReactionEditor");
goog.provide("kemia.controller.ReactionEditor.EventType");
goog.require("kemia.view.ReactionRenderer");
goog.require("kemia.view.MoleculeRenderer");
goog.require("goog.graphics");
goog.require('goog.events');
goog.require('goog.fx.Dragger');
goog.require('goog.fx.Dragger.EventType');
goog.require('goog.editor.BrowserFeature');
goog.require('goog.async.Delay');
goog.require('kemia.controller.Plugin');
goog.require('kemia.model.NeighborList');
goog.require('goog.ui.Prompt');
// goog.require('goog.ui.KeyboardShortcutHandler');

/**
 * A graphical editor for reactions
 * 
 * 
 * @constructor
 * @extends {goog.events.EventTarget}
 */
kemia.controller.ReactionEditor = function(element, opt_config) {
	goog.events.EventTarget.call(this);
	this.originalElement = element;
	this.id = element.id;
	this.editableDomHelper = goog.dom.getDomHelper(element);
	this.models = [];
	/**
	 * Map of class id to registered plugin.
	 * 
	 * @type {Object}
	 * @private
	 */
	this.plugins_ = {};

	/**
	 * Plugins registered on this editor, indexed by the
	 * kemia.controller.Plugin.Op that they support.
	 * 
	 * @type {Object.<Array>}
	 * @private
	 */
	this.indexedPlugins_ = {};

	for ( var op in kemia.controller.Plugin.OPCODE) {
		this.indexedPlugins_[op] = [];
	}
	this.config = new goog.structs.Map(
			kemia.controller.ReactionEditor.defaultConfig);
	if (opt_config) {
		this.config.addAll(opt_config); // merge optional config into
		// defaults
	}

	this.graphics = goog.graphics.createGraphics(element.clientWidth,
			element.clientHeight);

	this.graphics.render(this.originalElement);

	this.reactionRenderer = new kemia.view.ReactionRenderer( this.graphics, this.config);
	this.isModified_ = false;
	this.isEverModified_ = false;

	/**
	 * @type {goog.events.EventHandler}
	 * @protected
	 */
	this.eventRegister = new goog.events.EventHandler(this);
	// this.shortcutHandler = new goog.ui.KeyboardShortcutHandler(document);

	// Wrappers around this editor, to be disposed when the editor is disposed.
	this.wrappers_ = [];

	this.handleEditorLoad();

	this.loadState_ = kemia.controller.ReactionEditor.LoadState_.EDITABLE;

	this.isModified_ = false;
	this.isEverModified_ = false;

	// currently selected model objects
	this.selected = [];

	this.neighborList = [];

};
goog.inherits(kemia.controller.ReactionEditor, goog.events.EventTarget);
goog.exportSymbol('kemia.controller.ReactionEditor', kemia.controller.ReactionEditor);

/**
 * Sets the active editor id.
 * 
 * @param {?string}
 *            editorId The active editor id.
 */
kemia.controller.ReactionEditor.setActiveEditorId = function(editorId) {
	kemia.controller.ReactionEditor.activeEditorId_ = editorId;
};

/**
 * @return {goog.dom.DomHelper?} The dom helper for the editable node.
 */
kemia.controller.ReactionEditor.prototype.getEditableDomHelper = function() {
	return this.editableDomHelper;
};

/**
 * @return {?string} The id of the active editor.
 */
kemia.controller.ReactionEditor.getActiveEditorId = function() {
	return kemia.controller.ReactionEditor.activeEditorId_;
};

kemia.controller.ReactionEditor.prototype.clear = function() {
	this.logger.info('clear');
	this.graphics.clear();
	this.models = [];
	
	// TTD should be able to create empty NeighborList without this dummy Coordinate
	this.neighborList = new kemia.model.NeighborList([new goog.math.Coordinate(1,1)], 1, .5);
	var fill = new goog.graphics.SolidFill(this.config.get("background").color);

	this.graphics.drawRect(0, 0, this.graphics.getSize().width, this.graphics
			.getSize().height, null, fill);
}

kemia.controller.ReactionEditor.prototype.getScaleFactor = function() {
	return this.reactionRenderer.scale_factor;
}

kemia.controller.ReactionEditor.prototype.setScaleFactor = function(scale) {
	this.reactionRenderer.transform = undefined; // to force new transform
	this.reactionRenderer.scale_factor = scale;
}

kemia.controller.ReactionEditor.prototype.setModels = function(models) {
	this.clear();
	this.models = models;
	var objects = goog.array.flatten(goog.array.map(models, function(model) {
		if (model instanceof kemia.model.Reaction) {
//			if (model.pluses.length == 0) {
//				model.generatePlusCoords(model.reactants);
//				model.generatePlusCoords(model.products);
//			}
//			if (model.arrows.length == 0 && model.reactants.length > 0
//					&& model.products.length > 0) {
//				model.generateArrowCoords(model.reactants, model.products);
//			}
			return goog.array.concat(model.reactants, model.products,
					model.pluses, model.arrows);
		} else {
			return [ model ];
		}
	}));

	if (objects.length > 0) {
		this.neighborList = new kemia.model.NeighborList(objects, 1, .5);
	}
	this.render();
};
goog.exportSymbol('kemia.controller.ReactionEditor.prototype.setModels', kemia.controller.ReactionEditor.prototype.setModels);

kemia.controller.ReactionEditor.prototype.render = function() {
	goog.array.forEach(this.models, function(model) {

		if (model instanceof kemia.model.Reaction) {
			this.reactionRenderer.render(model);
		}
		if (model instanceof kemia.model.Molecule) {
{'fraction_non_alphanumeric': 0.13674840736538965, 'fraction_numerical': 0.003490705995287547, 'mean_word_length': 4.475394171046345, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '229947', 'n_tokens_mistral': 3825, 'n_tokens_neox': 3525, 'n_words': 720}