; (function (trv, $, window, document, undefined) {
    "use strict";
    
    var utils = trv.utils;
    if (!utils) {
        throw 'Missing telerikReporting.utils';
    }

    function linkButton(dom, options) {
        var cmd, $element = $(dom), dataCommand = $element.attr('data-command');
        if (dataCommand) {
            cmd = options.model[dataCommand];
        }

        if (cmd) {
            $element
            .click(function (e) {
                if (cmd.enabled()) {
                    cmd.exec($(this).attr('data-command-parameter'));
                }
                else {
                    e.preventDefault();
                }
            });

            $(cmd)
                .bind("enabledChanged", function(e) {
                    (cmd.enabled() ? $.fn.removeClass : $.fn.addClass).call($element, "disabled");
                })
                .bind("checkedChanged", function (e) {
                    (cmd.checked() ? $.fn.addClass : $.fn.removeClass).call($element, "checked");
                })
            ;
        }
    }
    
    function textInput(dom, options) {
        var $element = $(dom), $viewModel = $(options.model), role = $element.attr('data-role'), lock;
        $viewModel.bind(role, function (e, value) {
            if (!lock) {
                $element.val(value);
            }
        });

        $element.change(function () {
            var val = $(this).val();
            var num = utils.tryParseInt(val);
            if (num != NaN) {
                try {
                    lock = true;
                    $viewModel.trigger(role, num);
                } finally {
                    lock = false;
                }
            }
        });

        $element.keydown(function (e) {
            if (e.which == 13) {
                $(this).change();
                e.preventDefault();
            }
        });
    }

    function textLabel(dom, options) {
        var $element = $(dom), $viewModel = $(options.model), role = $element.attr('data-role');
        $viewModel.bind(role, function (e, value) {
            $element.html(value);
        });
    }

    var buttonBinders = [
        { selector: 'a', bind: linkButton },
        //{ selector: 'input[type=button]', bind: button },
        //{ selector: 'button', bind: button },
    ];

    var textBinders = [
        { selector: 'input:not([type=submit]):not([type=file])', bind: textInput },
        { selector: '*', bind: textLabel },
    ];

    var roles = {
        'trv-pages-area': [
            {
                selector: '*',
                bind: function (dom, options) {
                    $(dom).telerik_ReportViewer_PagesArea(options);
                }
            }
        ],
        
        'trv-document-map': [
            {
                selector: '*',
                bind: function (dom, options) {
                    $(dom).telerik_ReportViewer_DocumentMapArea(options);
                }
            }
        ],

        'trv-parameters-area': [
            {
                selector: '*',
                bind: function (dom, options) {
                    $(dom).telerik_ReportViewer_ParametersArea(options);
                }
            }
        ],
        
        'button': buttonBinders,

        'pageNumber': textBinders,

        'pageCount': textBinders,

        'menu': [
            {
                selector: 'ul',
                bind: function (dom, options) {
                    $(dom).telerik_ReportViewer_MainMenu(options);
                }
            }
        ],
        
        'side-menu': [
            {
                selector: '*',
                bind: function (dom, options) {
                    $(dom).telerik_ReportViewer_SideMenu(options);
                }
            }
        ],
        
        'content-wrapper': [
            {
                selector: '*',
                bind: function (dom, options) {
                    contentWrapper(dom, options);
                }
            }
        ],

        'zoom': [],
    };
    
    function contentWrapper(dom, options) {
        $(options.controller).bind('toggleSideMenu', function () {
            $(dom).toggleClass("right");
        });
    }

    function bindElement(binders, dom, options) {
        var b = selectBinder(dom, binders);
        if (b) {
            b(dom, options);
        }
    }

    function selectBinder(dom, binders) {
        var $element = $(dom);
        for (var i = 0, len = binders.length; i < len; i++) {
            var b = binders[i];
            if (!b.selector || $element.is(b.selector)) {
                return b.bind;
            }
        }
        return null;
    }
    
    function bindCore(element, filter, options) {
        $(element).find(filter).each(function () {
            var binders = roles[$(this).attr('data-role')];
            if (binders) {
                bindElement(binders, this, options);
            }
        });
    }

    var binder = {
        bind: function (element, options) {
            bindCore(element, '*[data-role=export-format-list]', options);
            bindCore(element, '*[data-role]', options);
        }
    };

    trv.binder = binder;

}(window.telerikReportViewer = window.telerikReportViewer || {}, jQuery, window, document));