/**
 * Impressions component
 *
 * model = {
 *      entity: {
 *          type: 'dest',
 *          id: 999
 *      },
 *      ratingAverage: 3.67,
 *      voters: 145,
 *      // optionals
 *      review: {
 *          title: 'Nice Place',
 *          link: '/travel/',
 *          review: 'This is grate hotel',
 *          navigation: {
 *              prev: 45, // id's of review
 *              next: 47,
 *          }
 *          totalReviews: 43,
 *          userName: 'Lara & Sara',
 *          userAvatar: '/travel/pics/46?mode=hitlist-thumbnail',
 *      },
 *      ratings: {
 *          tob: [{
 *              id: 1,
 *              title: 'Do',
 *              value, 3.45
 *          }, {
 *              id: 2,
 *              title: 'Stay',
 *              value: 4.67
 *          }],
 *          travelers: [{
 *              id: 1, // unused
 *              title: 'Over All',
 *              value: 4.01
 *          }, {
 *              id: 2,
 *              title: 'Couples',
 *              value: 2.55
 *          }]
 *      },
 *      photos: {
 *          "pictures":[
 *              {"url":"/travel/pics/14?mode=presentation-picture","width":360,"height":239},
 *              {"url":"/travel/pics/15?mode=presentation-picture","width":360,"height":539},
 *              {"url":"/travel/pics/16?mode=presentation-picture","width":360,"height":269},
 *              {"url":"/travel/pics/17?mode=presentation-picture","width":360,"height":235},
 *              {"url":"/travel/pics/18?mode=presentation-picture","width":360,"height":540}
 *          ],
 *          "thumbnails":[
 *              {"url":"/travel/pics/14?mode=presentation-thumbnail","width":105,"height":70},
 *              {"url":"/travel/pics/15?mode=presentation-thumbnail","width":46,"height":70},
 *              {"url":"/travel/pics/16?mode=presentation-thumbnail","width":93,"height":70},
 *              {"url":"/travel/pics/17?mode=presentation-thumbnail","width":107,"height":70},
 *              {"url":"/travel/pics/18?mode=presentation-thumbnail","width":46,"height":70}
 *          ],
 *          "info":[
 *              {"title": "Sea shore", "author": "Paul Leggre", "descr": "I like this sea coast. In this place I feel yourself a child of the universe. Here is the power. Here is the live."},
 *              {"title": "Alone tree", "author": "Marry Kate", "descr": "This picture was taken in early morning from a moving bus. It came better than i expected. There was lot of fog (dew rather). This tree was the only one in this field and somehow i felt like clicking it."},
 *              {"title": "Yellow fish", "author": "Marilyn Manson", "descr": "Will somebody save me? Do you wanna know how living is beneath the waves? Do you wanna know how everything I knew was changed?\nIt wasnt such a big commotion, all you need is magic potion with a wriggle, a twist, a splash and a splish, you're a fish. Help me!"},
 *              {"title": "Sunset at grape vineyards", "author": "Jasper North", "descr": "I first realized that my father was serious about growing grapes when he announced his intention to raze our modest, but popular baseball diamond in favor of a nursery. My brothers and I created that ball park, hacking it out from a fallow field with a regular push-type lawnmower. We even built a substantial chicken-wire backstop to halt the progress of an errant pitch."},
 *              {"title": "Solid Rock", "author": "Larry Norman", "descr": "The constant sea billows roll and pound as the Solid Rock stands fast. The rock represents God's strength as the rock of our salvation stands firm. The surging sea represents the push and pull of this world (the devil) who threatens to tear us down."}
 *          ]
 *      }
 * }
 *
 * @author Mista K.
 */

