
import { Command } from '@ckeditor/ckeditor5-core';
import { isImage } from '@ckeditor/ckeditor5-image/src/image/utils';
import { IMAGEMAP_ATTRIBUTES, IMAGEMAP_ELEMENTS, findMapNodes, drawMap, createInsertedEvent, createRemovedEvent } from './utils';
import { trimStart } from '../common/qmsCKEditorUtil';

export default class ImageMapCommand extends Command {
	// refresh() {
	// 	const element = this.editor.model.document.selection.getSelectedElement();
	// 	this.isEnabled = isImage(element);
	// }

	execute(options) {
		const editor = this.editor;
		const model = editor.model;
		model.change(writer => {
			var newName =  trimStart(options.name, '#');
			const areas = options.areas;
			const width = options.imageWidth;
			const height = options.imageHeight;
			const imageElement = model.document.selection.getSelectedElement();
			if(!imageElement | !isImage(imageElement)){
				return;
			}
			const oldName = imageElement.getAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_USE_MAP) || options.oldName;

			if(!!oldName){
				const range = model.createRangeIn(model.document.getRoot());
				const existingMapElements = findMapNodes([trimStart(oldName, '#')], range);
				if(existingMapElements && existingMapElements.length > 0){
					existingMapElements.forEach(element => {
						writer.remove(element);
					});
				}
			}

			if(!!areas && areas.length > 0)
			{
				writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_USE_MAP, '#' + newName, imageElement);
				writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_WIDTH, width, imageElement);
				writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_HEIGHT, height, imageElement);

				let originalImageSrc = imageElement.getAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SRC);
				if(!imageElement.hasAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SAVED_SRC) || !imageElement.getAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SAVED_SRC)){
					writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SAVED_SRC, originalImageSrc, imageElement);
				}
				else{
					originalImageSrc = imageElement.getAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SAVED_SRC);
				}

				let attrs = {};
				attrs[IMAGEMAP_ATTRIBUTES.MAP_NAME] = newName;
				attrs[IMAGEMAP_ATTRIBUTES.MAP_AREAS] = JSON.stringify(areas);
				attrs[IMAGEMAP_ATTRIBUTES.MAP_WIDTH] = width;
				attrs[IMAGEMAP_ATTRIBUTES.MAP_HEIGHT] = height;
				const mapElement = writer.createElement(IMAGEMAP_ELEMENTS.MAP, attrs);

				writer.insert(mapElement, writer.createPositionAt(imageElement, "after"));

				drawMap(originalImageSrc, width, height, areas, (oldsrc, newsrc) =>{
					model.enqueueChange(writer.batch, writer => {
						writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SRC, newsrc, imageElement);
						this.fire(createInsertedEvent(newName));
					});
				});
			}
			else {
				if(imageElement.hasAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_USE_MAP)){
					writer.removeAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_USE_MAP, imageElement);
				}

				if(imageElement.hasAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SAVED_SRC)){

					let src = imageElement.getAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SAVED_SRC);
					if(!!src){
						writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SRC, src, imageElement);
					}
					writer.removeAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SAVED_SRC, imageElement);
				}

				if(imageElement.hasAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_HEIGHT)){
					writer.removeAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_HEIGHT, imageElement);
				}

				if(imageElement.hasAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_WIDTH)){
					writer.removeAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_WIDTH, imageElement);
				}
				this.fire(createRemovedEvent(newName));
			}
		},{ once: true });
	}
}

