'use strict';

var React = require('react'),
    Helpers = require('./helpers'),
    IconComponent = require('./icon'),
    Dropzone, DropzoneComponent;

DropzoneComponent = React.createClass({displayName: "DropzoneComponent",
    /**
     * Configuration of Dropzone.js. Defaults are
     * overriden overriden by the 'djsConfig' property
     * For a full list of possible configurations,
     * please consult
     * http://www.dropzonejs.com/#configuration
     */
    getDjsConfig: function () {
        var options,
            defaults = {
                url: this.props.config.postUrl ? this.props.config.postUrl : null
            };

        if (this.props.djsConfig) {
            options = Helpers.extend(true, {}, defaults, this.props.djsConfig);
        } else {
            options = defaults;
        }

        return options;
    },

    /**
     * React 'componentDidMount' method
     * Sets up dropzone.js with the component.
     */
    componentDidMount: function () {
        var self = this,
            options = this.getDjsConfig();

        Dropzone = Dropzone || require('dropzone');
        Dropzone.autoDiscover = false;

        if (!this.props.config.postUrl && !this.props.eventHandlers.drop) {
            console.info('Neither postUrl nor a "drop" eventHandler specified, the React-Dropzone component might misbehave.');
        }

        this.dropzone = new Dropzone(React.findDOMNode(self), options);
        this.setupEvents();
    },

    /**
     * React 'componentWillUnmount'
     * Removes dropzone.js (and all its globals) if the component is being unmounted
     */
    componentWillUnmount: function () {
        if (this.dropzone) {
            var files = this.dropzone.getActiveFiles();

            if (files.length > 0) {
                // Well, seems like we still have stuff uploading.
                // This is dirty, but let's keep trying to get rid
                // of the dropzone until we're done here.
                this.queueDestroy = true;

                var destroyInterval = window.setInterval(function()  {
                    if (this.queueDestroy = false) {
                        return window.clearInterval(destroyInterval);
                    }

                    if (this.dropzone.getActiveFiles().length === 0) {
                        this.dropzone = this.dropzone.destroy();
                        return window.clearInterval(destroyInterval);
                    }
                }.bind(this), 500);
            } else {
                this.dropzone = this.dropzone.destroy();
            }
        }
    },

    /**
     * React 'componentDidUpdate'
     * If the Dropzone hasn't been created, create it
     */
    componentDidUpdate: function () {
        this.queueDestroy = false;

        if (!this.dropzone) {
            this.dropzone = new Dropzone(React.findDOMNode(this), this.getDjsConfig());
        }
    },

    componentWillUpdate: function() {
        this.dropzone.options.params = this.props.djsConfig.params;
    },

    /**
     * React 'render'
     */
    render: function () {
        var icons = [],
            files = this.state.files,
            config = this.props.config,
            className = (this.props.className) ? 'filepicker dropzone ' + this.props.className : 'filepicker dropzone';

        if (config.showFiletypeIcon && config.iconFiletypes && (!files || files.length < 1)) {
            for (var i = 0; i < this.props.config.iconFiletypes.length; i = i + 1) {
                icons.push(React.createElement(IconComponent, {filetype: this.props.config.iconFiletypes[i], key: "icon-component" + i}));
            }
        }

        if (!this.props.config.postUrl && this.props.action) {
            return (
                React.createElement("form", {action: this.props.action, className: className}, 
                    icons, 
                    this.props.children
                )
            );
        } else {
            return (
                React.createElement("div", {className: className}, 
                    icons, 
                    this.props.children
                )
            );
        }
    },

    /**
     * React 'getInitialState' method, setting the initial state
     * @return {object}
     */
    getInitialState: function () {
        return {
            files: []
        }
    },

    /**
     * Takes event handlers in this.props.eventHandlers
     * and binds them to dropzone.js events
     */
    setupEvents: function () {
        var eventHandlers = this.props.eventHandlers;

        if (!this.dropzone || !eventHandlers) {
            return;
        }

        for (var eventHandler in eventHandlers) {
            if (eventHandlers.hasOwnProperty(eventHandler) && eventHandlers[eventHandler]) {
                // Check if there's an array of event handlers
                if (Object.prototype.toString.call(eventHandlers[eventHandler]) === '[object Array]') {
                    for (var i = 0; i < eventHandlers[eventHandler].length; i = i + 1) {
                        // Check if it's an init handler
                        if (eventHandler === 'init') {
                            eventHandlers[eventHandler][i](this.dropzone);
                        } else {
                            this.dropzone.on(eventHandler, eventHandlers[eventHandler][i]);
                        }
                    }
                } else {
                    if (eventHandler === 'init') {
                        eventHandlers[eventHandler](this.dropzone);
                    } else {
                        this.dropzone.on(eventHandler, eventHandlers[eventHandler]);
                    }
                }
            }
        }

        this.dropzone.on('addedfile', function(file)  {
            if (file) {
                var files = this.state.files;

                if (!files) {
                    files = [];
                }

                files.push(file)

                this.setState({files: files});
            }
        }.bind(this));

        this.dropzone.on('removedfile', function(file)  {
            if (file) {
                var files = this.state.files;

                if (files && files.length > 0) {
                    for (var i = 0; i < files.length; i++) {
                        if (files[i].name === file.name && files[i].size === file.size) {
                            files.splice(i, 1);
                        }
                    }

                    this.setState({files: files});
                }
            }
        }.bind(this));
    }
});

module.exports = DropzoneComponent;
