/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
*  Truncates review description for posting at FaceBook
* removes all tags and returnes plain text
*/
function truncate(str, max, settings ) {
    settings = jQuery.extend( {
        chars: /\s/,
        trail: [ "...", "" ]
    }, settings );

    var myStrOrig = str.replace( /\r\n/gim, "" );
    var myStr = myStrOrig;
    var myRegEx = /<\/?[^<>]*\/?>/gim;

    myStr = jQuery.trim( myStr.split( myRegEx ).join( "" ) );
    if ( myStr.length > max ) {
        var c;
        while ( max < myStr.length ) {
            c = myStr.charAt( max );
            if ( c.match( settings.chars ) ) {
                myStr = myStr.substring( 0, max );
                break;
            }
            max--;
        }
    }
    return myStr+settings.trail[0];
};


/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

/*
*   LouderVoice JS API Widget
*   @author: Bartosz Ptaszynski
*   @email: bart@yazzgoth.com
*   http://loudervoice.com/
*/
(function(jQuery){
    var options = {};
    var session_user_id = 0;
    var auth_sessions = {
        loudervoice: false,
        facebook: false,
        twitter: false
    };
    var session_id = null;
    
    var session_id = null;
    var widgetAvgRating = "<div id='avg_rating'></div>"
    var widgetReadHTML = "<h3 class='ui-accordion-header ui-helper-reset ui-state-active ui-corner-top'><span class='count'></span> <div id='avg_rating' class='lv-avg-stars stars' style='display: inline;'></div></h3>";
    widgetReadHTML += "<div class='lv_reviews ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active'></div>";
    var widgetWriteHTML = "<h3 class='ui-accordion-header ui-helper-reset ui-state-active ui-corner-top'>Write Review</h3>";
    widgetWriteHTML += "<div class='lv_write ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active'>";
    widgetWriteHTML += "<label class='lv-review-label item' for='item' style='display:none'>Title</label><input name='item' style='display:none' class='lv-input'/>";
    //widgetWriteHTML += "<label class='lv-review-label name' for='name' style='display:none'>Name</label><input name='name' style='display:none' class='lv-input'/>";
    widgetWriteHTML += "<div class='lv-review-rating'>";
		widgetWriteHTML += "<label class='lv-review-label rating' for='star_rating'>Rate it</label>";
    widgetWriteHTML += "<span><input name='star_new' type='radio' class='star' value='1' />";
    widgetWriteHTML += "<input name='star_new' type='radio' class='star' value='2' />";
    widgetWriteHTML += "<input name='star_new' type='radio' class='star' value='3' />";
    widgetWriteHTML += "<input name='star_new' type='radio' class='star' value='4' />";
    widgetWriteHTML += "<input name='star_new' type='radio' class='star' value='5' checked='checked'/>";
    widgetWriteHTML += "</span></div>";
    widgetWriteHTML += "<label class='lv-review-label textarea-label' for='description'>Review</label>&nbsp;<textarea class='lv-review-description lv-input' name='description'></textarea>"; //added as a quick-css-fix
    widgetWriteHTML += "<label class='lv-review-label tags' for='tags' style='display:none'>Tags</label><input name='tags' style='display:none' class='lv-input'/>";
    //widgetWriteHTML += "<br class='lv-clear'/>";
    widgetWriteHTML += "<div class='lv-submitarea'>";
    widgetWriteHTML += "<span class='fb_profile'></span>";
    widgetWriteHTML += "<input type='button' class='lv-logout ui-corner-all ui-state-default lv-button lv-button-left' value='log out' style='display:none'/>";
    widgetWriteHTML += "<input type='button' value='Send' class='lv-send ui-corner-all ui-state-default lv-button lv-button-right lv-button-send' style='display:none'/>"; // hidden by default
    widgetWriteHTML += "<span class='lv-also-post-to' style='display:none'>";
    widgetWriteHTML += "<p class='lv-facebook-enabled' style='display:none'><label for='lv-post-to-facebook'><input type='checkbox' id='lv-post-to-facebook' name='lv-post-to-facebook' /> post to Facebook</label></p>";
		widgetWriteHTML += "</span>";
		widgetWriteHTML += "<span class='lv-also-post-to' style='display:none'>";
    widgetWriteHTML += "<p class='lv-twitter-enabled' style='display:none'><label for='lv-post-to-twitter'><input type='checkbox' name='lv-post-to-twitter' id='lv-post-to-twitter' /> post to Twitter</label></p>";
    widgetWriteHTML += "</span>";
   // widgetWriteHTML += "<input type='button' value='LV' class='lv-login-send ui-corner-all ui-state-default lv-button lv-button-left' /> ";
   // widgetWriteHTML += "<span class='lv-whatis ui-icon ui-icon-info'></span>";
    widgetWriteHTML += "<input type='button' value='Send' class='lv-register-send ui-corner-all ui-state-default lv-button lv-button-right' />";
    
    widgetWriteHTML += "</div>";
    var waitHTML = "<div id='lv-pleasewait' title='Please wait...'>";
    waitHTML += "<p>Please wait</p><img src='http://api.loudervoice.com/static/images/loading.gif' align='center'/>";
    waitHTML += "</div>";
    //var loginHTML = "<div id='lv-login' title='Previous Reviewers Only'>";
    //loginHTML += "<p class='lv-other-auth'>Login using one of these IDs:</p>";
    //loginHTML += "<p><a href='javascript:void(0)' style='display:none' class='fb-login'> <img id='fb_login_image' src='http://static.ak.fbcdn.net/images/fbconnect/login-buttons/connect_light_medium_long.gif' alt='Connect' /> </a></p>";
	//	loginHTML += "<p><a href='javascript:void(0)' style='display:none' class='twitter-login'><img id='twitter_login_image' src='http://api.loudervoice.com/static/images/Sign-in-with-Twitter-darker.png' alt='Twitter OAuth'/></a></p>"; 
    //loginHTML += "<div id='lv-log-form'><p><strong>OR</strong> login with your LouderVoice ID:</p>";
    //loginHTML += "<p><label class='lv-review-label email' for='email'>Email</label>";
    //loginHTML += "<input type='text' class='lv-review-email lv-input-fit lv-credentials' name='email'/></p>";
    //loginHTML += "<p><label class='lv-review-label password lv-clear' for='password'>Password</label>";
    //loginHTML += "<input type='password' class='lv-review-password lv-input-fit lv-credentials' name='password'/></p>";
    //loginHTML += "<p class='lv-whatis-text'>What is LouderVoice?</p></div>";
    //loginHTML += "<img src='http://wiki.developers.facebook.com/images/a/ac/Connect_light_medium_short.gif'/>";

    //loginHTML += "</div>";
    var registerHTML = "<div id='lv-register' title='Tell us who you are'>";

    registerHTML += "<p><label class='lv-review-label name' for='name'>Name/Nickname</label>";
    registerHTML += "<input type='text' class='lv-review-name lv-input-fit lv-credentials' name='name'/></p>";
    registerHTML += "<p><label class='lv-review-label email' for='email'>Email</label>";
    registerHTML += "<input type='text' class='lv-review-email lv-input-fit lv-credentials' name='email'/></p>";
    
    registerHTML += "<div id='lv-reg-form'>";
    registerHTML += "<p><p class='fb-title' style='display:none'><strong>OR</strong> use your Facebook ID:</p><a href='javascript:void(0)' style='display:none' class='fb-login'> <img id='fb_login_image' src='http://static.ak.fbcdn.net/images/fbconnect/login-buttons/connect_light_medium_long.gif' alt='Connect' /> </a></p><p class='twitter-title' style='display:none'><strong>OR</strong> use your Twitter ID:</p><p><a href='javascript:void(0)' style='display:none' class='twitter-login'><img id='twitter_login_image' src='http://api.loudervoice.com/static/images/Sign-in-with-Twitter-darker.png' alt='Twitter OAuth'/></a></p>";    
    registerHTML += "</div>";
    
    registerHTML += "</div>";
    var aboutHTML = "LouderVoice is an Irish customer reviews system that powers the review functionality here. They will never pass your contact details to a third party. <a href='http://business.loudervoice.com/' target='_blank'>Learn more</a>";
    var re_email = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i;
    
    var email = "";
    var name = "";
    
    function showModal(obj, title, msg, icon){
        obj.append("<div id='lvModal' class='lv-modal' title='"+title+"'><p><span class='ui-icon "+icon+"' style='float:left; margin:2px 7px 50px 0;'></span></p><p style='margin-left:25px'>"+msg+"</p></div>");
        jQuery('#lvModal').dialog({
             bgiframe:true, modal:true, 
             buttons: {
                 Ok: function(){ 
                     jQuery(this).dialog('close');
                     jQuery(this).remove();
                 }
             }
        }); 
    };
    
    function closeModal(obj) {
        var modal = jQuery(".lv-modal");
        modal.dialog('close');
        modal.remove();
    }
    
    function checkLength(o,min,max) {
        if ( o.val().length > max || o.val().length < min ) {
            o.addClass('ui-state-error');
            o.effect('highlight');
            o.focus( function(){ o.removeClass('ui-state-error'); });
            return false;
        } else {
            o.removeClass('ui-state-error');
            return true;
        }

    };

    function checkRegexp(o,regexp) {

        if ( !( regexp.test( o.val() ) ) ) {
            o.addClass('ui-state-error');
            o.effect('highlight');
            o.focus( function(){ o.removeClass('ui-state-error'); });
            return false;
        } else {
            o.removeClass('ui-state-error');
            return true;
        }

    };
    function submitReview(obj){
        var tags = options.tags;
        var item = options.item;
        var description = jQuery('[name=description]', obj);
        var anonymousName = "";
        if(options.allowAnonymous){
            if(options.defaultAnonymousName){
                anonymousName = options.defaultAnonymousName;
            }
        }
		if (name){
        	anonymousName = name.val();
		}
		var email_val = "";
		if (email){
			email_val = escape(email.val());
		}
		var auth_mthd;
        if(auth_sessions.twitter){
            auth_mthd = 'twitter';
        }
        if(auth_sessions.facebook){
            auth_mthd = 'facebook';
        }
        if(options.tagsEditable){
            if(tags.length>0)
                tags += ",";
            tags += jQuery('[name=tags]', obj).val();
        }
        if(options.itemEditable){
            item = jQuery('[name=item]', obj).val();
        }
        obj.rating_value = jQuery('.star-rating-control .star-rating-on', obj).length;
        var url = options.SERVER+"js/reviews/create/?callback=?"; //"?key="+options.key;
        jQuery("#lv-pleasewait").dialog('open');
        var params = {
            key: options.key,
            itemurl: escape(unescape(unescape(options.itemurl))), // haxor workaround
            ignore_slash: options.ignore_slash,
            item: escape(item),
            tags: escape(tags),
            rating: obj.rating_value,
            name: anonymousName,
            auth_method: auth_mthd,
            email: email_val,
            session_id: session_id,
            description: escape(jQuery('[name=description]', obj).val())
        };
        if(typeof(params.rating)=='undefined'){
            params.rating = 5;
        }
        jQuery.getJSON(url, params, function(data, status){
            obj.fetchReviews(options.offset, true);
            if(options.itemEditable) jQuery('[name=item]', obj).val("");
            if(options.tagsEditable) jQuery('[name=tags]', obj).val("");
            if(options.accordion) obj.accordion('activate', 0);
            if(data.status==200){
            	session_id = data.session_id;
            	checkSession();
                document.cookie = "sessionid="+data.session_id;
                showModal(obj, data.title, data.msg, "ui-icon-none");
                description.val("");
                jQuery('[name=tags]', obj).val("");
                jQuery('[name=item]', obj).val("");
                if(jQuery("[name=lv-post-to-twitter]", obj).attr('checked')||(getCookie('post_to_twitter')=="true")){
                    document.cookie = "post_to_twitter=false";
                    jQuery("#lv-pleasewait").dialog('open');
                    jQuery.getJSON( 
                        options.SERVER+"js/twitter/session/check/?callback=?",
                        {key: options.key, session_id: session_id}, 
                        function(data, status){
                            if(data.status==200){
                                jQuery.getJSON(
                                    options.SERVER +"js/twitter/update/?callback=?", 
                                    params, 
                                    function(data, status){
                                        if(data.status==200){
                                            jQuery( "#lv-pleasewait" ).dialog('close');
                                            showModal(obj, "Twitter status updated", data.msg, "ui-icon-none");
                                            auth_sessions.twitter = true;
                                        }   
                                });

                            }
                            else{
                                window.open(options.lv_receiver+"?popup=1&url="+escape("js/twitter/auth/?key="+options.key), "twitter", "height=400,width=900");
                                auth_sessions.twitter = false;
                            }
                        }
                    );
                }
                if(jQuery("[name=lv-post-to-facebook]", obj).attr('checked')||(getCookie('post_to_facebook')=="true")){
                    jQuery("#lv-pleasewait").dialog('open');
                    document.cookie = "post_to_facebook=false";
                    var desc = truncate(unescape(params.description), 120);
                    //var fb_feed = {
                    //    "item": item,
                    //    "itemurl": options.itemurl,
                    //    "description": desc,
                    //    "images": [{
                    //        "src": options.SERVER+"static/images/"+params.rating+"of5.png",
                    //        "href": unescape(params.itemurl)
                    //    }]
                    //};
                    
                    var attachment = {
                        'name': item,
                        'href': unescape(options.itemurl),
                        'description': desc,
                        'media': [{
    'type': 'image', 
    'src': options.SERVER+"static/images/"+params.rating+"of5.png",
    'href': unescape(params.itemurl)
                        }]
                    };
                    FB.Connect.streamPublish('I just wrote a review of this:', attachment, null, null, "My review of "+item, function(){
                        jQuery("#lv-pleasewait").dialog('close');
                    });
                    //FB_RequireFeatures(["Connect"], function(){
                    //    FB.Connect.requireSession(function(){
                    //        facebookLogin(obj, function(){
                    //            setTimeout(function(){ // FF hax
                    //                FB.Connect.showFeedDialog( 
                    //                    options.facebook.publish_template, 
                    //                    fb_feed,
                    //                    null, null, FB.FeedStorySize.shortStory
                    //                );
                    //            }, 0);
                    //            jQuery("#lv-pleasewait").dialog('close');
                    //        });
                    //    });
                    //});
                }
            }
            else if(data.status==401){
                checkSession();
                showModal(obj, data.title, data.msg, "ui-icon-alert");
            }
            else {
                showModal(obj, data.title, data.msg, "ui-icon-alert");
            }
            obj.fetchReviews(options.offset, true);
            jQuery("#lv-pleasewait").dialog('close');
        });
            
    };
    
    
    function loginSend(obj, callback){
        email = jQuery("#lv-login [name=email]");
        var password = jQuery("#lv-login [name=password]");
        if(!checkRegexp(email, re_email)) return false;
        if(!checkLength(password, 1, 100)) return false;
        var params = {
            email: email.val(),
            password: hex_md5( password.val() ),
            key: options.key
        };
        
        jQuery.getJSON(options.SERVER+"js/session/login/?callback=?", params, function(data, status){
            if(data.status==200){
                session_id = data.session_id;
                document.cookie = "sessionid="+data.session_id;
                closeModal(obj);
                submitReview(obj);
                checkSession();
                obj.fetchReviews(options.offset, true);
                if(typeof(callback)!='undefined'){
                    callback(obj);
                }
            }
            else{
                showModal(obj, data.title, data.msg, 'ui-icon-alert');
            }
        });
        return true;
        
    };
    
    function registerSend(obj, callback){
        email = jQuery("#lv-register [name=email]");
        name = jQuery("#lv-register [name=name]");
        // TODO: FaceBook Connect, OpenID, Orkut
        if(!checkRegexp(email, re_email) && !options.allowAnonymous) return false;
		if(!checkLength(name, 3, 100)) return false;
        if(options.allowAnonymous){
        	options.defaultAnonymousName = name.val();
        	submitReview(obj);
        	if(typeof(callback)!='undefined'){
                callback(obj);
            }
        	return true;
        }
        var params = {
            email: email.val(),
            name: name.val(),
            key: options.key
        };
        jQuery.getJSON(options.SERVER+"js/session/register/?callback=?", params, function(data, status){
            if(data.status==200){
                session_id = data.session_id;
                document.cookie = "sessionid="+data.session_id;
                submitReview(obj);
                checkSession();
                if(typeof(callback)!='undefined'){
                    callback(obj);
                }
            }
            else{
                obj.append("<div id='lvModal_upper' class='lv-modal' title='"+data.title+"'><p>"+data.msg+"</p></div>");
                jQuery('#lvModal_upper').dialog({
                     bgiframe:true,
                     modal:true,
                     buttons: {
                         Submit: function(){ 
                             loginSend(obj);
                         }
                     }
                });
            }
        });
        return true;
    };
    
    function facebookLogin(obj, callback){
        var api = FB.Facebook.apiClient;
        var session = api.get_session();
        session['API_KEY'] = api.get_apiKey();
        session['key'] = options.key;
        jQuery.getJSON(options.SERVER+"js/session/login/fb/?callback=?", session, function(data, status){
            if(data.status==200){
                session_id = data.session_id;
                document.cookie = "sessionid="+data.session_id;
                jQuery("#lv-login").dialog('close');
                jQuery("#lv-register").dialog('close');
                checkSession();
                auth_sessions.facebook = true;
                //showModal(obj, data.title, data.msg, "ui-icon-circle-check");
                obj.fetchReviews(options.offset, true);
                if(typeof(callback)!='undefined'){
                    callback(obj);
                }
            }
            else{
                showModal(obj, data.title, data.msg, 'ui-icon-alert');
            }
        });
    };

    
    function facebookSend(obj){
        var api = FB.Facebook.apiClient;
        var session = api.get_session();
        session['API_KEY'] = api.get_apiKey();
        session['key'] = options.key;
        jQuery.getJSON(options.SERVER+"js/session/login/fb/?callback=?", session, function(data, status){
            if(data.status==200){
                jQuery("#lv-login").dialog('close');
                jQuery("#lv-register").dialog('close'); 
                submitReview(obj);
                auth_sessions.facebook = true;
                //checkSession();
                
            }
            else{
                showModal(obj, data.title, data.msg, 'ui-icon-alert');
            }
            
        });
    };
    
    function checkFields(obj){
        var description = jQuery('[name=description]', obj);
        if(options.itemEditable && !checkLength(jQuery("[name=item]", obj) ) ) return false;
        
        if(!checkLength(description, 1, 2147483648)){
            showModal(obj, "Please enter review text", "Please write your review first.", "ui-icon-alert");
            return false;
        }
        if(!checkLength(description, 0, 3000)){
            showModal(obj, "Review long", "Your review is too long.<br/>Please try to keep it under 3000 characters.", "ui-icon-alert");
            return false;
        }
        return true;
    };
    
    function _addLogoutButton(obj)
    {
        jQuery(".lv-logout").click(function(){
            var params = {
                key: options.key,
                session_id: session_id
            };
            document.cookie = "sessionid=undefined";
            jQuery.getJSON(options.SERVER+"js/session/logout/?callback=?", params, function(){
                checkSession(function(){
                    obj.fetchReviews(options.offset, true);
                });
                
            });
            if(auth_sessions.facebook){
                FB_RequireFeatures(["Connect"], function(){
                    try{
                        if(FB.Connect.get_loggedInUser()){
                            FB.Connect.logout();
                            auth_sessions.facebook = false;
                        }
                    }
                    catch(err){
                    
                    }
                });
            }
            
            
        });
    };
    
    function _addFacebookLoginButton(obj){
        if(options.authMethods.facebook){
            jQuery('p.fb-title').show();
            jQuery('a.fb-login').show();
            jQuery('a.fb-login').click(function(){
                var msg = "Should we also send the review to your Facebook wall?";
                obj.append("<div id='lvModal_upper' class='lv-modal' title='Send to Facebook?'><p>"+msg+"</p></div>");
                jQuery('#lvModal_upper').dialog({
                     bgiframe:true, modal:true, 
                     buttons: {
                         No: function(){
                             document.cookie = "post_to_facebook=false";
                             jQuery(this).dialog('close');
                             jQuery(this).remove();
                             auth();
                         },
                         Yes: function(){
                             document.cookie = "post_to_facebook=true";
                             jQuery(this).dialog('close');
                             jQuery(this).remove();
                             auth();
                         }
                     }
                });
                function auth(){
                    FB_RequireFeatures(["Connect"], function(){
                        FB.Connect.requireSession(function(){
                            facebookLogin(obj, submitReview);
                        });
                    });
                };
            });
        }
    };
    
    function _addTwitterLoginButton(obj){
        if(options.authMethods.twitter){
            jQuery('p.twitter-title').show();
            jQuery('a.twitter-login').show();
            jQuery('a.twitter-login').click(function(){
                var msg = "Should we also send the review to your Twitter stream?";
                obj.append("<div id='lvModal_upper' class='lv-modal' title='Send to Twitter?'><p style='margin-left:10px'>"+msg+"</p></div>");
                jQuery('#lvModal_upper').dialog({
                     bgiframe:true, modal:true, 
                     buttons: {
                         No: function(){
                             document.cookie = "post_to_twitter=false";
                             jQuery(this).dialog('close');
                             jQuery(this).remove();
                             auth();
                         },
                         Yes: function(){
                             document.cookie = "post_to_twitter=true";
                             jQuery(this).dialog('close');
                             jQuery(this).remove();
                             auth();
                         }
                     }
                });
                function auth(){
                    window.open(
                        options.lv_receiver+"?popup=1&url="+escape("js/twitter/auth/?test=1&key="+options.key),
                        "twitter", "height=400,width=900");
                    };
            }); 
      }
    };
    
    function _addAuthButtons(obj){
        _addFacebookLoginButton(obj);
        _addTwitterLoginButton(obj);
        //_addLoginButton(obj);
        _addRegisterButton(obj);
        _addLogoutButton(obj);
    };
    function _whatIsLV(obj){
        jQuery('.lv-whatis').click(function(){
            showModal(obj, "About LouderVoice", aboutHTML, 'ui-icon-info');
        });
        jQuery('.lv-whatis-text').click(function(){
            showModal(obj, "About LouderVoice", aboutHTML, 'ui-icon-info');
        });
    };
    function _addRegisterButton(obj){
        jQuery(".lv-register-send", obj).click(function(){
            if(!checkFields(obj)) return;
            jQuery(document.body).append(registerHTML);
            _whatIsLV(obj);
            if(options.authMethods.loudervoice==false){
                jQuery('#lv-reg-form').hide();
            }
            if(options.allowAnonymous){
            	jQuery("[for=email]").text("Email");
            }
            _addFacebookLoginButton(obj);
            _addTwitterLoginButton(obj);
            jQuery("#lv-register").dialog({
                autoOpen: true,
                modal: true,
                close: function(){
                    jQuery(this).remove();
                },
                buttons: {
                    //Close: function(){ 
                    //    jQuery(this).dialog('close');
                    //},
                    Submit: function(){
                        if(registerSend(obj)){
                            jQuery(this).dialog('close');
                        }
                    }
                }
            }); 
        });
    };
    //function _addLoginButton(obj){
    //    jQuery(".lv-login-send", obj).click(function(){
    //        //if(!checkFields(obj)) return;
    //        jQuery(document.body).append(loginHTML);
    //        _whatIsLV(obj);
    //        
    //        jQuery("#lv-login").dialog({
    //            autoOpen: true,
    //            modal: true,
    //            close: function(){
    //                jQuery(this).remove();
    //            },
    //            buttons: {
    //                Close: function(){ 
    //                    jQuery(this).dialog('close');
    //                },
    //                Submit: function(){
    //                    if(login(obj)){
    //                        jQuery(this).dialog('close');
    //                    }
    //                    
    //                }
    //            }
    //        });
    //        if(options.authMethods.loudervoice==false){
    //            jQuery('#lv-log-form').hide();
    //        }
    //        _addFacebookLoginButton(obj); 
    //        _addTwitterLoginButton(obj);
    //    });
    //};
    
    function addWidget(obj){
        var useOtherAuths = options.authMethods.facebook || options.authMethods.openid || options.authMethods.gauth;
        if(options.readerOnly){
            obj.html(widgetAvgRating+widgetReadHTML);
        }
        else if(options.writerOnly){
            obj.html(widgetAvgRating+widgetWriteHTML);
        }
        else{
            obj.html(widgetAvgRating+widgetReadHTML+widgetWriteHTML);
        }
        _addAuthButtons(obj);
        jQuery('.lv-send', obj).click(function(){ // deprecated?
            if(!checkFields(obj)) return;
            submitReview(obj);
        }); 
        
        jQuery('.star', obj).rating({
            required:true, callback: function(value, link){
                obj.rating_value = value;
        }});
        
        // get the reviews
        obj.fetchReviews(options.offset);
        
        jQuery('.lv-button').hover(
            function(){ 
                jQuery(this).addClass("ui-state-hover"); 
            },
            function(){ 
                jQuery(this).removeClass("ui-state-hover"); 
            }
        );
        
        if(options.itemEditable){
            jQuery("[name=item]", obj).show();
            jQuery("[for=item]", obj).show();
        }
        if(options.tagsEditable){
            jQuery("[name=tags]", obj).show();
            jQuery("[for=tags]", obj).show();
        }
        //jQuery('.lv-whatis', obj).click(function(){
        //    showModal(obj, "What is LouderVoice", "LouderVoice is...", 'ui-icon-info');
        //});
        jQuery("[name=lv-post-to-twitter]", obj).click(function(){
            if(jQuery("[name=lv-post-to-twitter]", obj).attr('checked')){
                if(!auth_sessions.twitter){
                    window.open(
                                options.lv_receiver+"?popup=1&url="+escape("js/twitter/auth/?key="+options.key),
                                "twitter", "height=400,width=900");
                }
            }
        });
        obj.addClass("ui-accordion ui-widget ui-helper-reset");
        if (options.show_avg==true){
            var dest = jQuery('#avg_rating');
            if(typeof(dest.av_rating)!='undefined')
            dest.avg_rating({key:options.key, itemurl:options.itemurl, show_avg_min_count: options.show_avg_min_count})
            if(dest.html!=null){
                jQuery('#avg_rating').show();
            }
        }
    };
    
    function getCookie(c_name)
    {
    if (document.cookie.length>0)
      {
      c_start=document.cookie.indexOf(c_name + "=");
      if (c_start!=-1)
        {
        c_start=c_start + c_name.length+1;
        c_end=document.cookie.indexOf(";",c_start);
        if (c_end==-1) c_end=document.cookie.length;
        return unescape(document.cookie.substring(c_start,c_end));
        }
      }
    return "";
    };
    
    function checkSession(callback){
        var session_cookie = getCookie('sessionid');
        if(session_id==null && session_cookie!="" && session_cookie!="undefined"){
            session_id = session_cookie;
        }
        var params = {
            key: options.key,
            session_id: session_id
        };
        jQuery.getJSON(options.SERVER+"js/session/check/?callback=?", 
            params, 
            function(data, status){
                try{
                    session_user_id=parseInt(data.id, 10);
                }
                catch(err){
                    session_user_id=0;
                }
                if(data.loggedin){
                    jQuery(".lv-logged-out").hide();
                    session_id = data.session_id;
                    document.cookie = "sessionid="+data.session_id;
                    jQuery(".lv-send").show();
                    jQuery(".lv-login-send").hide();
                    jQuery(".lv-register-send").hide();
                    //if(!options.allowAnonymous)
                        jQuery(".lv-logout").show();
                    //else
                    //    jQuery(".lv-logout").hide();
                    jQuery("[name=name]").hide();
                    jQuery("[for=name]").hide();
                    auth_sessions.loudervoice = true;
                    if(options.authMethods.facebook && options.facebook.postToWall){
                        jQuery(".lv-also-post-to").show();
                        jQuery(".lv-facebook-enabled").show();
                    }
                    if(options.authMethods.twitter && options.twitter.postToTwitter){
                        jQuery(".lv-also-post-to").show();
                        jQuery(".lv-twitter-enabled").show();
                    }
          
                }
                else {
                    jQuery(".lv-logged-out").show();
                    session_id = null;
                    auth_sessions.loudervoice = false;
                    auth_sessions.facebook = false;
                    auth_sessions.twitter = false;
                    /*if(options.allowAnonymous){
                        jQuery(".lv-send").show();
                        jQuery("[name=name]").show();
                        jQuery("[for=name]").show();
                        jQuery(".lv-login-send").hide();
                        jQuery(".lv-register-send").hide();
                    }
                    else{*/
                        jQuery(".lv-send").hide();
                        jQuery(".lv-login-send").show();
                        jQuery(".lv-register-send").show(); 
                    //}
                    jQuery(".lv-logout").hide();
                    /*if(!options.allowAnonymous || options.defaultAnonymousName){
                        jQuery("[name=name]").hide();
                        jQuery("[for=name]").hide();
                    }*/
                    jQuery(".lv-also-post-to").hide(); 
                    
                }
                if(typeof(callback)!='undefined'){
                    callback();
                }
        });
    };
    
    function include_css(css_file) {
        var css;
        var html_doc = document.getElementsByTagName('head')[0];
        css = document.createElement('link');
        css.setAttribute('rel', 'stylesheet');
        css.setAttribute('type', 'text/css');
        css.setAttribute('href', css_file);
        html_doc.appendChild(css);
        return false;
    }

    jQuery.fn.extend({
        avg_rating: function(opt){

                var avg_defaults = {
                    SERVER: "http://api.loudervoice.com/",
                    itemurl: null,
                    key: null,
                    standalone: false,
                    show_avg_min_count: 0,
                    standalone_css: null
                };
                avg_options = jQuery.extend(avg_defaults, opt);
                var clas = '';
                if (avg_options.standalone==true){
                    clas = '-stand';
                    if(avg_options.standalone_css!=null){
                        for(var i=0;i<avg_options.standalone_css.length;i++){
                            include_css(avg_options.standalone_css[i]);
                        }
                    }else{
                        include_css("http://api.loudervoice.com/static/customers/default/css/avg_standalone.css");
                    }
                }
                return this.each(function(){
                    var obj = jQuery(this);
                    var params = {
                        key: avg_options.key,
                        itemurl: avg_options.itemurl
                    };
                    jQuery.getJSON(avg_options.SERVER+"graph_data/get_rating/?callback=?", params, function(data, status){
                        if(data.review_count>=avg_options.show_avg_min_count){
                            var html = "<div class='lv-average_rating"+clas+"'>";
                            var rating = parseInt(data.avg_rating+0.5, 10);
                            for(j=1; j<=5; j++)
                            {
                                if(j<=rating){
                                    html += "<div class='avg_rate"+clas+" lv-star-on'>&nbsp;</div>";
                                }else{
                                    html += "<div class='avg_rate"+clas+" lv-star-off'>&nbsp;</div>";
                                }
                            }
                            html += "<div id='exact_rate"+clas+"'> ("+data.avg_rating.toFixed(1)+"/5)</div>";
                            html += "<div id='rate_based_on"+clas+"'>Based on "+data.review_count+" reviews</div>";
                            html += '</div>';
                            html += '<br class="clear">';
                            obj.html(html);
                        }
                    });
                });
            },
        
        oauth_callback: function(source, data){
            if(source=="twitter" && typeof(data)!='undefined' && data.id){
                auth_sessions.twitter = true;
                document.cookie = "sessionid="+data.session_id;
                checkSession();
                var obj = jQuery(jQuery('.lv-review-description').parent().parent());
                
                obj.rating_value = jQuery('.star-rating-control .star-rating-on', obj).length;
                
                if(jQuery('[name=description]', obj).attr('value').length>0){
                    submitReview(obj);
                }
                jQuery("#lv-login").dialog('close');
                jQuery("#lv-register").dialog('close');
                //showModal(jQuery(document.body), "Logged in successfully", "You have successfully logged in. Please write your review and click Send", 'ui-icon-info');
            }
        },
         
        reviews: function(opt){
            var defaults = {
                SERVER: "http://api.loudervoice.com/",
                item: document.title,  // Default 'item' name
                itemEditable: false, // should the 'item' field be visible and editable?
                itemurl: window.location.href, // itemurl default
                itemurl_get: false,
                ignore_slash: false,
                tags: "", // default tags, these are being added to user specified tags
                tagsEditable: false, // should the tags input field be visible?
                authMethods: {facebook: false, openid: false, gauth: false, twitter: false, loudervoice: true}, // auth methods
                dynamicLimit: true,
                limit: 10, // how many reviews per page
                offset: 0, // starting offset
                autosize: false, // should the widget autosize to fit all reviews? (no scrollbars)
                clearOnPagination: true,
                activeTab:0,
                writerOnly: false,
                readerOnly: false,
                showitem: false,
                show_avg: false,
                show_avg_min_count: 0,
                defaultAnonymousName: null,
                allowAnonymous: false,
                animated: false,
                accordion: true,
                facebook: {
                    key: null,
                    channel: null,
                    postToWall: true,
                    publish_template: null // 119704093824
                },
                twitter: {
                    postToTwitter: true
                },
                style: {
                    star_on: "http://www.loudervoice.com/static/images/star_on.png",
                    star_off: "http://www.loudervoice.com/static/images/star_off.png"
                },
                css: [],
                key: null // API Key
            };
            options = jQuery.extend(defaults, opt);
            if(typeof(options.facebook.postToWall)=='undefined'){
                options.facebook.postToWall = true;
            }
            if(options.itemurl.indexOf("#")!=-1){
                options.itemurl = options.itemurl.substring(0, options.itemurl.indexOf("#"));                                
            }
            if(options.autosize) options.clearOnPagination = true;
            checkSession();
            for(i=0; i<options.css.length; i++){
                include_css(options.css[i]);
            }
            return this.each(function(){
                var obj = jQuery(this);
                obj.bind("ajaxError", function(){ 
                    showModal(obj, "Error", "Internal error occurred. Try to reload this page.", "ui-icon-alert");
                });
                
                if(options.authMethods.facebook && options.facebook.key &&     options.facebook.channel){
                    try{
                        FB_RequireFeatures(["Connect"], function(){ 
                            FB.Facebook.init(options.facebook.key, options.facebook.channel);
                            if(FB.Connect.get_loggedInUser())
                                facebookLogin(obj);
                        });
                    }
                    catch(err){
                        options.authMethods.facebook = false; //disable facebook
                    }
                }
                
                if(options.key==null){
                    obj.html("Please provide API Key.");
                    return;
                }
                addWidget(obj);
                
                jQuery(obj).append(waitHTML);
                jQuery("#lv-pleasewait").dialog({autoOpen: false});
                if(options.accordion){
                    if(options.autosize){
                        obj.accordion({
                            autoHeight:false, clearStyle:true, fillSpace:true, animated: options.animated});
                    } 
                    else{
                        obj.accordion({clearStyle:false, fillSpace:true, animated: options.animated});
                    }
                    if(!(options.readerOnly || options.writerOnly)){
                        obj.accordion('activate', options.activeTab);
                    }

                }
        });
        },
        fetchReviews: function(offset, clear){
            return this.each(function(){
                var obj = jQuery(this);
                if(options.itemurl_get != false){
                    item_url = options.itemurl_get;
                }else{
                    item_url = options.itemurl;
                }
                jQuery.getJSON(options.SERVER+"js/reviews/?key="+options.key+"&itemurl="+escape(item_url)+"&callback=?&offset="+offset+"&limit="+options.limit+'&slash='+options.ignore_slash, function(data){
                    if(data.count!=0){
                        jQuery(".count", obj).html("Read Reviews ("+data.count+")");
                    }else{
                        jQuery(".count", obj).html("No reviews yet. Why not write the first one?");
                    }
                    // avg rating
                    var star = "<div class='lv-average_rating'>";
                    var k;
                    var avg_round = data.avg.toFixed(1);
                    for(k=1;k<=5;k++){
                        if(k<=data.avg)
                            star += "<div class='avg_rate lv-star-on-neg'>&nbsp;</div>";
                        else
                            star += "<div class='avg_rate lv-star-off-neg'>&nbsp;</div>";
                    }
                    star += "&nbsp;("+avg_round+"/5) based on "+data.count+"&nbsp;review";
                    if (data.count!=1){
                        star  += 's';
                    }
                    star += '</div>';
                    if (options.show_avg==true&&data.count>=options.show_avg_min_count&&data.count>0){
                        jQuery('.lv-avg-stars', obj).html(star);
                    }
                    // /
                    if(data.count==0 && !(options.readerOnly || options.writerOnly) && options.accordion){
                        obj.accordion('activate', 1);
                    }
                    var elem = jQuery('.lv_reviews', obj);
                    jQuery(".lv-paginator", elem).remove();
                    if(options.clearOnPagination || clear)
                        elem.html("");
                    if(offset>0 && options.clearOnPagination){
                        elem.append("<div class='lv-paginator'><a href='javascript:void(0)' class='lv-paginator ui-corner-all ui-state-default lv-button lv-prev'>Previous "+options.limit+" reviews</a></div>");
                    }
                    for(i=0; i<data.results.length; i++){
                        var r = data.results[i]; 
                        var html = "<div class='ui-state-default ui-corner-all hreview' review_id_cont='"+r.pk+"'><span class='item'><span style='display:none;' class='fn'>"+options.item+"</span></span>"; //quick background fix
                        if(options.itemEditable){
                            html +=  "<p class='date-author-edit'><strong>"+r.fields.item+"</strong></p>";
                        }
                        else{
                            html += "";
                        }
                        html += "<p class='date-author-edit'>";
												if(r.fields.author.pk==session_user_id){
                            html += "<span class='ui-icon ui-icon-trash lv-right' review_id='"+r.pk+"'>Delete</span><span class='ui-icon ui-icon-document lv-right' review_id='"+r.pk+"' rating='"+r.fields.rating+"'>edit</span>";
                        }

			if(options.showitem==true){
                            html += "<span class='itemlink item'><a href='"+r.fields.itemurl+"' target='_blank' class='fn'>"+r.fields.item+"</a></span>";
                        }
                        create_array = r.fields.created.split(",");
                        html += "      by <strong class='reviewer vcard'><span class='fn'>"+unescape(r.extras.author_name)+"</span></strong> on <span><abbr class='dtreviewed' title='"+create_array[0]+"'>"+create_array[1]+"</abbr></span></p>";
                        html += "<div class='lv-review description' review_id='"+r.pk+"'>"+unescape(r.fields.description)+"</div>";
						html += "<span class='stars'><span class='rating' style='display: none;'>"+r.fields.rating+"</span>";
                        for(j=1; j<=5; j++)
                        {   
                            if(j<=r.fields.rating)
                                html += "<div class='lv-star-on star'>&nbsp;</div>";
                            else
                                html += "<div class='lv-star-off star'>&nbsp;</div>";
                        }
                        html += "</span><span class='version' style='display:none;'>0.3</span>";
                        if(r.fields.authenticated==true){
                            html += "<div style='float: right; width: 140px;'><a href='http://www.kwikchex.com/' target='_blank'><img src='"+options.SERVER+"static/images/kwikchex_widget.png'/></a</div>";
                        }
                        html += "</div>";
                        elem.append(html);
                    }
                    
                    // edit review
                    jQuery(".ui-icon-document[review_id]").click(function(){
                        var review_id = jQuery(this).attr("review_id");
                        var desc = jQuery("div[review_id="+review_id+"]");
                        var rating = parseInt(jQuery(this).attr('rating'), 10);
                        if(jQuery("div[review_id="+review_id+"] textarea").length>0){
                            return;
                        }
                        desc.html(desc.html().replace(/<br\/>/g, "\n"));
                        desc.html(desc.html().replace(/<BR\/>/g, "\n"));
                        desc.html(desc.html().replace(/<br>/g, "\n"));
                        desc.html(desc.html().replace(/<BR>/g, "\n"));
                        desc.html(desc.html().replace(/<p>/g, "\n\n").replace(/<\/p>/g, "\n\n"));
                        desc.html(desc.html().replace(/<P>/g, "\n\n").replace(/<\/P>/g, "\n\n"));
                        desc.html("<textarea class='lv-input'>"+desc.html()+"</textarea><br/><input type='button' value='save' class='lv-inline-edit-button lv-button'/>");
                        
                        var star = "";
                        for(k=1;k<=5;k++){
                            if(k==rating)
                                star += "<input type='radio' name='star' class='star' checked='checked' value='"+k+"'/>";
                            else
                                star += "<input type='radio' name='star' class='star' value='"+k+"'/>";
                        }
                        jQuery("[review_id_cont="+review_id+"] .stars").html(star);
                        jQuery('[review_id_cont='+review_id+'] .star').rating({
                            required:true, callback: function(value, link){
                                rating = value;
                        }});
                        
                        
                        jQuery("div[review_id="+review_id+"] input").click(function(){
                            var new_desc = jQuery("div[review_id="+review_id+"] textarea").val();
                            // add saving progress...
                            // todo: keep it DRY!
                            new_desc = new_desc.replace(/\n/g, "<br/>");
                            desc.html(new_desc);
                            star = "";
                            for(j=1; j<=5; j++)
                            {   
                                if(j<=rating)
                                    star += "<div class='lv-star-on star'>&nbsp;</div>";
                                else
                                    star += "<div class='lv-star-off star'>&nbsp;</div>";
                            }
                            jQuery("[review_id_cont="+review_id+"] .stars").html(star);
                            var params = {
                                id: review_id,
                                desc: escape(new_desc),
                                rating: rating
                            };
                            jQuery.getJSON(
                                options.SERVER + "js/reviews/edit/?callback=?",
                                params,
                                function(data, status){
                                    
                            });
                        });
                    });
                    // end of edit
                    
                    // delete review
                    jQuery(".ui-icon-trash[review_id]").click(function(){
                       var review_id = jQuery(this).attr("review_id");
                       var dialog = jQuery("<div id='lv-confirm-dialog' title='Delete?'><p>Are you sure you want to delete this review? This cannot be undone!</p></div>");
                       jQuery(obj).append(dialog);
                       jQuery(dialog).dialog({
                           buttons: {'Delete': function(){
                               jQuery.getJSON(
                                   options.SERVER+"js/reviews/delete/?callback=?", 
                                   {id: review_id}, 
                                   function(data, status){
                                        jQuery("[review_id_cont="+review_id+"].ui-state-default").addClass('ui-state-disabled');
                               }); 
                               jQuery(this).dialog('close');
                               jQuery(this).remove();
                           },
                           Cancel: function() {
                               jQuery(this).dialog('close');
                               jQuery(this).remove();
                           }
                       }});
                       
                       
                    });
                    // end of delete
                    
                    
                    if(offset+options.limit < data.count){
                        if((data.count-(offset+options.limit)) > options.limit)
                            elem.append("<div class='lv-paginator'><a href='javascript:void(0)' class='lv-paginator ui-corner-all ui-state-default lv-button lv-next'>Next "+options.limit+" reviews</a></div>");
                        else
                            elem.append("<div class='lv-paginator'><a href='javascript:void(0)' class='lv-paginator ui-corner-all ui-state-default lv-button lv-next'>Next "+(data.count-(offset+options.limit))+" reviews</a></div>");
                    }
                    jQuery('.lv-button').hover(
                        function(){ 
                            jQuery(this).addClass("ui-state-hover"); 
                        },
                        function(){ 
                            jQuery(this).removeClass("ui-state-hover"); 
                        }
                    
                    );
                    jQuery('.lv-next', obj).click(function(){
                        obj.fetchReviews(offset+options.limit, false);
                    });
                    jQuery('.lv-prev', obj).click(function(){
                        obj.fetchReviews(offset-options.limit, false);
                    });
                
                
                });  
            });
            
        }
    });
})(jQuery);
// End of LouderVoice JS API Widget
