
import { Command } from '@ckeditor/ckeditor5-core';
import { isImage } from '@ckeditor/ckeditor5-image/src/image/utils';
import { IMAGEMAP_ATTRIBUTES, parsePixelToFloat, findFirstMapNode, drawMap, resizeAreaWidth, resizeAreaHeight, createResizedEvent } from './utils';
import  { getSelectedImageWidget} from '@ckeditor/ckeditor5-image/src/image/utils';
import { trimStart } from '../common/qmsCKEditorUtil';

export default class ResizeImageMapCommand extends Command {

	refresh() {
		const element = this.editor.model.document.selection.getSelectedElement();
		this.isEnabled = isImage(element) && element.hasAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_USE_MAP);
	}

	execute( options = {}) {
        const editor = this.editor;
        const model = editor.model;
        const view = this.editor.editing.view;
        const imageElement = model.document.selection.getSelectedElement();
        const mapName = imageElement.getAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_USE_MAP);
        if(mapName){
            const imageWidget = getSelectedImageWidget( view.document.selection);
            const widgetResizePlugin = editor.plugins.get('WidgetResize');
            const resizer = widgetResizePlugin.getResizerByViewElement( imageWidget );
            if(resizer){
                const resizerWrapper = resizer._viewResizerWrapper;
                const newWidth = parsePixelToFloat(resizerWrapper.getStyle('width', 0));
                const newHeight = parsePixelToFloat(resizerWrapper.getStyle('height', 0));

                const range = model.createRangeIn(model.document.getRoot());
                const existingMapElement = findFirstMapNode(trimStart(mapName, '#'), range);
                if(existingMapElement){
                    const areas = JSON.parse(existingMapElement.getAttribute(IMAGEMAP_ATTRIBUTES.MAP_AREAS) || []);
                    const width = parsePixelToFloat(existingMapElement.getAttribute(IMAGEMAP_ATTRIBUTES.MAP_WIDTH, 0));
                    const height = parsePixelToFloat(existingMapElement.getAttribute(IMAGEMAP_ATTRIBUTES.MAP_HEIGHT, 0));

                    const widthChanged = newWidth != width && width != 0 ;
                    const heightChanged = newHeight != height && height != 0 ;

                    if(widthChanged || heightChanged){
                        if(widthChanged){
                            const widthRatio = (newWidth * 1.0) / width;
                            for (var i = 0; i < areas.length; ++i) {
                                areas[i] = resizeAreaWidth(areas[i], widthRatio);
                            }
                        }

                        if(heightChanged){
                            const heightRatio = (newHeight * 1.0) / height;
                            for (var i = 0; i < areas.length; ++i) {
                                areas[i] = resizeAreaHeight(areas[i], heightRatio, widthChanged);
                            }
                        }

                        const areasAsString  = JSON.stringify(areas);
                        model.change(writer => {
                            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);
                            }

                            writer.setAttribute(IMAGEMAP_ATTRIBUTES.MAP_AREAS, areasAsString, existingMapElement);
                            writer.setAttribute(IMAGEMAP_ATTRIBUTES.MAP_WIDTH, newWidth, existingMapElement);
                            writer.setAttribute(IMAGEMAP_ATTRIBUTES.MAP_HEIGHT, newHeight, existingMapElement);
                            writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_WIDTH, newWidth, imageElement);
                            writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_HEIGHT, newHeight, imageElement);

                            drawMap(originalImageSrc, newWidth, newHeight, areas, (oldsrc, newsrc) =>{
                                model.enqueueChange(writer.batch, writer => {
                                    writer.setAttribute(IMAGEMAP_ATTRIBUTES.IMAGE_SRC, newsrc, imageElement);
                                    this.fire(createResizedEvent(mapName));
                                });
                            });
                        });
                    }
                }
            }
        }
	}
}
