import PropTypes from 'prop-types';
import React from 'react';
import {connect} from 'react-redux';

import FixedToolsComponent from '../components/fixed-tools/fixed-tools.jsx';

import {changeMode} from '../reducers/modes';
import {changeFormat} from '../reducers/format';
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import {deactivateEyeDropper} from '../reducers/eye-dropper';
import {setTextEditTarget} from '../reducers/text-edit-target';
import {setLayout} from '../reducers/layout';

import {getSelectedLeafItems} from '../helper/selection';
import {bringToFront, sendBackward, sendToBack, bringForward} from '../helper/order';
import {groupSelection, ungroupSelection} from '../helper/group';

import Formats from '../lib/format';
import {isBitmap} from '../lib/format';
import bindAll from 'lodash.bindall';
import {syncMenuEvent, syncUpdateNameEvent} from '../helper/sync-event';
// import log from '../log/log';

class FixedTools extends React.Component {
    constructor (props) {
        super(props);
        bindAll(this, [
            'handleSendBackward',
            'handleSendForward',
            'handleSendToBack',
            'handleSendToFront',
            'handleSetSelectedItems',
            'handleGroup',
            'handleUngroup',
            'handleUndo',
            'handleRedo',
            'handleUpdateName'
        ]);
    }
    componentWillReceiveProps (nextProps) {
        if (nextProps.selectedMenu !== this.props.selectedMenu) {
            if (nextProps.selectedMenu === 'group') {
                this.handleGroup();
            } else if (nextProps.selectedMenu === 'ungroup') {
                this.handleUngroup();
            } else if (nextProps.selectedMenu === 'send-backward') {
                this.handleSendBackward();
            } else if (nextProps.selectedMenu === 'send-forward') {
                this.handleSendForward();
            } else if (nextProps.selectedMenu === 'send-to-back') {
                this.handleSendToBack();
            } else if (nextProps.selectedMenu === 'send-to-front') {
                this.handleSendToFront();
            } else if (nextProps.selectedMenu === 'undo') {
                this.handleUndo();
            } else if (nextProps.selectedMenu === 'redo') {
                this.handleRedo();
            }
            // else {
            //     log.error('unhandled menu : ', nextProps.selectedMenu);
            // }
        }
        if (nextProps.paintName !== this.props.paintName) {
            this.handleUpdateName(nextProps.paintName);
        }
    }
    handleGroup () {
        syncMenuEvent('group');
        groupSelection(this.props.clearSelectedItems, this.handleSetSelectedItems, this.props.onUpdateImage);
    }
    handleUngroup () {
        syncMenuEvent('ungroup');
        ungroupSelection(this.props.clearSelectedItems, this.handleSetSelectedItems, this.props.onUpdateImage);
    }
    handleSendBackward () {
        syncMenuEvent('send-backward');
        sendBackward(this.props.onUpdateImage);
    }
    handleSendForward () {
        syncMenuEvent('send-forward');
        bringForward(this.props.onUpdateImage);
    }
    handleSendToBack () {
        syncMenuEvent('send-to-back');
        sendToBack(this.props.onUpdateImage);
    }
    handleSendToFront () {
        syncMenuEvent('send-to-front');
        bringToFront(this.props.onUpdateImage);
    }
    handleSetSelectedItems () {
        this.props.setSelectedItems(this.props.format);
    }
    handleUndo () {
        syncMenuEvent('undo');
        this.props.onUndo();
    }
    handleRedo () {
        syncMenuEvent('redo');
        this.props.onRedo();
    }
    handleUpdateName (name) {
        syncUpdateNameEvent(name);
        this.props.onUpdateName(name);
    }
    render () {
        return (
            <FixedToolsComponent
                canRedo={this.props.canRedo}
                canUndo={this.props.canUndo}
                name={this.props.name}
                onGroup={this.handleGroup}
                onRedo={this.handleRedo}
                onSendBackward={this.handleSendBackward}
                onSendForward={this.handleSendForward}
                onSendToBack={this.handleSendToBack}
                onSendToFront={this.handleSendToFront}
                onUndo={this.handleUndo}
                onUngroup={this.handleUngroup}
                onUpdateImage={this.props.onUpdateImage}
                onUpdateName={this.handleUpdateName}
            />
        );
    }
}

FixedTools.propTypes = {
    canRedo: PropTypes.func.isRequired,
    canUndo: PropTypes.func.isRequired,
    clearSelectedItems: PropTypes.func.isRequired,
    format: PropTypes.oneOf(Object.keys(Formats)),
    name: PropTypes.string,
    onRedo: PropTypes.func.isRequired,
    onUndo: PropTypes.func.isRequired,
    onUpdateImage: PropTypes.func.isRequired,
    onUpdateName: PropTypes.func.isRequired,
    setSelectedItems: PropTypes.func.isRequired,
    selectedMenu: PropTypes.string,
    paintName: PropTypes.string
};

const mapStateToProps = state => ({
    changeColorToEyeDropper: state.scratchPaint.color.eyeDropper.callback,
    format: state.scratchPaint.format,
    isEyeDropping: state.scratchPaint.color.eyeDropper.active,
    mode: state.scratchPaint.mode,
    pasteOffset: state.scratchPaint.clipboard.pasteOffset,
    previousTool: state.scratchPaint.color.eyeDropper.previousTool,
    selectedItems: state.scratchPaint.selectedItems,
    viewBounds: state.scratchPaint.viewBounds,
    selectedMenu: state.scratchPaint.modeTools.menu,
    paintName: state.scratchPaint.modeTools.name
});
const mapDispatchToProps = dispatch => ({
    changeMode: mode => {
        dispatch(changeMode(mode));
    },
    clearSelectedItems: () => {
        dispatch(clearSelectedItems());
    },
    handleSwitchToBitmap: () => {
        dispatch(changeFormat(Formats.BITMAP));
    },
    handleSwitchToVector: () => {
        dispatch(changeFormat(Formats.VECTOR));
    },
    removeTextEditTarget: () => {
        dispatch(setTextEditTarget());
    },
    setLayout: layout => {
        dispatch(setLayout(layout));
    },
    setSelectedItems: format => {
        dispatch(setSelectedItems(getSelectedLeafItems(), isBitmap(format)));
    },
    onDeactivateEyeDropper: () => {
        // set redux values to default for eye dropper reducer
        dispatch(deactivateEyeDropper());
    }
});

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(FixedTools);
