import Ember from 'ember';

import setScrollClassName from 'ghost/utils/set-scroll-classname';

var EditorScroll = Ember.Mixin.create({
    /**
     * Determine if the cursor is at the end of the textarea
     */
    isCursorAtEnd: function () {
        var selection = this.$().getSelection(),
            value = this.getValue(),
            linesAtEnd = 3,
            stringAfterCursor,
            match;

        stringAfterCursor = value.substring(selection.end);
        /* jscs: disable */
        match = stringAfterCursor.match(/\n/g);
        /* jscs: enable */

        if (!match || match.length < linesAtEnd) {
            return true;
        }

        return false;
    },

    /**
     * Build an object that represents the scroll state
     */
    getScrollInfo: function () {
        var scroller = this.get('element'),
            scrollInfo = {
                top: scroller.scrollTop,
                height: scroller.scrollHeight,
                clientHeight: scroller.clientHeight,
                diff: scroller.scrollHeight - scroller.clientHeight,
                padding: 50,
                isCursorAtEnd: this.isCursorAtEnd()
            };

        return scrollInfo;
    },

    /**
     * Calculate if we're within scrollInfo.padding of the end of the document, and scroll the rest of the way
     */
    adjustScrollPosition: function () {
        // If we're receiving change events from the end of the document, i.e the user is typing-at-the-end, update the
        // scroll position to ensure both panels stay in view and in sync
        var scrollInfo = this.getScrollInfo();
        if (scrollInfo.isCursorAtEnd && (scrollInfo.diff >= scrollInfo.top) &&
            (scrollInfo.diff < scrollInfo.top + scrollInfo.padding)) {
            scrollInfo.top += scrollInfo.padding;
            // Scroll the left pane
            this.$().scrollTop(scrollInfo.top);
        }
    },

    /**
     * Send the scrollInfo for scrollEvents to the view so that the preview pane can be synced
     */
    scrollHandler: function () {
        this.set('scrollThrottle', Ember.run.throttle(this, function () {
            this.set('scrollInfo', this.getScrollInfo());
        }, 10));
    },

    /**
     * once the element is in the DOM bind to the events which control scroll behaviour
     */
    attachScrollHandlers: function () {
        var $el = this.$();

        $el.on('keypress', Ember.run.bind(this, this.adjustScrollPosition));

        $el.on('scroll', Ember.run.bind(this, this.scrollHandler));
        $el.on('scroll', Ember.run.bind($el, setScrollClassName, {
            target: Ember.$('.js-entry-markdown'),
            offset: 10
        }));
    }.on('didInsertElement'),

    /**
     * once the element is in the DOM unbind from the events which control scroll behaviour
     */
    detachScrollHandlers: function () {
        this.$().off('keypress');
        this.$().off('scroll');
        Ember.run.cancel(this.get('scrollThrottle'));
    }.on('willDestroyElement')
});

export default EditorScroll;