/**
 * @author: bluehipy@yahoo.com
 **/

(function($) {

        window.ImageTagger = function (){};
        var o =
        {
            constructor:ImageTagger,
            parent:undefined,
            container:undefined,
            pic_container:undefined,
            tags_container:undefined,
            anchors_container:undefined,
            pad:undefined,
            img:undefined,
            ready:false,
            data:[],
            tags:[],
            anchors:[],
            captions:[],
            editable:false,
            init:function(img, data)
            {
                this.img = img;this.data = data;var w = img.width();var h = img.height();
                if (w == 0 && h == 0){var self = this;img.bind('load', function(){self.registerImage();});}else{this.registerImage();}
            },
            setEditable:function(onoff){this.editable = ( onoff == true );if (this.ready){this.reset();}},
            remove:function(){this.parent.replaceWith(this.img);},
            reset:function(){this.remove();this.init(this.img, this.data);},
            addTag:function(rect, caption,linkdata){this.data.push([rect,caption,linkdata]);this.draw();return this.data.length - 1;},
            removeTag:function(index){this.data.splice(index, 1);this.draw();},
            drawTag:function(rect, caption,linkdata)
            {
                var css = {position:'absolute',top:rect[1] + 'px',left:rect[0] + 'px',width:rect[2] + 'px',height:rect[3] + 'px'}

                //var picTag = $('<div>').addClass('img_tg_tag').css(css).appendTo(this.tags_container).hide();
                var picTag = $('<div>').addClass('img_tg_tag').css(css).appendTo(this.tags_container).hide();

                //var picCaption = $('<span>').addClass('img_tg_caption').html(caption).css('position', 'absolute').css('top', rect[1] + rect[3] + 'px').appendTo(this.tags_container);
                var picCaption = $('<a href="'+linkdata+'"/>').addClass('img_tg_caption').html(caption).css('position', 'absolute').css('top', rect[1] + rect[3] + 'px').appendTo(this.tags_container).click(function(){return true;}).bind('mouseover', function(){picTag.show();}).bind('mouseout', function(){picTag.hide();});
                var x = rect[0] + Math.floor(( rect[2] - picCaption.width() ) / 2);
                //picCaption.css('left', x + 'px').hide();
                picCaption.css('left', x + 'px');

                var anchor = $('<a href="'+linkdata+'"/>').html(caption).appendTo(this.anchors_container).click(function(){return true;}).bind('mouseover', function(){picTag.show();}).bind('mouseout', function(){picTag.hide();});
                this.tags.push(picTag);
                this.captions.push(picCaption);
                this.anchors.push(anchor);
                //remove link
                if (this.editable){var self = this;var index = this.tags.length - 1;var del = $('<a href="#"/>').html('(delete)').appendTo(this.anchors_container).click(function(){self.removeTag(index);return false;})}
            },
            registerImage:function()
            {
                var img = this.img;var self = this;var w = img.width();var h = img.height();
                this.parent = $('<div>').css('position', 'absolute');
                this.container = $('<span>');
                this.pic_container = $('<span>');
                this.tags_container = $('<span>');
                this.anchors_container = $('<span>');
                this.pad = $('<span>');
                img.replaceWith(this.parent).appendTo(this.pic_container);
                this.container.appendTo(this.parent);
                this.pic_container.appendTo(this.container);
                this.tags_container.appendTo(this.container);
                this.anchors_container.appendTo(this.container);
                //this.pad.appendTo(this.container);
                var props = {position:'absolute',display:'block',top:'0px',left:'0px',width:w + 'px',height:h + 'px'};
                this.container.css(props);
                this.pic_container.css(props).css('z-index', 0);
                this.tags_container.css(props).css('z-index', 1);
                //this.pad.css(props).css('z-index', 2);
                this.anchors_container.css(props).css('top', h + 'px').css('height', 'auto');
                //
                this.pad.mousedown(function(event){self.beginTagging(event);}).mouseup(function(event){self.endTagging(event);}).mouseenter(function(){self.showCaptions();}).mouseleave(function(){self.hideCaptions();}).addClass('img_tg_transparent');
                this.draw();
                this.ready = true;
            },
            draw:function()
            {
                this.tags = [];
                this.anchors = [];
                this.captions = [];
                //
                this.tags_container.html('');
                this.anchors_container.html('');
                //
                if (this.data.length > 0)
                {
                    this.anchors_container.html('In this picture: ');
                    for (var i = 0; i < this.data.length; i++)
                    {
                        this.drawTag(this.data[i][0], this.data[i][1],this.data[i][2]);
                        if (i < this.data.length - 1)
                        {
                            $('<span>, </span>').appendTo(this.anchors_container);
                        }
                    }
                }
                this.parent.css('width', this.container.width() + 'px').css('height', this.container.height() + this.anchors_container.height() + 'px');
            },
            showCaptions:function(){for (var i = 0; i < this.captions.length; i++){this.captions[i].show();}},
            hideCaptions:function(){for (var i = 0; i < this.captions.length; i++){this.captions[i].hide();}},
            beginTagging:function(e)
            {
                if (!this.editable){return;}
                var self = this;
                this.startX = e.layerX ? e.layerX : e.offsetX;
                this.startY = e.layerY ? e.layerY : e.offsetY;
                this.ghost = $('<div>').addClass('img_tg_tag').hide().css('position', 'absolute').appendTo(this.tags_container);
                this.pad.mousemove(function(event){self.dragTag(event);});
                // prevent ugly Firefox behaviour  while dragging
                if (e.preventDefault){e.preventDefault();}
            },
            endTagging:function(e)
            {
                if (!this.editable){return;}
                this.pad.unbind('mousemove');
                var caption = prompt("Tag", "tag name");
                if (caption)
                {
                    var rect = [this.ghost.position().left,this.ghost.position().top,this.ghost.width(),this.ghost.height()];
                    this.addTag(rect, caption,linkdata);
                    $(this).trigger('change', [rect, caption]);
                }
                this.ghost.remove();
                this.ghost = undefined;
            },
            dragTag:function(e)
            {
                if (!this.editable){return;}
                var w,h,x,y;
                e.layerX = e.layerX ? e.layerX : e.offsetX;
                e.layerY = e.layerY ? e.layerY : e.offsetY;
                x = Math.min(e.layerX, this.startX);
                y = Math.min(e.layerY, this.startY);
                w = Math.abs(e.layerX - this.startX);
                h = Math.abs(e.layerY - this.startY);

                this.ghost.css('top', y + 'px').css('left', x + 'px').css('width', w + 'px').css('height', h + 'px').show();
                //console.log(e);
            }
        };
        ImageTagger.prototype = o;

})(jQuery);
