(function($) {
    $.fn.bitTemplates = function(options) {
        var defaults = {
            showPrivacy: ["private", "users", "friends", "public"],
            
            messageBitSelector: ".message-bit",
            pictureBitSelector: ".picture-bit",
            collageBitSelector: ".collage-bit",
            videoBitSelector: ".video-bit",
            linkBitSelector: ".link-bit",
            videolinkBitSelector: ".videolink-bit",
            smsBitSelector: ".sms-bit",
            memorySelector: ".memory"
        };

        var opts = $.extend(defaults, options);
        
        // Clone the initial list and use as a template
        var template = $(this).clone();
        
        var messageBit = template.children(opts.messageBitSelector);
        var pictureBit = template.children(opts.pictureBitSelector);
        var collageBit = template.children(opts.collageBitSelector);
        var videoBit = template.children(opts.videoBitSelector);
        var linkBit = template.children(opts.linkBitSelector);
        var videolinkBit = template.children(opts.videolinkBitSelector);
        var smsBit = template.children(opts.smsBitSelector);
        var memoryTemplate = template.children(opts.memorySelector);
        
        var textbox_width = 298;
        var textbox_height = 100;
        
        var img_width = 160;
        var img_height = 120;
        var linkimg_width = 80;
        var linkimg_height = 80;
        var linkbox_width = 280;
        var linkbox_height = 90;
        var memoryimg_width = 140;
        var memoryimg_height = 140;
        var memorybox_width = 181;
        var memorybox_height = 177;
        var default_aspect_ratio = 4 / 3;
        
        function shrinkToFit(rect) {
            var heightInCells = Math.ceil((rect.height + opts.paddingHeight) / opts.cellHeight);

/*            if (heightInCells > gridHeight) {
                heightInCells = gridHeight;
                var oldHeight = rect.height;
                rect.height = ((heightInCells - 1) * opts.cellHeight) - opts.paddingHeight;
                var ratio = oldHeight / rect.height;
                rect.width /= ratio;
            }*/
        }

        function pictureCollageHandler(current) {
            var newdiv = pictureBit.clone();
            $("p.title", newdiv).text(current.title);
            $("p.description", newdiv).text(current.description);
            $("a.edit-link", newdiv).attr("href", "/bits/picture/edit/" + current.id);
            //console.log("current", current);

            var aspect_ratio;
            if (current.original_dims.width && current.original_dims.height) {
                aspect_ratio = current.original_dims.width / current.original_dims.height;
            } else {
                aspect_ratio = default_aspect_ratio;
            }
            newdiv.data("aspect_ratio", aspect_ratio);

            addCommentAndFavoriteCounts(current, newdiv, current.title);

            var img = $("img.memo-lane-small-pic", newdiv);
            img.attr("src", current.lane_image_url);


            shrinkToFit(current);
            //current.width = img_width;
            //current.height = img_width / aspect_ratio;

            if (aspect_ratio > default_aspect_ratio){
                img.width(img_width);
                current.width = img_width;
                var diff = current.original_dims.height - img_height;
                if (diff > 0){
                    current.height = img_width / aspect_ratio;
                    img.height = current.height;
                } else {
                    current.height = img_height;
                    img.css({"margin-top":Math.abs(diff/2)+"px"});
                }
            } else {
                current.height = img_height;
                var diff = current.original_dims.width - img_width;
                if (diff > 0){
                    current.width = img_height * aspect_ratio;
                    img.width = current.width;
                } else {
                    current.width = img_width;
                    img.css({"margin-left":Math.abs(diff/2)+"px"});
                }
                img.height(img_height);
            }
            //img.width(current.width);
            //img.height(current.height);

            var rotation = "rotate" + Math.round(Math.random() * 12 - 6);
            newdiv.addClass(rotation);

            return newdiv;
        }

        var handlers = {
            MessageBit: function(current) {
                var newdiv = messageBit.clone();
                $("a.edit-link", newdiv).attr("href", "/bits/text/edit/" + current.id);
                $("p.content", newdiv).text(truncate(current.body, 12));
                if (current.sender) {
                    $(".sender", newdiv).text("— " + current.sender);
                } else {
                    $(".sender", newdiv).text("");
                }

                addCommentAndFavoriteCounts(current, newdiv, current.sender);

                current.width = textbox_width;
                current.height = textbox_height;
                return newdiv;
            },
            PictureBit: pictureCollageHandler,
            CollageBit: pictureCollageHandler,
            VideoBit: function(current) {
                var newdiv = videoBit.clone();
                $("p.title", newdiv).text(current.title);
                $("p.description", newdiv).text(current.description);
                $("a.edit-link", newdiv).attr("href", "/bits/videofile/edit/" + current.id);

                addCommentAndFavoriteCounts(current, newdiv, current.title);

                var img = $("img.memo-lane-small-pic", newdiv);
                img.attr("src", current.lane_image_url);
                img.width(img_width); // FIXME: remove once images have proper sizes
                img.height(img_height); // FIXME: remove once images have proper sizes

                var rotation = "rotate" + Math.round(Math.random() * 12 - 6);
                newdiv.addClass(rotation);

                current.width = img_width;
                current.height = img_height;
                return newdiv;
            },
            LinkBit: function(current) {
                var newdiv = linkBit.clone();
                $("a.edit-link", newdiv).attr("href", "/bits/link/edit/" + current.id);
                $("p.title:first", newdiv).text(truncate(current.title, 5));
                $("p.title:last", newdiv).text(current.title);
                $(".source", newdiv).text(current.domain);

                addCommentAndFavoriteCounts(current, newdiv, current.title);

                var img = $("img.memo-lane-small-pic", newdiv);
                if (current.image_url) {
                    img.attr("src", current.image_url);
                } else {
                    img.remove();
                }
                //img.width(linkimg_width); // FIXME: remove once images have proper sizes
                //img.height(linkimg_height); // FIXME: remove once images have proper sizes

                var rotation = "rotate" + Math.round(Math.random() * 12 - 6);
                newdiv.addClass(rotation);

                current.width = linkbox_width;
                current.height = linkbox_height;
                return newdiv;
            },
            VideoLinkBit: function(current) {
                var newdiv = videolinkBit.clone();
                $("p.title", newdiv).text(current.title);
                $("a.edit-link", newdiv).attr("href", "/bits/video/edit/" + current.id);

                addCommentAndFavoriteCounts(current, newdiv, current.title);

                var img = $("img.memo-lane-small-pic", newdiv);
                img.attr("src", current.image_url);
                img.width(parseInt(current.image_width));
                img.height(parseInt(current.image_height));
                $(".source", newdiv).text(current.domain);

                var rotation = "rotate" + Math.round(Math.random() * 12 - 6);
                newdiv.addClass(rotation);

                if (current.domain.match("youtube")) {
                    newdiv.find(".videolink-icon").addClass("youtube-link-overlay");
                } else if (current.domain.match("vimeo")) {
                    newdiv.find(".videolink-icon").addClass("vimeo-link-overlay");
                } else {
                    newdiv.find(".videolink-icon").addClass("video-link-overlay");
                }

                current.width = parseInt(current.image_width); // no padding?
                current.height = parseInt(current.image_height); // no padding?
                return newdiv;
            },
            Memory: function(current) {
                var newdiv = memoryTemplate.clone();

                var img = $("img.memo-lane-small-pic", newdiv);
                var popupimg = $("img.memo-lane-big-pic", newdiv);

                if (current.lane_url) {
                    img.attr("src", current.lane_url);
                    popupimg.attr("id", current.popup_url);
                } else {
                    img.attr("src", "/images/default_latest_memory.png");
                    popupimg.attr("id", "/images/default_latest_memory.png");
                }

                addCommentAndFavoriteCounts(current, newdiv, current.name);
                $(".description", newdiv).text(current.description);
                $("a.edit-link", newdiv).attr("href", current.showmore_url);

                var rotation = "rotate" + Math.round(Math.random() * 12 - 6);
                newdiv.addClass(rotation);

                current.width = memorybox_width;
                current.height = memorybox_height;

                //img.width(memoryimg_width); // FIXME: remove once we have the dimensions of the image
                //img.height(memoryimg_height); // FIXME: remove once we have the dimensions of the image

                return newdiv;
            },
            SmsBit: function(current) {
                var newdiv = smsBit.clone();
                $("a.edit-link", newdiv).attr("href", "/bits/text/edit/" + current.id);
                current.width = 99; // FIXME: proper value
                current.height = 99; // FIXME: proper value
                return newdiv;
            }
        };
        
        function addCommentAndFavoriteCounts(current, newdiv, name){
            $(".overlay-info .name", newdiv).text(name);
            if (current.comment_count > 0){
                $("span.comments", newdiv).text(current.comment_count);
            } else {
                $("span.comments", newdiv).remove();
            }
            if (current.favorite_count > 0){
                $(".overlay-info span.favorites", newdiv).text(current.favorite_count);
            } else {
                $(".overlay-info span.favorites", newdiv).remove();
            }
        }

        function newlinesToBrs(value) {
            return value.replace(/\r\n|\r|\n/g, "<br />");
        }

        function getContent(current) {
            var handler = handlers[current.doc_type];
            var newdiv;

            if (handler) {
                newdiv = handler(current);
                $.metadata.setType("attr", "data");
                newdiv.metadata().bit_data = current;
                if (newdiv.metadata().bit_data.description) {
                    newdiv.metadata().bit_data.description = newlinesToBrs(newdiv.metadata().bit_data.description);
                }
                if (newdiv.metadata().bit_data.body) {
                    newdiv.metadata().bit_data.body = newlinesToBrs(newdiv.metadata().bit_data.body);
                }

                if ($.inArray(current.visibility, opts.showPrivacy) != -1) {
                    $("span.vis", newdiv).addClass(current.visibility);
                }

                newdiv.width(current.width);
                newdiv.height(current.height);
                newdiv.show();
                var checkbox = $("<input type=\"checkbox\" name=\"bits\" value=\"" + current.id + "\" id=\"" + current.id + "\" class=\"item_selector\" style=\"display: none;\"/>");
                newdiv.append(checkbox);
            } else {
                if (window.console) {
                    console.log("Error: unexpected doc_type");
                }
            }

            return newdiv;
        }

        function truncate(value, nof_words) {
            var split_value = value.split(" ");
            if (nof_words < split_value.length) {
                value = split_value.slice(0, nof_words).join(" ");
                value += " ...";
            }
            return value;
        }

        return {
            handler: getContent
        };
    };
})(jQuery);

