define(['scripts/knockout-3.3.0', 'scripts/ACTComponent.js'], function(ko, ACTComponent) {

    function StreamDescriptor(imgSrc, imgHeight, command, type) {
        this.icon = {
            src: imgSrc,
            height: imgHeight
        };
        this.command = command;
        this.type = type;
        switch (type) {
            case "input":
                this.classType = "stream-input";
                break;
            case "output":
                this.classType = "stream-output";
                break;
            case "error":
                this.classType = "stream-error";
                break;
        }
    }

    function IOStreamComponentViewModel(params, element) {
        //********************************************************************************
        //---------------------------------INIT-------------------------------------------
        //******************************************************************************** 
        var _this = this;
        _this.base = new ACTComponent($(element), params);
        _this.ioStreamItems = ko.observableArray([]);
        _this.ShowPopupMenu = params.Model.ShowPopupMenu;
        _this.ioStreamContainer = $(element).find('#ioStream-container');
        _this.hasMenu = ko.observable(params.Model.DisplayPopupMenu);


        _this.base.onRefresh = function(obj) {

            _this.hideInputs = obj.HideInputs;
            _this.hideOutputs = obj.HideOutputs;
            _this.hideErrors = obj.HideErrors;

            _this.streams = obj.Streams;
            if(_this.streams){
            _this.streams.forEach(function(stream){
                if (stream.Input) {
                    _this.ioStreamItems.push(new StreamDescriptor("images/Input.png", "10", _this.convertToHtmlTag(stream.Input), "input"));
                }
                if (stream.Output) {
                    _this.ioStreamItems.push(new StreamDescriptor("images/Output.png", "10", _this.convertToHtmlTag(stream.Output), "output"));
                }
                if (stream.Error) {
                    _this.ioStreamItems.push(new StreamDescriptor("images/error2.png", "10", _this.convertToHtmlTag(stream.Error), "error"));
                }
            });
            }

            if (obj.ClearContent) {
                _this.clear();
            }
            _this.filter();
        }.bind(_this);

        _this.base.addCallbackX(_this, "showPopupMenu", "ShowPopupMenu");

        //********************************************************************************
        //---------------------------------IOSTREAM----------------------------------------
        //******************************************************************************** 
        _this.filter = function() {
            if (_this.hideInputs) {
                $('.stream-input').hide();
            } else {
                $('.stream-input').show();
            }
            if (_this.hideOutputs) {
                $('.stream-output').hide();
            } else {
                $('.stream-output').show();
            }
            if (_this.hideErrors) {
                $('.stream-error').hide();
            } else {
                $('.stream-error').show();
            }
            _this.ioStreamContainer.scrollTop(_this.ioStreamContainer[0].scrollHeight);
        };

        _this.clear = function() {
            setTimeout(function() {
                _this.ioStreamItems.removeAll();
            }, 0);
        };

        //event bound from ko
        _this.onClickMenu = function(data, event) {
            var command = data.command;
            command = command.replace(/\<br\>/g, "\r\n"); //remove html tags.
            command = command.replace(/\&nbsp;/g, " "); //remove html tags.
            var positionX = parseInt(event.clientX);
            var positionY = parseInt(event.clientY);
            _this.showPopupMenu(positionX, positionY, command, data.type);
        };

        _this.convertToHtmlTag = function(input) {
            var convertedInput = input.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;"); //change tabs to non-breakable space
            convertedInput = convertedInput.split(' ').join("&nbsp;");
            convertedInput = convertedInput.replace(/(\r\n)|[\r\n]/g, "<br>");
            return convertedInput;
        };

        params.baseModel.resizeFunctions[params.baseModel.resizeFunctions.length] = function(height, width) {
            // Scroll to the bottom.
            _this.ioStreamContainer.scrollTop(_this.ioStreamContainer[0].scrollHeight);
        };
        _this.base.initialize();
        params.ready(true);
    }

    return {
        createViewModel: function(params, componentInfo) {
            return new IOStreamComponentViewModel(params, componentInfo.element);
        }
    };
});
