define(['knockout', 'select2', 'services/datacontext', 'services/logger'], function(ko, select2, dataservice, logger){
    ko.bindingHandlers.select2 = {
        init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
            ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
                $(el).select2('destroy');
            });

            var options  = valueAccessor();  options.item = allBindingsAccessor().item;
            var selected  = options.item.selectedTags;

            // init selection
            options.initSelection = options.initSelection || function (element, callback) {
                callback(selected());
            };

            // Tag remove
            options.onAddTag = options.onAddTag || function (tag) {
                var tagObject = ko.observable();
                tagObject.subscribe(function(value){
                    var data = {tag: value};
                    data[options.item.type] = options.item;
                    options.item.addTag(dataservice.createTagMap(data, options.item.tagMap));
                });

                if(parseInt(tag.id) > 0){
                    dataservice.getTagById(tag.id, tagObject);
                }else{
                    tagObject(dataservice.createTag({name: tag.text}));
                }
            };

            // Tag add
            options.onRemoveTag = options.onRemoveTag || function (tag) {
                options.item.removeTag(tag);
            };

            // Init select2
            $(el).select2(ko.utils.unwrapObservable(options));

            // Subscribe change event
            $(el).on("change", function (e) {
                //console.log("change " + JSON.stringify({val: e.val, added: e.added, removed: e.removed}));
                if(e.added){
                    options.onAddTag(e.added);
                }
                if(e.removed){
                    options.onRemoveTag(e.removed);
                }
            });

        },
        update: function (el, valueAccessor, allBindingsAccessor, viewModel) {
            var options  = valueAccessor();  options.item = allBindingsAccessor().item;

            $(el).select2('val', options.item.selectedTagValues());
        }

    };
});