(function () {

    var assets;

    /**
     * Private component for review navigation
     *
     * @constructor
     * @param target {DOMNode} root object
     * @param model  {Object}  optional for control of accessability
     *
     * @method disable {DOMNode|String} element to disable
     * @method enable  {DOMNode|String} element to enable
     * @method update  {Object} update accessability
     * @method getElement       ul.navigate getter
     */
    var reviewNavigation = function(target, model) {
        var self = TRAVEL.Observable2();
        var liEles, ul, data;

        self.disable = function (obj) {
            if (typeof obj === 'string') {
                obj = liEles.filter('.' + obj);
            }
            obj = obj || liEles;
            $('span', obj).addClass('disabled');
        };

        self.enable = function (obj) {
            if (typeof obj === 'string') {
                obj = liEles.filter('.' + obj);
            }
            obj = obj || liEles;
            $('span', obj).removeClass('disabled');
        };

        self.update = function (navData) {
            data = navData;
            if (navData.prev == undefined && navData.next == undefined) {
                self.disable();
            } else {
                if (navData.prev == undefined) {
                    self.disable('prev');
                } else {
                    self.enable('prev');
                }
                if (navData.next == undefined) {
                    self.disable('next');
                } else {
                    self.enable('next');
                }
            }
        };

        self.getElement = function () {
            return ul;
        };

        ul = $(['<ul class="navigate">',
                '<li class="prev"><span unselectable="on">', assets.prev, '</span></li>',
                '<li class="next"><span unselectable="on">', assets.next, '</span></li>',
            '</ul>'].join('')).appendTo(target);

        liEles = $('li', self.getElement()).click(function () {
            if (!$('span', this).hasClass('disabled')) {
                self.notify('changeReview', data[this.className]);
            }
        });

        if (model) {
            self.update(model);
        }

        return self;
    };




    /**
     * Private component for view pictures
     */
    var photosPanel = function (target) {
        var self = TRAVEL.Observable2();
        var block, root = target;
        var slides, infoBlock;
        var curEntity = {};

        function uploadPhotos () {

            var obj = [];

            obj.push('<div class="upload"><div class="clearer">',
                    '<h3>', assets.uploadtitle, '</h3>',
                    '<div class="col">',
                        '<div class="row"><span>1.</span>',
                            '<input type="file" class="file">',
                            '<input type="text" class="text">',
                        '</div>',
                        '<div class="row"><span>2.</span>',
                            '<input type="file" class="file">',
                            '<input type="text" class="text">',
                        '</div>',
                        '<div class="row"><span>3.</span>',
                            '<input type="file" class="file">',
                            '<input type="text" class="text">',
                        '</div>',
                        '<div class="row"><span>4.</span>',
                            '<input type="file" class="file">',
                            '<input type="text" class="text">',
                        '</div>',
                        '<div class="row"><span>5.</span>',
                            '<input type="file" class="file">',
                            '<input type="text" class="text">',
                        '</div>',
                        '<div class="agreetext">',
                            '<h4>', assets.agreetitle, '</h4>',
                            '<div><input type="checkbox" class="chb" />',
                                '<p>', assets.agreetext.sprintf('<a href="#">' + assets.termlink + '</a>'), '</p>',
                            '</div>',
                        '</div>',
                        '<table class="btn btn31-blue uploadphotos"><tr>',
                            '<td class="btn-left"><span></span></td>',
                            '<td class="btn-center">',
                                '<span unselectable="on"><button type="button" disabled="disabled" class="btn-text">', assets.uploadbtn, '</button></span>',
                            '</td>',
                            '<td class="btn-right"><span></span></td>',
                        '</tr></table>',                            
                    '</div><div class="col rules">',
                        '<h4>', assets.rulestitle, '</h4>',
                        '<p>', assets.rulestext, '</p>',
                        '<ul>',
                            '<li class="title">', assets.rules0, '</li>',
                            '<li>', assets.rules1, '</li>',
                            '<li>', assets.rules2, '</li>',
                            '<li>', assets.rules3, '</li>',
                            '<li>', assets.rules4, '</li>',
                            '<li>', assets.rules5, '</li>',
                            '<li>', assets.rules6, '</li>',
                        '</ul>',
                        '<p>', assets.guidelinestext.sprintf('<a href="#">' + assets.guidelineslink + '</a>'), '</p>',
                    '</div>',
                    '</div></div>');

            $(block).children().addClass('hidden');
            $(block).append(obj.join(''));

            $('.agreetext input.chb', block).click(function () {
                $('.uploadphotos button', block).attr('disabled', this.checked ? '' : 'disabled');
            });

            var inputFile = $('input.file', block);

            var uploadCallback = function (responseText) {
                var m = eval("(" + responseText + ")");
                $('div.upload', block).remove();
                self.notify('imageRefresh', m);
            };

            var picturesUpload = new AjaxFileUpload( {
                    baseLink : baseUrl + "ajaxCommandHTML.service",
                    serviceName : "travel.command.TravelImageUpload",
                    input : inputFile,
                    callback : uploadCallback
                } );

            $('.btn.uploadphotos', block).click(function () {
                var i, obj, data = {'entity': curEntity, 'files': []};
                for (i = 0; i < inputFile.length; i++) {
                    obj = inputFile[i];
                    if (obj.name === '') {
                        obj.name = 'pic' + Math.floor(Math.random() * 99999);
                    }
                    data.files.push({
                        'id': obj.name,
                        'title': $(obj).siblings('input.text').val()
                    });
                }

                picturesUpload.setServiceParameters([encodeURIComponent(Object.toJSON(data))]);

                picturesUpload.upload();
            });

        }
        
        function changePicture(info) {
            $(infoBlock.firstChild).html(['<h3>', info.title, '</h3>',
                    '<p class="author">', assets.authorlabel, ' ', info.author, '</p>',
                    TRAVEL.para(info.descr),
                    ((info.remove === true) ?
                        '<div class="remove-photo"><span>' + assets.removephoto + '</span></div>' : '')
                ].join(''));

            $('.remove-photo span', infoBlock).click(function () {
                var ajaxRemovePhoto = baseUrl + "ajaxCommand.service?command=travel.command.TravelImageDelete";

                TRAVEL.postJSON(ajaxRemovePhoto, {'entity': curEntity, 'image': info.id}, function (m) {
                    self.notify('imageRefresh', m);
                });
            });
        }

        self.render = function(model, entity) {

            curEntity = entity;

            $('ul.navigate-slides', root).remove();
            $('div.slideline', root).parent().remove();

            block = document.createElement('div');
            block.className = "photos-container";
            $('.item', root).append(block);

            if (model.pictures.length && model.thumbnails.length && model.info.length) {
                var nav = $('.impressions-hitlist-menu', root).get(0);
                slides = TRAVEL.Slides(block, nav, model)
                        .attachObserver('changePicture', function (pos) {
                            changePicture(model.info[pos]);
                        });

                infoBlock = document.createElement('div');
                infoBlock.className = 'slides-info';
                $(infoBlock).html('<div class="slides-info-details"></div>');
                if (TRAVEL.isAuthenticated) {
                    $(infoBlock).append('<div class="upload-link"><span>' + assets.placemyphotos + '</span></div>');
                    $('.upload-link span', infoBlock).click(uploadPhotos);
                }

                $('.fullsize-wrapper', root).prepend(infoBlock);

                slides.notify('changePicture', 0);
            } else {
                $(block).append(['<div class="no-slides-wrapper">',
                        '<p>', assets.nophotos, '</p>',
                    '</div>'].join(''));
                if (TRAVEL.isAuthenticated) {
                    $('.no-slides-wrapper', block).append('<div class="upload-link"><span>' + assets.placemyphotos + '</span></div>');
                    $('.upload-link span', block).click(uploadPhotos);
                }
            }
        };

        return self;
    };



    /**
     * Private component for view and set ratings
     */
    var ratingsPanel = function (target) {

        var ajaxSaveRatings = baseUrl + 'ajaxCommand.service?command=travel.command.JSONRateEntity';

        var self = TRAVEL.Observable2(), root = target;

        var i, r, obj = [];
        var block = $('.ratings-container', root);

        var getWidth = function (data) {
            var w = Math.round(100 * data / 5); // (data.max - data.min + 1));
            w = (w > 100) ? 100 : (w < 0) ? 0 : w;
            return (w + "%");
        };

        function setRatings (model, entity) {

            var i, r, obj = [];

            var ratingData = {'values': {}, 'entity': entity};

            var entityTitle = {
                'dest': assets.destination,
                'prdc': assets.producer,
                'prdct': assets.product
            };

            obj.push('<div><p>', assets.ratetitle.sprintf(entityTitle[entity.type]), '</p>');

            obj.push('<div class="col">',
                    '<h3>', assets.rateservice, '</h3>',
                    '<table><tbody>');
            for (i = 0, r = model.tob; i < r.length; i++) {
                obj.push('<tr>',
                        '<td><div class="myrating" id="myrating-', r[i].id, '"></div></td>',
                        '<td><div class="label">', r[i].title, '</div></td>',
                        '</tr>');
                ratingData.values[r[i].id] = 0;
            }
            obj.push('</tbody></table></div>');

            obj.push('<div class="col">',
                    '<h3>', assets.typetravelers, '</h3>',
                    '<table><tbody>');
            // skip first travelers group
            for (i = 1, r = model.travelers; i < r.length; i++) {
                obj.push('<tr>',
                        '<td><input type="radio" name="', entity.type + '-' + entity.id, '" value="', r[i].id, '" /></td>',
                        '<td><div class="label">', r[i].title, '</div></td>',
                        '</tr>');
            }
            obj.push('</tbody></table></div>');

            obj.push('<div class="clearer" style="margin-bottom: 14px;">',
                        '<div class="ftl">',
                            '<table class="btn btn20" style="margin-right: 10px; margin-left: 48px;"><tr>',
                                '<td class="btn-left"><span></span></td>',
                                '<td class="btn-center">',
                                    '<span unselectable="on"><button type="button" class="btn-text">', assets.save, '</button></span>',
                                '</td>',
                                '<td class="btn-right"><span></span></td>',
                            '</tr></table>',
                        '</div>',
                        '<div class="ftl">',
                            '<table class="btn btn20"><tr>',
                                '<td class="btn-left"><span></span></td>',
                                '<td class="btn-center">',
                                    '<span unselectable="on"><button type="button" class="btn-text">', assets.cancel, '</button></span>',
                                '</td>',
                                '<td class="btn-right"><span></span></td>',
                            '</tr></table>',
                        '</div>',
                    '</div>');

            obj.push('</div>'); // block end

            block.firstChild.className = "hidden";
            $(block).append(obj.join(''));

            $('.myrating', block).starrating({callback: function (r) {
                var id = this.parentNode.id.match(/^myrating-(.+)$/);
                ratingData.values[id[1]] = r;
                return {'value': r, 'voters': 1};
            }});

            $('input:radio', block).click(function () {
                ratingData.group = this.value;
            }).eq(0).click();

            $('.btn:eq(0)', block).click(function () {
                TRAVEL.postJSON(ajaxSaveRatings, ratingData, function (json) {
                    $(block).remove();
                    self.notify("updateRatings", json);
                });
            });

            $('.btn:eq(1)', block).click(function () {
                $(block).children(':not(:first)').remove();
                block.firstChild.className = "";
            });
        }

        self.render = function (model, entity) {

            block = document.createElement('div');
            block.className = 'ratings-container clearer';
            obj = [];
            obj.push('<div><div class="col">',
                    '<h3>', assets.rateservice, '</h3>',
                    '<table><tbody>');
            for (i = 0, r = model.tob; i < r.length; i++) {
                obj.push('<tr>',
                        '<td><div class="readonly star-rating">',
                        '<div class="star-rating-bar"><div class="bar" style="width: ', getWidth(r[i].value), ';">', r[i].value, '</div></div>',
                        '</div></td>',
                        '<td><div class="label">', r[i].title, '</div></td>',
                        '</tr>');
            }
            obj.push('</tbody></table></div>');

            obj.push('<div class="col">',
                    '<h3>', assets.ratetravelers, '</h3>',
                    '<table><tbody>');
            for (i = 0, r = model.travelers; i < r.length; i++) {
                obj.push('<tr>',
                        '<td><div class="readonly star-rating">',
                        '<div class="star-rating-bar"><div class="bar" style="width: ', getWidth(r[i].value), ';">', r[i].value, '</div></div>',
                        '</div></td>',
                        '<td><div class="label">', r[i].title, '</div></td>',
                        '</tr>');
            }
            obj.push('</tbody></table></div>');

            if (TRAVEL.isAuthenticated) {
                obj.push('<div class="rate-this-link"><span>', assets.ratethis, '</span></div>');
            }
            obj.push('</div>');
            $('.item', root).empty().append($(block).html(obj.join('')));

            $('div.rate-this-link span', block).click(function () {
                setRatings(model, entity);
            });

            $('.head-rating', root).starrating({'value': model.travelers[0].value, 'voters': model.travelers[0].voters});
        };

        return self;
    };



    var reviewPanel = function (target) {

        var ajaxSaveReview = baseUrl + 'ajaxCommand.service?command=travel.command.JSONWriteReview';

        var root = target, navigation;
        var self = TRAVEL.Observable2();

        var currentModel;

        function showMyReview(model, entity) {

            var holder, block = $('.myreview-container', root);

            if (block.length === 0) {
                holder = $.template(['<div class="myreview-container">',
                    '<p>', assets.reviewtext, '</p>',
                    '<input id="#title" class="text" value="" />',
                    '<textarea id="#message" class="text"></textarea>',
                    '<div class="clearer">',
                        '<div class="ftl">',
                            '<table id="#send" class="btn btn20" style="margin-right: 10px;"><tr>',
                                '<td class="btn-left"><span></span></td>',
                                '<td class="btn-center">',
                                    '<span unselectable="on"><button type="button" class="btn-text">', assets.send, '</button></span>',
                                '</td>',
                                '<td class="btn-right"><span></span></td>',
                            '</tr></table>',
                        '</div>',
                        '<div class="ftl">',
                            '<table id="#cancel" class="btn btn20"><tr>',
                                '<td class="btn-left"><span></span></td>',
                                '<td class="btn-center">',
                                    '<span unselectable="on"><button type="button" class="btn-text">', assets.cancel, '</button></span>',
                                '</td>',
                                '<td class="btn-right"><span></span></td>',
                            '</tr></table>',
                        '</div>',
                    '</div>',
                '</div>'].join(''), $('.item', root), 'append');

                TRAVEL.Button(holder.send, 'click', function () {
                    var title = $('div.myreview-container input.text', root).val();
                    var msg = $('div.myreview-container textarea', root).val();
                    var data = {'title': title, 'text': msg, 'entity': entity};
                    if (model.id) {
                        data.reviewId = model.id;
                    }
                    if (msg.length > 0) {
                        TRAVEL.postJSON(ajaxSaveReview, data, function (json) {
                            $(block).remove();
                            self.notify('showReviews', json);
                        });
                    }
                });

                TRAVEL.Button(holder.cancel, 'click', function () {
                    self.notify('showReviews');
                });
            }

            $('div.myreview-container input.text', root).val(model.title || '');
            $('div.myreview-container textarea', root).val(model.review || '');

            self.notify('showMyReview');
        }


        self.render = function (model, entity) {

            currentModel = model;

            function getOtherLinks(m) {
                var str = '';
                if (TRAVEL.isAuthenticated) {
                    if (typeof m.navigation.own !== 'undefined') {
                        str += '<li class="show-review"><span>' + assets.showmyreview + '</span></li>';
                    } else {
                        str += '<li class="my-review"><span>' + assets.myreview + '</span></li>';
                    }

                    str += '<li class="edit-review"><span>' + assets.correctreview + '</span></li>';
                    str += '<li class="remove-review"><span>' + assets.removereview + '</span></li>';
                }
                return str;
            }

            var block, obj = [];
			$('.item', root).html("");
            if ($('div.reviews-container', root).length === 0) {
                block = document.createElement('div');
                block.className = 'clearer reviews-container';
                $('.item', root).append(block);

                if (typeof model.review !== 'undefined') {
                    obj.push('<div class="item-wrapper">',
                                '<div class="item-body">',
                                    '<h3>', model.title, '</h3>',
                                    TRAVEL.para(model.review),
                                '</div>',
                            '</div>',
                            '<div class="item-image">',
                                '<img src="', model.userAvatar, '" alt="', model.userName, ' avatar" />',
                                '<span>', model.userName, '</span>',
                            '</div>',
                            '<ul class="item-links">',
                                '<li class="all-reviews">', assets.allreviews, ' (<em>', model.totalReviews, '</em>)</li>',
                                '<li class="abuse"><span>', assets.abuse, '</span></li>',
                                getOtherLinks(model),
                            '</ul>');

                    $(block).append(obj.join(''));

                    if (!model.remove) {
                        $('li.edit-review, li.remove-review', root).addClass('hidden');
                    }

                    $('ul.item-links li.remove-review span', root).click(function () {
                    	var ajaxDeleteReview = baseUrl + 'ajaxCommand.service?command=travel.JSONDeleteReview';
                        TRAVEL.postJSON(ajaxDeleteReview, {'review': currentModel.id, 'entity': entity}, function (m) {
                            self.notify('showReviews', m);
                        });
                    });

                    $('ul.item-links li.edit-review span', root).click(function () {
                        showMyReview(currentModel, entity);
                    });

                    $('ul.item-links li.show-review span', root).click(function () {
                        self.notify('changeReview', currentModel.navigation.own);
                    });

                    $('.abuse', root).click(function (e) {
                        TRAVEL.SendAbuse(entity.type, entity.id, e);
                    });

                    // TODO: empty
                    var container = $('.impressions-hitlist-menu', root).get(0);
                    while (container.childNodes.length > 1)
                        container.removeChild(container.childNodes[1]);

                    navigation = reviewNavigation($('.impressions-hitlist-menu', root).get(0), model.navigation)
                            .attachObserver('changeReview', function (pos) {
                                self.notify('changeReview', pos);
                            });
                    $(navigation.getElement()).addClass('navigate-reviews');
                } else {
                    $(block).append('<div class="empty-block">' + TRAVEL.para(assets.noreview) + '</div>');
                    if (TRAVEL.isAuthenticated) {
                        $(block).append(['<ul class="item-links">',
                                    '<li class="my-review"><span>', assets.myreview, '</span></li>',
                                '</ul>'].join(''));
                    }
                }
                $('ul.item-links li.my-review span', root).click(function () {
                    showMyReview({}, entity);
                });
            } else {
                self.update(model, entity);
            }
        };

        self.update = function (model, entity) {

            currentModel = model;

            if (model.review) {
                $('div.item-body', root).html(['<h3>', model.title, '</h3>',
                    TRAVEL.para(model.review)].join(''));
                $('div.item-image', root).html(['<img src="', model.userAvatar, '" alt="', model.userName,' avatar" />',
                    '<span>', model.userName, '</span>'].join(''));
                $('ul.item-links li.all-reviews em').html(model.totalReviews);

                navigation.update(model.navigation);

                if (model.remove) {
                    $('li.edit-review, li.remove-review', root).removeClass('hidden');
                } else {
                    $('li.edit-review, li.remove-review', root).addClass('hidden');
                }
            }
        };

        return self;
    };




    TRAVEL.ImpressionsHitlist = function (target) {

        var root = target, menu = null;

        // inject assets
        assets = TRAVEL.Assets.Impressions;

        var ajaxReviewProvider = baseUrl + 'ajaxCommand.service?command=travel.command.JSONReviewProvider';
        var ajaxRatingsProvider = baseUrl + 'ajaxCommand.service?command=travel.JSONStubCommand';
        var ajaxPhotosProvider = baseUrl + 'ajaxCommand.service?command=travel.command.JSONTravelImagesProvider';

        function changeMode(mode) {
            var cls = root.className.match(/mode-(\w+)/g);
            $(cls).each(function () {
                $(root).removeClass(this);
            });
            $(root).addClass('mode-' + mode);
        }

        this.create = function (model) {
            var activeTab, nav, obj = [];

            var panels = {};

            function showReviews() {
                if (!model.review) {
                    TRAVEL.getJSON(ajaxReviewProvider, {'position': 0, 'entity': model.entity}, function (json) {
                        model.review = json;
                        showReviews();
                    });
                } else {
                    if (!panels.review) {
                        panels.review = reviewPanel(root);
                    }
                    panels.review
                            .attachObserver('changeReview', function (pos) {
                                TRAVEL.getJSON(ajaxReviewProvider, {'position': pos, 'entity': model.entity}, function (json) {
                                    model.review = json;
                                    panels.review.update(json);
                                });
                            })
                            .attachObserver('showMyReview', function () {
                                changeMode('myreview');
                            })
                            .attachObserver('showReviews', function (data) {
                                if (data) {
                                    model.review = data;
                                    panels.review.render(data, model.entity);
                                }
                                changeMode('reviews');
                            });
                    panels.review.render(model.review, model.entity);
                    changeMode('reviews');
                }
            }

            function showRatings() {

                if (!model.ratings) {
                    TRAVEL.getJSON(ajaxRatingsProvider, {'entity': model.entity}, function (json) {
                        model.ratings = json;
                        showRatings();
                    });
                } else {
                    if (!panels.ratings) {
                        panels.ratings = ratingsPanel(root);
	                    panels.ratings
	                        .attachObserver('updateRatings', function (data) {
	                            model.ratings = data;
	                            showRatings();
	                        });
                    }
                    panels.ratings.render(model.ratings, model.entity);
                    changeMode('ratings');
                }
            }

            function showPhotos() {

                if (!model.photos) {
                    TRAVEL.getJSON(ajaxPhotosProvider, {'entity': model.entity}, function (json) {
                        model.photos = json;
                        showPhotos();
                    });
                } else {
                    // container for Slides must be visible at render step
                    changeMode('photos');
                    if (!panels.photos) {
                        panels.photos = photosPanel(root);
                        panels.photos
                            .attachObserver('imageRefresh', function (data) {
                                model.photos = data;
                                showPhotos();
                            });
                    }
                    panels.photos.render(model.photos, model.entity);
                }
            }


            if (model.review) {
                activeTab = 0;
            } else if (model.ratings) {
                activeTab = 1;
            } else if (model.photos) {
                activeTab = 2;
            }

            obj.push('<div class="clearer">',
                    '<h1 class="title"><a name="impressions">', assets.blocktitle, '</a></h1>',
                    '<div class="head-rating readonly"></div>',
                '</div>',
                '<div class="impressions-hitlist-menu clearer"></div>',
                '<div class="item"></div>');

            if (!TRAVEL.isAuthenticated) {
                obj.push('<p class="anonymousnote">', assets.anonymousnote, '</p>');
            }

            $(root).append(obj.join(''));

            $('.head-rating').starrating({'value': model.ratingAverage, 'voters': model.voters});

            nav = $('div.impressions-hitlist-menu', root).get(0);
            var menuData = [{
                    name: assets.menureviews,
                    event: 'showReviews'
                }, {
                    name: assets.menuratings,
                    event: 'showRatings'
                }, {
                    name: assets.menuphotos,
                    event: 'showPhotos'
                }
            ];
            menu = new TRAVEL.HorizMenu(nav, {selectedIndex: activeTab, items: menuData});
            menu.attachObserver(menuData[0].event, showReviews)
                .attachObserver(menuData[1].event, showRatings)
                .attachObserver(menuData[2].event, showPhotos)
                .notify(menuData[activeTab].event);
        };
    };
})();