
/* - jquery.ws.tagger.js - */
//Dodanie funkcji 'some' do tablicy, przyjmujacej jako argument funkcje oceniajaca
//zwraca true jesli ktorykolwiek z argumentow spelnia warunek.
if (!Array.prototype.some) {
    Array.prototype.some = function(fun /*, thisp*/) {
        var len = this.length;
        if (typeof fun != "function")
            throw new TypeError();

        var thisp = arguments[1];
        for (var i = 0; i < len; i++) {
            if (i in this && fun.call(thisp, this[i], i, this))
                return true;
        }
        return false;
    };
}

//Dodanei funkcji filter do array.
if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}


(function($){
    $.fn._create_tag = function (tag, id, cls, type, name){
        var t = $( document.createElement(tag) );
        if (id != null) {
            t.attr('id', id);
        }
        if (type != null) {
            t.attr('type', type);
        }
        if (name != null) {
            t.attr('name', name);
        }
        if (cls != null) {
            t.addClass(cls);
        }
        
        return t;
    };
    
    $.fn._prepare_tag = function (name) {
        if (name == null) {
            return null;
        }
        //usuniecie bialych znakow z poczatku i konca
        name = $.trim(name);
        //zamiana na male litery
        name = name.toLowerCase();
        return name;
    }
    
    //tag_id - ustawione jesli tag wystepuje w bazie danych i znane jest jego ID.
    //tag_name - nazwa tagu - jesli dodawany nowy, jego nazwa
    //tag_synonim - nazwa tagu - jesli ustawiony i rozny od tag_name - jest to synonim
	$.fn.add_tag = function(tag_id, tag_name, tag_synonim, tag_type){
        tag_name = $(this)._prepare_tag(tag_name);
        
        //tag musi miec nazwe
        if (tag_name == null || tag_name == '') {
            return false;
        }
        
        if (tag_type == undefined || tag_type == null) {
            tag_type = $(this).data('tag_type');
        }
        
        tag_synonim = $(this)._prepare_tag(tag_synonim);
        
        var main_container = $(this);
        var name = $(this).data('name');
        if (name == null) {
            main_container = $(this).parent();
            name = $(this).parent().data('name');
        }
        //Brak nazwy (a wiec i glownego kontenera - cos nie tak...
        if (name == null) {
            alert('Unknown error');
        }

        var tag_objects = main_container.data('tag_objects');        
        //Przeszukaj liste tagow w poszukiwaniu obecnego...
        var _cmp_fun = function(v) {
            if ((v[0] == tag_name) && (v[1] == tag_type)) {
                return true;
            }
            return false;
        };
        var _ncmp_fun = function(v) {
            if ((v[0] == tag_name) && (v[1] == tag_type)) {
                return false;
            }
            return true;
        };
        
        //jesli jest juz taki tag, to nie dodaj go drugi raz.
        if (tag_objects.some(_cmp_fun)) {
            return false;
        }
        
        //Dodaj do listy obiektow ten obiekt
        tag_objects.push([tag_name, tag_type]);
        main_container.data('tag_objects', tag_objects);
        var container = $('#tag_container_' + name);
        
        var main_span = $(this)._create_tag('span', null, 'tag_main');
        
        var a_tag = $(this)._create_tag('span', null, 'rounded');
        a_tag.attr('href', '#');
        
        var tag_name_txt = tag_name;
        if (tag_type != $(this).data('tag_type')) {
            tag_name_txt = tag_name_txt + ' [' + tag_type + ']';
        }
        
        a_tag.text(tag_name);
        
        var a_remove = $(this)._create_tag('a', null, 'closeRounded');
        a_remove.attr('href', '#');
        a_remove.text('X');
        a_remove.click(function(){
            var parent = $(this).data('tag_container');
            var tag_name = $(this).data('tag_name');
            var tag_objects_tmp = main_container.data('tag_objects');
            tag_objects_tmp = tag_objects_tmp.filter(_ncmp_fun);
            main_container.data('tag_objects', tag_objects_tmp);
			parent.fadeOut(400, function() { $(this).remove(); });
            return false;
			})
        .data('tag_container', main_span).data('tag_name', tag_name);
        
        var tag_input = $(this)._create_tag('input', null, null, 'hidden', name);
        //Skoro zawsze zwracamy nazwe, nie potrzebny jest przedroste name:
        //tag_input.val('name:' + tag_name);
        tag_input.val(tag_type + ':::' + tag_name);
        //tag_input.val(tag_name);
        
        if (tag_synonim != null && tag_synonim != '' && tag_synonim != tag_name) {
            var span_tag_synonim = $(this)._create_tag('span', null, 'tag_synonim');
            span_tag_synonim.text('(' + tag_synonim + ')');
            a_tag.append(span_tag_synonim);
        }
        main_span.append(a_tag).append(a_remove).append(tag_input).append(', ').css('opacity', 0);
        
        container.append(main_span);
        main_span.animate({
            opacity: 1
        }, 400);
	};

	$.fn.add_tags = function(_tags_list){
		for(var idx in _tags_list){
            var tag = _tags_list[idx];
 
            $(this).add_tag(tag[0], tag[1], tag[2], tag[3]);
		}
	};
    
    $.fn.clear_tags = function() {
        //Usuwanie wszystkich tagow
        var main_container = $(this);
        main_container.find("span.tag_main").remove();
        main_container.data('tag_objects', []);
    };
    
    $.fn._input_getter = function(elem, id, name, synonim, type) {
        //jesli ID nie jest ustawione, sprawdz czy aby na pewno nie ma tego tagu w danych zwrocnych z autocomplete.
        if (id == null) {
            var data = elem.data('autocomplete_tags');
            for(var idx in data) {
                if (data[idx].synonim == name) {
                    name = data[idx].tag_name;
                    synonim = data[idx].tag_synonim;
                    id = data[idx].tag_id;
                    type = data[idx].type;
                    break;
                }
            }
        }
        elem.add_tag( id, name, synonim, type );
        elem.val('');
        elem.stop();
    }
	
    $.fn.create_container = function(ac_file, name, extraParams) {
        if (name == null) {
            name = $(this).attr('name');
        }
        $(this).removeAttr('name');
        
        $(this).data('name', name);	
        $(this).data('ac_file', ac_file);	
        $(this).data('tag_objects', []);	
        
        if (extraParams == null || extraParams == undefined) {
            extraParams = {};
        }
        
        var tag_type = extraParams['tag_type'] ? extraParams['tag_type'] : "";
        $(this).data('tag_type', tag_type);	
        var search_tags = extraParams['search_tags'] ? extraParams['search_tags'] : $(this).data('tag_type');
        $(this).data('search_tags', search_tags);	
        var strict = extraParams['strict'] ? Boolean(extraParams['strict']) : false;
        $(this).data('strict', strict);	
        var base_tags = extraParams['base_tags'] ? Boolean(extraParams['base_tags']) : false;
        $(this).data('base_tags', base_tags);	
        
        var input_field = $(this).find('input.tag_input');
        input_field.attr('name', $(this).data('name') + '_input');
        if ($(this).data('strict') == false) {
            input_field.bind('keypress', function(e){
                if( 13 == e.keyCode){
                    $(this)._input_getter($(this), null, $(this).val(), null, $(this).parent().data('tag_type'));
                    return false;
                }
            });
        }
        

        
        var container = $(this).find('div.tag_container');
        
        $(this).append(container);
        
        input_field.autocomplete({
            minLength: 1,
            source: function( request, response ) {
                $.ajax({
                    url: this.element.parent().data('ac_file'),
                    dataType: "json",
                    data: {
                        q: request.term,
                        tag_type: this.element.parent().data('search_tags'),
                        base_tags: this.element.parent().data('base_tags')
                    },
                    success: function( data ) {
                        //cache[term] = data;
                        response( $.map( data.tags, function( item ) {
                            var txt_label = item.name + ((item.synonim != null && item.synonim != item.name) ? " (" + item.synonim + ")" : "");
                            txt_label = txt_label + ' [' + item.type + ']';
                            return {
                                name: item.name,
                                type: item.type,
                                id: item.id,
                                label: txt_label,
                                value: item.synonim
                            }
                        }));
                    }
                });
            }, 
            select: function(e, ui) {
                $(this)._input_getter($(this), ui.item.id, ui.item.name, ui.item.value, ui.item.type);
                this.close;
                return false;
            }
        });
        
        $(this).append(input_field);
        
        var b = $(this).find('input.tag_add');
        if ($(this).data('strict') == false) {
            b.click( function() {
                var input_f = $(this).data('input_f');
                $(input_f)._input_getter(input_f, null, $(input_f).val(), null, $(this).parent().data('tag_type'));
            }).data('input_f', input_field);
            $(this).append(b);
        }
        else {
            if (b.length) {
                b.remove();
            }
        }
        
    };
})(jQuery);

