<div class="toolbar">
    <div class="toolbar-container web {% if mode == "print" %}hide{% endif %}">
        <input id="resize-w" class="input-resize input-large" type="text" value="320" />
        ×
        <input id="resize-h" class="input-resize input-large" type="text" value="500" />

        <div class="button mobile-s size-preset" data-width="320">
            <i class="fa fa-mobile"></i>
        </div>
        <div class="button mobile-l size-preset" data-width="400">
            <i style="font-size:17px" class="fa fa-mobile"></i>
        </div>
        <div class="button desktop size-preset" data-width="600">
            <i class="fa fa-desktop"></i>
        </div>
    </div>
</div>

<script type="text/javascript">
    var resizer = function() {

        var old_height, old_width;

        var measureChartHeight = _.debounce(function() {
            var iframe = $('#iframe-vis').get(0).contentWindow;
            if (iframe) {
                var chartBody = iframe.document.querySelector('.dw-chart-body');
                if (chartBody && chartBody.getBoundingClientRect) {
                    var h = chartBody.getBoundingClientRect().height;
                    if (h != chart.get('metadata.publish.chart-height')) {
                        chart.set('metadata.publish.chart-height', h);
                        chart.save();
                    }
                    // console.log('measured chart height to', h, 'pixel');
                } else {
                    // try again later
                    setTimeout(measureChartHeight, 2000);
                }
            }
        }, 800);

        this.resizeIframe = function () {
            var maxW = $('#iframe-wrapper').parent().parent().width() - 22,
                w = chart.get('metadata.publish.embed-width'),
                h = chart.get('metadata.publish.embed-height'),
                m = String(w).match(/^(\d+(?:\.\d+)?)%$/),
                realW = m ? (+m[1] / 100) * maxW : w,
                resizer = this;

            $('#resize-w').val(w);
            $('#resize-h').val(h);
            $('#resize-mm-w').val(w / 4);
            $('#resize-mm-h').val(h / 4);

            $('#iframe-wrapper').animate({
                width: w,
                height: h,
                'margin-left': (maxW - realW) * 0.5,
            }, {
                duration: 200,
                step: function () {
                    $(this).css('overflow', 'visible');
                }
            });

            $('.visconfig').css('min-height', (+h) + 250);

            dw.backend.fire('chart-resize');
            measureChartHeight();
        };

        this.updateSize = function (w, h) {
            var maxW = $('#iframe-wrapper').parent().parent().width() - 22,
                chart = dw.backend.currentChart,
                resizer = this;

            if (Number(w) > maxW) {
                w = maxW;
            }

            var m = String(w).match(/^(\d+(?:\.\d+)?)%$/),
                realW = m ? (+m[1] / 100) * maxW : w;

            if (w != old_width || h != old_height) {
                old_width = w;
                old_height = h;

                chart.set('metadata.publish.embed-width', w);
                chart.set('metadata.publish.embed-height', h);

                this.resizeIframe();
            }
        };

        this.initWebMode = function () {
            var resizer = this;

            // 1. Resize when textbox changes
            $('#resize-w, #resize-h').change((function () {
                resizer.updateSize($('#resize-w').val(), $('#resize-h').val());
            }).bind(this));

            // 2. Resize when drag&drop event fires
            var iframe = $('#iframe-wrapper').addClass('resizable');
            iframe.find('.resizer').remove();
            iframe.append('<div class="resizer resizer-both icon-resize-horizontal"></div>');

            $('.resizer', iframe).on('mousedown', dragStart);
            var startX, startY, startWidth, startHeight;

            function dragStart(e) {
                startX = e.clientX;
                startY = e.clientY;
                startWidth = iframe.width();
                startHeight = iframe.height();
                $(document).on('mousemove', doDrag);
                $(document).on('mouseup', stopDrag);
                $('#iframe-vis').addClass('resizing');
            }

            function doDrag(e) {
                iframe.height(startHeight + e.clientY - startY);
                iframe.width(startWidth + e.clientX - startX);
                iframe.css('pointer-events', 'none');
                e.preventDefault();
                return false;
            }

            function stopDrag(e) {
                $(document).unbind('mousemove', doDrag);
                $(document).unbind('mouseup', stopDrag);
                // now, update size;
                resizer.updateSize($('#iframe-vis').width(), $('#iframe-vis').height());
                iframe.css('pointer-events', 'initial');
                $('#iframe-vis').removeClass('resizing');
            }

            // 3. Resize when a preset is clicked
            $('.size-preset').click(function () {
                resizer.updateSize($(this).attr('data-width'), $('#resize-h').val());
            });

            // 4. Resize when type has changed
            dw.backend.on('type-changed', function (metas) {
                var newMeta = metas[0], oldMeta = metas[1];

                if (oldMeta.height == "fixed" && (newMeta.height || "fit") == "fit" && $('#resize-h').val() > 500) {
                    resizer.updateSize($('#resize-w').val(), 500);
                }
            });

            // 5. Resize when chart wants to resize itself
            window.addEventListener('message', function (e) {
                var message = e.data;

                if (typeof message['datawrapper-height'] != "undefined") {
                    var h;

                    for (var chartId in message['datawrapper-height']) {
                        h = message['datawrapper-height'][chartId];
                    }

                    if (!$('.preset.manual').hasClass('selected') && !$('#iframe-vis').hasClass('resizing')) {
                        resizer.updateSize($('#resize-w').val(), h);
                    }
                }
            });

            // 6. keep buttons in sync
            dw.backend.on('chart-resize', function () {
                var w = dw.backend.currentChart.get('metadata.publish.embed-width');

                $('.toolbar-container.web .size-preset').removeClass('active');

                if (w <= $('.toolbar-container.web .size-preset.mobile-s').attr('data-width')) {
                    $('.toolbar-container.web .size-preset.mobile-s').addClass('active');
                } else if (w <= $('.toolbar-container.web .size-preset.mobile-l').attr('data-width')) {
                    $('.toolbar-container.web .size-preset.mobile-l').addClass('active');
                } else if (w <= $('.toolbar-container.web .size-preset.desktop').attr('data-width')) {
                    $('.toolbar-container.web .size-preset.desktop').addClass('active');
                }
            });
        };

        this.init = function () {
            this.initWebMode();
            this.resizeIframe();
        };
    };

    var r = new resizer();
    r.init();
</script>