function ReviewProMiniWidget(apiKey, widgetId, renderTarget, lang, overrideProductId) {
    this.apiKey = apiKey;
    this.overrideProductId = overrideProductId;
    this.renderTarget = renderTarget;
    this.widgetId = widgetId;
    this.lang = lang;
    this.resURL = 'http://api.reviewpro.com/static/v1/';
    this.shouldShowToolTip = false;
    this.showingToolTip = false;
    this.mX = 0;
    this.mY = 0;

    this.render = function() {
        var width;
        var height;
        jQuery('#'+this.renderTarget)
            .css({
                fontFamily: 'helvetica, arial',
                width: width,
                height: height
            });
        var jsonURL = 'http://api.reviewpro.com/ws/v1/' + this.apiKey + '/data/miniwidget/' +this.widgetId +'/'+ this.lang;
        if (this.overrideProductId != null) {
            jsonURL += '/' + overrideProductId;
        }
        var _this = this;
        jQuery.ajax({
            type: "GET",
            url: jsonURL,
            dataType: "jsonp",
            success: function(data) {
                var centre = function(el) {
                    var w = el.getBBox().width;
                    el.translate(w/-2, 0);
                };
                var nonIEOffsetY = jQuery.browser.msie ? 0 : -2;
                var nonIEOffsetX = jQuery.browser.msie ? 0 : 1;
                var show = data.layout.showbars + '' + data.layout.showname + '' + data.layout.biglogo;
                var r = Raphael(renderTarget, data.layout.width, data.layout.height);
                if (data.layout.scoretype == 'verbal') {
                    var vLength = data.score.verbal.length;
                    var score = r.text(39, 67, data.score.verbal).attr({ 'font-size': 3.5 / (vLength + 2) * 40, fill: '#444' });
                } else {
                    var score = r.text(39,67, data.score.numeric + '%').attr({ 'font-size': 22, 'font-weight': 'bold', fill: '#444' });
                }
                   var helpLeft = '174px';
                    var helpTop = '12px';
                    var drawBars = function(bx, by) {
                    var bgBars = r.set();
                    bgBars.push(r.rect(78, 54, 85, 10), r.rect(78, 67, 85, 10), r.rect(78, 80, 85, 10));
                    bgBars.attr({ stroke: '#eee', 'stroke-width': 0, fill: '#ddd' });
                    var brPos = r.rect(78, 54, data.score.pos/100*85, 10).attr({ fill: '#4b3' });
                    var brMed = r.rect(78, 67, data.score.med/100*85, 10).attr({ fill: '#fa1' });
                    var brNeg = r.rect(78, 80, data.score.neg/100*85, 10).attr({ fill: '#d01' });
                    var bars = r.set();
                    bars.push(brPos, brMed, brNeg).attr({ stroke: '#ddd', 'stroke-width': 0 });
                    var pcPos = r.text(175 + nonIEOffsetX, 62 + nonIEOffsetY, data.score.pos + '%').attr({ 'font-size': 10, fill: '#666' });
                    var pcMed = r.text(175 + nonIEOffsetX, 75 + nonIEOffsetY, data.score.med+'%').attr({ 'font-size': 10, fill: '#666' });
                    var pcNeg = r.text(175 + nonIEOffsetX, 88 + nonIEOffsetY, data.score.neg+ '%').attr({ 'font-size': 10, fill: '#666' });
                    bgBars.translate(bx, by);
                    bars.translate(bx, by);
                    var pc = r.set().push(pcPos, pcMed, pcNeg);
                    pc.translate(bx, by);
                }
                var reviewsStr = new String(data.score.reviews);
                var sitesStr = new String(data.score.sites);
                var reviewsNum = r.text(0, 0, reviewsStr.substring(0, reviewsStr.indexOf(' '))).attr({ 'font-size': 12, 'text-anchor': 'start' });
                var sitesNum = r.text(0, 0, sitesStr.substring(0, sitesStr.indexOf(' '))).attr({ 'font-size': 12, 'text-anchor': 'start' });
                var sitesOffset = reviewsNum.getBBox().width - sitesNum.getBBox().width;
                var reviewsOffset = sitesNum.getBBox().width - reviewsNum.getBBox().width;
                if (sitesOffset > reviewsOffset) {
                    reviewsOffset = 0;
                } else {
                    sitesOffset = 0;
                }
                reviewsNum.hide();
                sitesNum.hide();
                switch (show) {
                    case '000':
                    jQuery('#'+renderTarget).css({ background: 'url('+ _this.resURL +'bg-000.png) no-repeat 0 0' });
                    reviews = r.text(105 + nonIEOffsetX + reviewsOffset, 73 + nonIEOffsetY, data.score.reviews).attr({ 'font-size': 12, fill: '#444', 'text-anchor': 'start' });
                    sites = r.text(105 + nonIEOffsetX + sitesOffset, 90 + nonIEOffsetY, data.score.sites).attr({ 'font-size': 12, fill: '#444', 'text-anchor': 'start' });
                    score.translate(14, 16 + nonIEOffsetY);
                    break;
                    case '001':
                    jQuery('#'+renderTarget).css({ background: 'url('+ _this.resURL +'bg-001.png) no-repeat 0 0' });
                    reviews = r.text(108 + nonIEOffsetX + reviewsOffset, 85 + nonIEOffsetY, data.score.reviews).attr({ 'font-size': 12, fill: '#444', 'text-anchor': 'start' });
                    sites = r.text(108 + nonIEOffsetX + sitesOffset, 102 + nonIEOffsetY, data.score.sites).attr({ 'font-size': 12, fill: '#444', 'text-anchor': 'start' });
                    score.translate(18, 26 + nonIEOffsetY);
                    helpLeft = '131px';
                    helpTop = '35px';
                    break;
                    case '010':
                    jQuery('#'+renderTarget).css({ background: 'url('+ _this.resURL +'bg-010.png) no-repeat 0 0' });
                    reviews = r.text(105 + nonIEOffsetX + reviewsOffset, 59 + nonIEOffsetY, data.score.reviews).attr({ 'font-size': 12, fill: '#444', 'text-anchor': 'start' });
                    sites = r.text(105 + nonIEOffsetX + sitesOffset, 76 + nonIEOffsetY, data.score.sites).attr({ 'font-size': 12, fill: '#444', 'text-anchor': 'start' });
                    score.translate(12, nonIEOffsetY);
                     hotelName = r.text(93 + nonIEOffsetX, 115 + nonIEOffsetY, data.hotel.name).attr({ 'font-size': 13, fill: '#666' });
                    break;
                    case '100':
                    jQuery('#'+renderTarget).css({ background: 'url('+ _this.resURL +'bg-100.png) no-repeat 0 0' });
                    reviews = r.text(95 + nonIEOffsetX, 113 + nonIEOffsetY, data.score.reviews + ' | ' + data.score.sites).attr({ 'font-size': 11, fill: '#444' });
                    score.translate(0, nonIEOffsetY);
                    drawBars(0, -9);
                    break;
                    default:
                    jQuery('#'+renderTarget).css({ background: 'url('+ _this.resURL +'bg-110.png) no-repeat 0 0' });
                    var offsetY = _this.lang == 'es' ? -1 : 0;
                    var fontSize = 11;
                    reviews = r.text(130 + nonIEOffsetX, 46 + nonIEOffsetY + offsetY, data.score.reviews + ' | ' + data.score.sites).attr({ 'font-size': fontSize, fill: '#444' });
                    while (reviews.node.getComputedTextLength() > 115) {
                        reviews.attr({'font-size': --fontSize} );
                    }
                     score.translate(0, nonIEOffsetY);
                    drawBars(0, 0);
                     hotelName = r.text(93 + nonIEOffsetX, 115 + nonIEOffsetY, data.hotel.name).attr({ 'font-size': 13, fill: '#666' });
                    break;
                }
                var openPopup = function(){
                    window.open(data.help.url,'rrPopup','toolbar=no, location=yes, status=yes, menubar=no, scrollbars=yes, resizable=yes, width=550,height=330,left=430,top=23');
                    jQuery('#reviewproinfo'+_this.renderTarget).css({ visibility: 'hidden', display: 'none'});
                    return false;
                };
                var openInfo = function() {
                    jQuery('#reviewproinfo'+_this.renderTarget).css({visibility: 'visible', display: 'block'});
                    return false;
                };
                var hideInfo = function() {
                    jQuery('#reviewproinfo'+_this.renderTarget).css({ visibility: 'hidden', display: 'none'});
                    return false;
                };
                jQuery('#'+_this.renderTarget).css({ position: 'relative', width: 190, height: 130}).append('<a id="reviewprohelp'+_this.renderTarget+'"></a>');
                jQuery('body').append('<div id="reviewproinfo'+_this.renderTarget+'"><div id="reviewproinfoclose'+_this.renderTarget+'">X</div>'+data.help.gri+' <a id="reviewprolink'+_this.renderTarget+'" >' + data.help.linkText + '</a> </div>');
                var infoDiv = jQuery('#reviewproinfo'+_this.renderTarget);
                infoDiv.css({ position: 'absolute', zIndex: 999, display: 'none', visibility: 'hidden', width: 220, border: 'solid gray 1px', background: '#EFEFEF', padding: '5px', "font-size": '12px', color: 'black', "font-family": 'helvetica,arial' });
                jQuery('#reviewprohelp'+_this.renderTarget).css({ position: 'absolute', left: helpLeft, top: helpTop, zIndex: 998, display: 'block', width: '12px', height: '12px', cursor: 'pointer' })
                    .bind('click', openInfo);
                jQuery('#reviewprolink'+_this.renderTarget).css({cursor: 'pointer', 'text-decoration': 'underline', color: 'blue'})
                    .bind('click', openPopup);
                jQuery('#reviewproinfoclose'+_this.renderTarget).css({ 'float': 'right', cursor: 'pointer'})
                        .bind('click', hideInfo);
                var position = jQuery('#'+_this.renderTarget).offset();
                infoDiv.css('left', position.left + 90);
                infoDiv.css('top', position.top + 30);
            }
        });
    };
}


