/*
* File: ous.js
* Purpose: Provides functionality for the download detail page in catalog app
* 
* Last JSLint: 07/3/2009
* By: John Ware
* TODO: Finish jslinting, I resolved a lot, many more to go.

Functions:
iwin.
TODO: fillin
*/
/* JSLINT hinting */
/*global 
  Prototype, Element, Ajax, Event, $, i$, $F, $$, PeriodicalExecuter
  pageTracker, 
  hideObj, showObj, console, 
  window, location, document
  
  determine_direction */

if (!window.iwin) {
    var iwin = {};
}
var cache = null;

function awardTypesInit() {
    var hissImage = $$('.future_hiss_image')[0];
    if (Object.isElement(hissImage)) {
        hissImage.observe('click', function () {
            var elem, dir, element_position, element_dimensions, popup, popup_dimensions, 
                popup_fullwidth, popup_fullheight, adj_vert, adj_horz, popup_left, popup_top;
                
            console.debug('Show awards clicked');
            elem = this;
                
            if (typeof cache !== 'object' || cache.length === 0) {
                return;
            }
            // TODO: this kind of cross lib utilization is bad. Need to refactor
            // determine_direction is defined in Root scripts, game-popups.js
            dir = determine_direction(elem);
       
            element_position = elem.cumulativeOffset();
            element_dimensions = elem.getDimensions();
        
            popup = $('earnawards_popup');
            popup.className = '';
            popup.addClassName('popup_' + dir);
            popup_dimensions = popup.getDimensions();
            popup_fullwidth = popup_dimensions.width;
            popup_fullheight = popup_dimensions.height;
            

            adj_vert = 83;
            adj_horz = 0;
            
            switch (dir) {
            case 'ne':
                popup_left = (element_position.left - popup_fullwidth) + adj_horz;
                popup_top = (element_position.top + (element_dimensions.height / 2)) - adj_vert;
                break;
            case 'nw':
                popup_left = element_position.left + element_dimensions.width - adj_horz;
                popup_top = (element_position.top + (element_dimensions.height / 2)) - adj_vert;
                break;
            case 'se':
                popup_left = (element_position.left - popup_fullwidth) + adj_horz;
                popup_top = (element_position.top + (element_dimensions.height / 2)) - popup_fullheight + adj_vert;
                break;
            case 'sw':
                popup_left = element_position.left + element_dimensions.width - adj_horz;
                popup_top = (element_position.top + (element_dimensions.height / 2)) - popup_fullheight + adj_vert;
                break;
            }
            $('earnawards_popup').style.left = popup_left + 'px';
            $('earnawards_popup').style.top = popup_top + 'px';
            $('earnawards_popup').style.display = 'block';
        });
        
        $$('#earnawards_popup .close_button')[0].observe('click', function () {
            $('earnawards_popup').style.display = 'none';
        });
    } else {
        console.debug ('Initing HISS display failed with hissImage = %s', hissImage);
    }
}

function download_award_types_success(req) {
    console.debug('download_award_types AJAX success');
    
    var oddStyle, reqObj, gdata, elements, len, text,
        local, icon, name, type, difficulty, reward, difficultyText, difficultyTexts, i;
        
    gdata = req.responseXML;
    elements = gdata.getElementsByTagName('award-type');
    len = elements.length;  
    cache = [];
    text = [];
    
    for (i = 0; i < len; i = i + 1) {
        
        local = elements[i];
        icon = local.getAttribute('icon');
        name = local.getElementsByTagName('name')[0].firstChild.data;
        type = local.getElementsByTagName('type')[0].firstChild.data;
        difficulty = local.getElementsByTagName('difficulty')[0].firstChild.data;
        difficultyTexts = ['Simple', 'Pretty Easy', 'Medium', 'Difficult', 'Really Difficult'];
        difficultyText = difficultyTexts[difficulty - 1];
        reward = local.getElementsByTagName('opals-reward')[0].firstChild.data;
        
        // cache for reuse (TODO: not sure if we need to do this)
        cache.push({
            'icon' : icon,
            'name' : name,
            'type' : type,
            'difficulty' : difficulty,
            'opalsReward' : reward
        });
        // determine needed zebra striping on table
        if (i % 2 === 1) {
            oddStyle = ' class="trOdd"';
        } else {
            oddStyle = '';
        }
        // build a table row with all the data and correct classes
        text.push('<tr' + oddStyle + '>');
        text.push('<td class="tdIcon"><img src="' + icon + '" alt="' + name + '" /></td>');
        text.push('<td class="tdName">' + name + '</td>');
        text.push('<td class="tdDifficulty">' + difficultyText + '</td>');
        text.push('<td class="tdOpalsReward">' + reward + '</td>');
        text.push('</tr>');
    }

    // build and apply the final text
    text = '<table><thead><tr><th>&nbsp;</th><th>Name</th><th>Difficulty</th><th class="tdOpalsReward">Opals&nbsp;Reward</td></tr></thead>' + text.join('') + '</table>';
    $$('#earnawards_popup .table')[0].update(text);
    
    // if there were items to display, make the table visible
    if (len > 0) {
        console.debug('awards available so shot ribbon.');
        $$('div .future_hiss_image')[0].style.visibility = 'visible';
        $$('div .future_hiss_image')[0].style.display = 'block';
    } else {
        console.debug('no awards for this game.');
    }
}
function download_award_types() {
    console.debug('download_award_types entered');
    var oddStyle, reqObj, gdata, elements, len, text,
        local, icon, name, type, difficulty, reward, difficultyText, ajaxPathDomObj, ajaxPath;
       
    if (cache) {
        return;
    }
    cache = 'in progress';
    ajaxPath = '';
    ajaxPathDomObj = $('awardUrl');
    
    if (Object.isElement(ajaxPathDomObj)) {
        ajaxPath = ajaxPathDomObj.innerHTML;
        if (ajaxPath.length > 0) {
            reqObj = new  Ajax.Request(ajaxPath, {
                method: 'get',
                onSuccess: download_award_types_success,
                onFailure: function (req) {
                    console.error(req.status);
                    cache = null;
                }
            });
        } else {
            cache = null;
        }
    }
}
    
function activate_tab(obj, container) {
    var li, ul, liArray, i, containers, j;
    li = $(obj).up('li');
    ul = li.up('ul');
    liArray = ul.getElementsByTagName('li');
    
    for (i = 0; i < liArray.length; i = i + 1) {
        if (liArray[i].className === "selected") {
            $(liArray[i]).removeClassName('selected');
        }
    }
    // Hide/Show containers
    containers = $(container).parentNode;
    for (j = 0; j < containers.childNodes.length; j = j + 1) {
        if (containers.childNodes[j].nodeType === j) {
            containers.childNodes[j].style.display = 'none';
        }
    }
    $$('.tabbed_items').each(function (tabbed) {
        $(tabbed).childElements().each(function (item) {
            item.style.display = 'none';
        });
    });
    
    $(container).style.display = 'block';
    li.addClassName('selected');
}


function updateDdpDisplayForIcoins(hasIcoins) {
    // designed to be safe to call without knowing whether the action items area is on the page
    console.debug('updateDdpDisplayForIcoins called'); 
    
    var displayForNonICoinsUser, displayForICoinsUser, miniPromoDisplayForNonMember;
    // store the dom objects
    displayForNonICoinsUser = $('action_buy_button_container');
    displayForICoinsUser = $('action_buy_button_container_icoins');
    miniPromoDisplayForNonMember = $('miniPromoNonClub');
    
    // note hide/show is old school, hideObj/showObj is newer/preferred approach
    if (Object.isElement(displayForNonICoinsUser) &&
         Object.isElement(displayForICoinsUser)) {
        if (hasIcoins) {
            displayForNonICoinsUser.hide();
            iwin.Util.hideObj(miniPromoDisplayForNonMember);
            displayForICoinsUser.show();
        } else {
            displayForNonICoinsUser.show();
            iwin.Util.showObj(miniPromoDisplayForNonMember);
            displayForICoinsUser.hide();
        }
    } 
    else {
        console.debug('updateDdpDisplayForIcoins no objects to update');
    }
}

function updateDdpForUser(haveUser) {
    // designed to be safe to call without knowing whether the action items area is on the page
    console.debug('start updateDdpForUser');
    
    var displayForNonUser, displayForUser;
    
    // store the dom objects
    displayForNonUser = $('action_buy_button_container_nonuser');
    displayForUser = $('action_buy_button_container_user'); // only there for ones that matter
    
    if (Object.isElement(displayForNonUser) &&
         Object.isElement(displayForUser)) {
        if (haveUser) {
            displayForNonUser.hide();
            displayForUser.show();
        } else {
            displayForNonUser.show();
            displayForUser.hide();
        }
    } 
    else {
        console.debug('updateDdpForUser no objects to update');
    }
}


function updateDdpForIcoins() {
    console.debug('start updateDdpForIcoins() with .json');
    var resource, reqObj;
    resource = '/icoins/account/summary.json';
    /* It will return a 404 if not found , 401 if not logged in and 200 if found
       however if account is found but has zero balance it will still show 200. */
    reqObj = new Ajax.Request(resource, {
            method: 'GET',
            requestHeaders: {'Accept': 'application/json'},
            onException: function (req, e) {
                console.error("updateForIcoins caused an error: %s", e);
                updateDdpDisplayForIcoins(false);
            },
            onSuccess: function (req) {
                updateDdpDisplayForIcoins(true);
            },
            onFailure: function (req) {
                console.debug('updateDdpForIcoins determined no icoins user with status: %s', req.status);
                updateDdpDisplayForIcoins(false);
            }
        }); 
    console.debug('end updateDdpForIcoins()');
}


function cut_after_word(input, num) {
    var ret, punct, count;
    if (input.length <= num) {
        return input;
    }
    ret = input.substr(0, input.indexOf(' ', num));
    punct = '.,:;!?'.split('');
    count = 0;
    while (punct.include(ret.substr(ret.length - 1))) {
        ret = ret.substr(0, ret.length - 1);
        if (count++ > 6) {
            break;
        }
    }
    return ret;
}

function get_suggested_games() {
    var reqObj, games, this_game_url, container, num_inserted,
        game, url, title, img_src, game_node, a_img, img, a_text;
    
    reqObj = new Ajax.Request('/categories/games.xml?m=5', {
        method: 'get',
        onSuccess: function (req) {
            games = req.responseXML.getElementsByTagName('game');
            setTimeout(function () {
                this_game_url = window.location.href;
                container = $('popular_games_content');
                num_inserted = 0;
                for (var i = 0; i < games.length; i++) {
                    game = games[i];
                    url = game.getAttribute('self');
                    if (url === this_game_url) {
                        continue;
                    }
                    
                    title = game.getElementsByTagName('title')[0].firstChild.data;                    
                    img_src = game.getElementsByTagName('images-url')[0].firstChild.data + '/feat_2.jpg';
                    
                    game_node = new Element('div', {'class': 'game'});
                    container.insert(game_node);
                    
                    a_img = new Element('a', {'href': url, 'class': 'poppable'});
                    game_node.insert(a_img);
                    img = new Element('img', {'src': img_src,
                                                  'alt': 'Box Art',
                                                  'width': '150',
                                                  'height': '100'});
                    a_img.insert(img);
                                              
                    game_node.insert(new Element('br'));
                    
                    a_text = new Element('a', {'href': url, 'class': 'poppable'});
                    game_node.insert(a_text);
                    a_text.update(title);

                    if (++num_inserted >= 4) { 
                        break;
                    }
                }
                $$('.poppable').each(function (elem) {
                    make_poppable(elem, 750);
                });
                $('popular_games').style.display = 'block';
            }, 0);
        },
        onFailure: function (req) {
            console.error('Failed to get popular games listing: %s %s', req.status, req.statusText);
        }
    });
}


function populate_review_header(reviewData) {
    var sum, num_reviews, overall, graphics, sound, gameplay, small_star_width, big_star_width;
    
    big_star_width = 115;    
    small_star_width = 80;
    //$('review_form_link').href = reviewData.getElementsByTagName('reviews')[0].getAttribute('review-form-url');
    
    sum = reviewData.getElementsByTagName('summary')[0];
    num_reviews = sum.getElementsByTagName('total-reviews')[0].firstChild.data;
    overall = sum.getElementsByTagName('overall')[0].firstChild.data;
    graphics = sum.getElementsByTagName('graphics')[0].firstChild.data;
    sound = sum.getElementsByTagName('sound')[0].firstChild.data;
    gameplay = sum.getElementsByTagName('gameplay')[0].firstChild.data;
    
    $('game_num_reviews').innerHTML = num_reviews;
    if (num_reviews === '0') {
        $('all_reviews_link').innerHTML = '';
        $('rating_breakdowns').innerHTML = '';
    } else {
        /* pining these to half star values to make it look a bit better */
        $('game_graphics_rating').style.width = parseInt(((small_star_width * Math.round(graphics / 10)) / 10), 10) + 'px';
        $('game_sound_rating').style.width = parseInt(((small_star_width * Math.round(sound / 10)) / 10), 10) + 'px';
        $('game_gameplay_rating').style.width = parseInt(((small_star_width * Math.round(gameplay / 10)) / 10), 10) + 'px';      
    }

    $('game_overall_rating').style.width = parseInt(((big_star_width * Math.round(overall / 10)) / 10), 10) + 'px';
}

function populate_reviews(reviewData) {
    var revs, self_url, username, small_star_width, avatar_url, review_date, upvotes,
        downvotes, review_text, total_reviews, user_rated, user_owner, ratings, overall, graphics, sound, gameplay, total_votes, r_body;
    
    small_star_width = 80;
    
    revs = reviewData.getElementsByTagName('user-review');
    for (var i = 0; i < revs.length; i++) {
        self_url = revs[i].getElementsByTagName('feedback-url')[0].firstChild.data;
        //self_url = revs[i].getAttribute('self');
        username = 'Anonymous';
        if (revs[i].getElementsByTagName('username')[0])
        {
            username = revs[i].getElementsByTagName('username')[0].firstChild.data;
        }
        avatar_url = '/avatar?method=view&username=default&background=true';
        if (revs[i].getElementsByTagName('avatar-url')[0])
        {
            avatar_url = revs[i].getElementsByTagName('avatar-url')[0].firstChild.data;
        }
        review_date = revs[i].getElementsByTagName('reviewed-date')[0].firstChild.data;
        upvotes = revs[i].getElementsByTagName('helpful-views')[0].firstChild.data;
        upvotes *= 1;
        downvotes = revs[i].getElementsByTagName('unhelpful-views')[0].firstChild.data;
        downvotes *= 1;
        review_text = revs[i].getElementsByTagName('comments')[0].firstChild.data;
        total_reviews = revs[i].getElementsByTagName('user-reviews-count')[0].firstChild.data;
        ratings = revs[i].getElementsByTagName('ratings')[0];

        user_rated = revs[i].getElementsByTagName('user-rated')[0].firstChild.data == 'true';
        user_owner = revs[i].getElementsByTagName('user-owner')[0].firstChild.data == 'true';
        
        overall = ratings.getElementsByTagName('overall')[0].firstChild.data;
        graphics = ratings.getElementsByTagName('graphics')[0].firstChild.data;
        sound = ratings.getElementsByTagName('sound')[0].firstChild.data;
        gameplay = ratings.getElementsByTagName('gameplay')[0].firstChild.data;
        
        total_votes = upvotes + downvotes;
        
        r_body = $('reviews_body');
        var p_rev, s_url, a_area, a_img, r_text, line1, uname, rdate, sp;
        p_rev = r_body.appendChild(document.createElement('div'));
        p_rev.className = 'player_review clearfix';
        s_url = p_rev.appendChild(document.createElement('div'));
        s_url.className = 'review_self_url hideObj';
        s_url.innerHTML = self_url;
        a_area = p_rev.appendChild(document.createElement('div'));
        if (username === 'Anonymous') {
            a_area = p_rev.appendChild(document.createElement('div'));
        } else {
            a_area = p_rev.appendChild(document.createElement('a'));
            a_area.href = '/hotel?room=' + username + '/top';
        }

        a_area.className = 'avatar_area';
        a_img = a_area.appendChild(document.createElement('img'));
        a_img.src = avatar_url;
        a_img.height = 48;
        a_img.width = 48;
 
		  a_img.onerror = function(){
			   this.onerror=null; 
				this.src='http://cimg.iwin.com/images/avatars/misc/noimage_48.png';
		  }
		  
        //a_img.alt = 'No Avatar';
        var maxNameLenght = 7;
        
        if (username === 'Anonymous') {
            a_img.alt = 'No Avatar';
        } else if (username.length > maxNameLenght) {
            a_img.alt = username.substr(0,maxNameLenght-2)+'..';
        } else {
            a_img.alt = username;
        }
		  
        var t_reviews = a_area.appendChild(document.createElement('span'));
        t_reviews.innerHTML = ' &#160;' + total_reviews + (total_reviews > 1 ? ' reviews' : ' review');
        t_reviews.className = 'total_reviews';

        a_img.className = 'avatar';
        r_text = p_rev.appendChild(document.createElement('div'));
        r_text.className = 'review_text';
        //line1 = r_text.appendChild(document.createElement('div'));
        //line1.className = 'review_first_line';

        var uname;
        if (username === 'Anonymous') {
            uname = r_text.appendChild(document.createElement('span'));
        } else {
            uname = r_text.appendChild(document.createElement('a'));
            uname.href = '/hotel?room=' + username + '/top';
        }

        //uname = line1.appendChild(document.createElement('span'));
        uname.className = 'username';
        uname.innerHTML = username;
        //rdate = line1.appendChild(document.createElement('span'));
        rdate = r_text.appendChild(document.createElement('span'));
        rdate.className = 'review_date';
        rdate.innerHTML = review_date.replace(/^(\d+)-(\d+)-(\d+).*$/, '$2-$3-$1'); 
        //sp = line1.appendChild(document.createElement('div'));
        //sp.className = 'spacer';
        //sp.innerHTML = '&#160;';
        
        //var h_com = r_text.appendChild(document.createElement('span'));
        var h_com = r_text.appendChild(document.createElement('div'));
        h_com.className = 'hidden_comment';
        h_com.innerHTML = review_text;
        //var d_com = r_text.appendChild(document.createElement('span'));
        var d_com = r_text.appendChild(document.createElement('div'));
        d_com.className = 'displayed_comment';
        d_com.innerHTML = '&#160;';
        
        var para = r_text.appendChild(document.createElement('p'));
        var toggle = para.appendChild(document.createElement('a'));
        toggle.href = "?init=show_review_" + username;
        toggle.className = 'toggle_player_review';
        toggle.innerHTML = 'Loading review...';
        Event.observe(toggle, 'click', function(event) {
            toggle_player_review(event.element());
            Event.stop(event);
        });
        
        var w_help = r_text.appendChild(document.createElement('div'));
        w_help.className = 'was_helpful';
        var s_up = w_help.appendChild(document.createElement('span'));
        s_up.className = 'upvotes';
        s_up.innerHTML = upvotes;
        w_help.innerHTML += ' out of ';
        var s_tot = w_help.appendChild(document.createElement('span'));
        s_tot.className = 'total';
        s_tot.innerHTML = total_votes;
        w_help.innerHTML += " found this review helpful<br />\n";
        var v_links = w_help.appendChild(document.createElement('span'));
        v_links.className = 'vote_links';
        //v_links.innerHTML = 'Was it helpful to you? <a href="?init=vote_yes_' + username + '" onclick="record_vote(this, 1); return false;">Yes</a> | <a href="?init=vote_no_' + username + '" onclick="record_vote(this, 0); return false;">No</a>';
        if (user_rated){
            v_links.innerHTML =  'You have rated this review.';
        } else if (user_owner){
            v_links.innerHTML =  'This is your review.';
        } else {
            v_links.innerHTML = 'Was it helpful to you? <a href="?init=vote_yes_'+username+
                '" onclick="iwin.userReviews.recordVote(this, 1); return false;">Yes</a> | <a href="?init=vote_no_'+username+
                '" onclick="iwin.userReviews.recordVote(this, 0); return false;">No</a>';
        }
        
        var r_star = p_rev.appendChild(document.createElement('div'));
        r_star.className = 'review_stars';
        ['Overall:', 'Graphics:', 'Sound:', 'Gameplay:'].each(function (cat_name) {
            var cat_var, row, item, s, rating, rtg;
            cat_var = cat_name.toLowerCase().replace(/[^a-z]/g, '');
            row = r_star.appendChild(document.createElement('div'));
            row.className = 'row';
            //item = row.appendChild(document.createElement('span'));
            //item.className = 'item';
            if (cat_name === 'Overall:') { /* only the first item to be bold */
                s = row.appendChild(document.createElement('strong'));
            } else {
                s = row.appendChild(document.createElement('span'));
            }
            s.innerHTML = cat_name;
            //rating = row.appendChild(document.createElement('span'));
            //rating.className = 'rating';
            //rtg = rating.appendChild(document.createElement('div'));
            //rtg.className = 'stars_small';
            rtg = row.appendChild(document.createElement('div'));
            if (cat_name == 'Overall:') { 
                rtg.className = 'stars_orange';
            } else {
                rtg.className = 'stars_bright_orange';
            }

            rtg.innerHTML = '&#160;';
            rtg.style.width = parseInt(((small_star_width * eval(cat_var)) / 100), 10) + 'px';
            //sp = row.appendChild(document.createElement('div'));
            //sp.className = 'spacer';
            //sp.height = 4;
            //sp.innerHTML = '&#160;';
        });

        //sp = p_rev.appendChild(document.createElement('div'));
        //sp.className = 'spacer';
        //sp.height = 4;
        //sp.innerHTML = '&#160;';
    }
}

function init_review_messages() {
   var msgCtrl = null;
   for (var r = 1; true; r++) {
      msgCtrl = $("toggle_player_review" + r);
      if (msgCtrl == undefined) break;
      Event.observe(msgCtrl, 'click', function(event){
          toggle_player_review(event.element());
          Event.stop(event);
      });
   }
   setTimeout(function(){
      for (var r = 1; true; r++) {
          var msgCtrl = $("toggle_player_review" + r);
          if (msgCtrl == undefined) break;
          toggle_player_review(msgCtrl);
      }
   }, 0);
}

function init_user_reviews() {
    console.debug('init_user_reviews entered');
    var reviews_url, reqObj, reviewData, reviews;
    reviews_url = $('all_reviews_link').href;
    reqObj = new Ajax.Request(reviews_url + '.xml', {
        method: 'get',
        onSuccess: function (req) {
            reviewData = req.responseXML;
            setTimeout(function () {
                populate_review_header(reviewData);
                populate_reviews(reviewData);
                reviews = $('reviews_body').getElementsByClassName('toggle_player_review');
                for (var r = 0; r < reviews.length; r++) {
                    toggle_player_review(reviews[r]);
                }
            }, 0);
        },
        onFailure: function (req) {
            console.error('Request to %s failed! Received: %s %s', $('secret_reviews_url').innerHTML, req.status, req.statusText);
        }
    });
}

function last_n(str, num) {
    if (num === null) {
        num = 32;
    }
    if (str.length < num) {
        return str;
    } else {
        return '...' + str.substr(str.length - num);
    }
}

// These constants should match the widths of the 5-star images.

function position_screenshot() {
    // Note: used to have optional arg for "display debugging info"
    
    var div_size, browser_width, browser_height, screenshot_div, screenshot_img, scroll_height,
        big_star_width;
    
    big_star_width = 115;
    browser_width = (window.innerWidth) ?
            window.innerWidth :
            (document.body && document.body.offsetWidth) ?
                    document.body.offsetWidth :
                    false;
    browser_height = (window.innerHeight) ?
            window.innerHeight :
            (document.documentElement && document.documentElement.clientHeight) ?
                    document.documentElement.clientHeight :
                    (document.body && document.body.offsetHeight) ?
                            document.body.offsetHeight :
                            false;
    screenshot_div = $('screenshot_popup');
    screenshot_img = $('popup_image');
    if (window.div_width === undefined || window.div_width < 10) {
        div_size = screenshot_div.getDimensions();
        window.div_width = div_size.width;
        window.div_height = div_size.height;
    }
    scroll_height = 0;
    if (window.scrollY) {
        scroll_height = window.scrollY;
    } else if (document.documentElement.scrollTop) {
        scroll_height = document.documentElement.scrollTop;
    } else if (document.body.scrollTop) {
        scroll_height = document.body.scrollTop;
    }
    screenshot_div.style.left = ((browser_width  / 2) - (window.div_width  / 2)) + 'px';
    screenshot_div.style.top  = ((browser_height / 2) - (window.div_height / 2)) + scroll_height + 'px';
}

function record_vote(elem, vote) {
    // Records a vote as useful if param 2 is nonzero; non-useful if zero.
    // The logic is a Boolean: "Was it useful?"

    var node, self_url, fb, params, was_helpful, upvotes, total, vote_links;
    
    node = elem;
    while (node.tagName.toUpperCase() !== 'BODY' && node.className !== 'player_review') {
        node = node.parentNode;
    }
    node = node.getElementsByClassName('review_self_url')[0];
    
    self_url = node.innerHTML.replace(/\/$/, '') + '/feedback';
    fb = (vote) ? 'positive' : 'negative';
    params = { 'feedback': fb };
    new Ajax.Request(self_url, {
        method: 'POST',
        parameters: params,
        onSuccess: function (req) {
            was_helpful = $(elem).up('.was_helpful');
            upvotes = (was_helpful.getElementsByClassName('upvotes'))[0];
            total = (was_helpful.getElementsByClassName('total'))[0];
            vote_links = (was_helpful.getElementsByClassName('vote_links'))[0];
            if (vote) {
                upvotes.innerHTML = parseInt(upvotes.innerHTML) + 1;
            }
            total.innerHTML = parseInt(total.innerHTML) + 1;
            vote_links.innerHTML = 'Thank you for rating this review.';
        },
        on401: function (req) {
            //signin_show(elem, load_session_data, );
            
            AuthUI.Login.show(elem, "You have to log in before you can rate another user's review.");
        },
        onFailure: function (req) {
            alert("I'm sorry, there was an error trying to record your vote. The server said:\n\n" + req.status + " " + req.statusText + "\n\n" + req.responseText.replace(/\<(p|div)\>/gi, "\n\n").replace(/\<br\>/gi, "\n").stripTags());
        }
    });
}

function show_screenshot(num, screen_path) {
    var screenshot_div, screenshot_img;

    position_screenshot();
    screenshot_div = $('screenshot_popup');
    screenshot_img = $('popup_image');
    screenshot_img.src = screen_path;
    set_screenshot_alt_text(num);
    screenshot_div.style.display='block';
    $$('#popup_window_controls a').invoke('removeClassName','active');
    $$('#popup_window_controls a')[4-num].addClassName('active');
    return false;
}
function show_screenshot_by_num(num) {
    var screenshot_img, old_src, new_src;
    /* only called once the first image has been loaded, so just swap the number in the path */
    //var img_src = (elem.getElementsByTagName('img'))[0].src;
    screenshot_img = $('popup_image');
    old_src = screenshot_img.src; // "screen_" + num + ".jpg";
    new_src = old_src.replace(/\d\.(gif|jpe?g|png)$/i, num + ".$1");
    screenshot_img.src = new_src;
    set_screenshot_alt_text(num);
    $$('#popup_window_controls a').invoke('removeClassName','active');
    $$('#popup_window_controls a')[4-num].addClassName('active');
    return false;
}
function set_screenshot_alt_text(num) {
    var screenshot_img = $('popup_image');
    switch(num) {
        case 1:
          screenshot_img.writeAttribute('alt', 'Screen One');
          break;    
        case 2:
          screenshot_img.writeAttribute('alt', 'Screen Two');
          break;
        case 3:
          screenshot_img.writeAttribute('alt', 'Screen Three');
          break;
        default:
          screenshot_img.writeAttribute('alt', 'Screen Shot'); // default/error case to something reasonable
    }
}

function hide_screenshot() {
    $$('#popup_window_controls a').invoke('removeClassName','active');
    $('screenshot_popup').style.display = 'none';
}

function toggle_player_review(elem) {
    var short_display_chars, collapsed_link_text, expanded_link_text, trigger;
    
    short_display_chars = 190;
    collapsed_link_text = 'Show Full Review';
    expanded_link_text  = 'Show Only First 3 Lines';
    trigger = new RegExp(collapsed_link_text.substr(3), "i");
    
    if (typeof elem !== 'object' ) return;
    
    if (! elem.hasClassName('review_text')) {
        elem = elem.up('.review_text');
    }
    var full_text = elem.down('.hidden_comment').innerHTML.replace(/\n\s*\n/g, "<br />\n<br />\n");
    var displayed = elem.down('.displayed_comment');
    var toggle = elem.down('.toggle_player_review');
    if (toggle.innerHTML.search(trigger) > 0) {
        displayed.innerHTML = full_text;
        toggle.innerHTML = expanded_link_text;
    } else {
        if (full_text.length < (short_display_chars + collapsed_link_text.length)) {
            displayed.innerHTML = full_text;
            toggle.innerHTML = '';
        } else {
            displayed.innerHTML = cut_after_word(full_text, short_display_chars) + '...';
            toggle.innerHTML = collapsed_link_text;
        }
    }
}

function _promoInTabSwitch() {
    // relies on cookie_crd.js or equiv.
    // if the cookie is there, show one result, else, set the cookie and show another result.
    if (readCookie("iWinVisitedDdp")) {
        promoDiv = $('promo_in_tab_icoins');  
        if (promoDiv) {
            promoDiv.show();
        }
        else {
            console.debug('_dynamicReuseOfSystemReqs promoDiv is null, promo_in_tab_icoins missing');
        }
    }
    else {
        createCookie("iWinVisitedDdp", "bonusFeatureEnabled", 120);
        promoDiv = $('promo_in_tab_shield');
        if (promoDiv) {
            promoDiv.show();
        }
        else {
            console.debug('_dynamicReuseOfSystemReqs promoDiv is null, promo_in_tab_shield missing');
        }        
    }
}

// use object literal to initialize the effects object
if (!window.iwin) {
    var iwin = {};
}
if (!iwin.experiment) {
    iwin.experiment = {};
}
iwin.experiment.effects = {
    counter: 0,
    idStr: 'egg',
    graphic: '/catalog/images/download_detail/egg.gif',
    payoutIdStr: 'bunny',
    payoutGraphic: '/catalog/images/download_detail/bunny.gif',
    on: 0,
    stepNum: 0,
    fadeTarget: 0,
    fadeIncrement: 0.01,
    fade: 0,
    awarded: 0,
    awardTxt: 'Keep clicking to win!',
    boxWidth: 0,
    boxHeight: 0
};

iwin.experiment.effects.initTimeout = function () {
    // console.debug('initTimeout');
    var minDelay = 3000;
    var variance = 4000;
    var delay = Math.ceil(Math.random() * variance) + minDelay;
    iwin.experiment.effects.timeout = window.setTimeout('iwin.experiment.effects.blink()', delay);
};

iwin.experiment.effects.init = function () {
    // only called after dom is done loading
    console.debug('effects initialization');
    
    // adjust box height to fill the viewport
    iwin.experiment.effects.boxWidth = document.viewport.getHeight();
    iwin.experiment.effects.boxHeight = document.viewport.getWidth();
    
    // dynamically construct the effect div and add it to the dom
    var newDiv = new Element('div', {style: 'position:absolute; top:40px; left:40px; z-index:101;', id: (iwin.experiment.effects.idStr).toString()});
    Element.extend(document.body);
    newDiv.update('<img src="'+iwin.experiment.effects.graphic+'" alt="Click to play!"/>');
    newDiv.setOpacity(0);
    console.debug(newDiv);
    document.body.insert({bottom: newDiv}); 
    newDiv.hide();
    
    var effectsDiv = $(iwin.experiment.effects.idStr);
    // todo: add guarding for non-existing div
    effectsDiv.absolutize();
    effectsDiv.observe('click', iwin.experiment.effects.payout);
       
    // dynamically construct the payout div and add it to the dom
    var newDiv2 = new Element('div', {style: 'position:absolute; top:40px; left:40px; z-index:102;', id: (iwin.experiment.effects.payoutIdStr).toString()});
    Element.extend(document.body);
    newDiv2.update('<img src="'+iwin.experiment.effects.payoutGraphic+'" alt="The bunny is out."/>');
    newDiv2.setOpacity(0);
    console.debug(newDiv2);
    document.body.insert({bottom: newDiv2}); 
    newDiv2.hide();
    
    var payoutDiv = $(iwin.experiment.effects.payoutIdStr);
    // todo: add guarding for non-existing div
    payoutDiv.absolutize();
    payoutDiv.observe('click', function () {payoutDiv.hide();});
      
    iwin.experiment.effects.initTimeout();
};

iwin.experiment.effects.payout = function () {
    console.debug('payout');
    var payoutDiv = $(iwin.experiment.effects.payoutIdStr);
    var effectsDiv = $(iwin.experiment.effects.idStr);
    // todo: add guarding for non-existing divs
    
    payoutDiv.style.top = effectsDiv.style.top;
    payoutDiv.style.left = effectsDiv.style.left;
    payoutDiv.setOpacity(1);
    payoutDiv.show();
};

iwin.experiment.effects.blink = function () {
    // console.debug('blinking, count = %s', iwin.experiment.effects.counter);
    iwin.experiment.effects.counter = iwin.experiment.effects.counter + 1;

    // stop after awhile
    if (iwin.experiment.effects.counter < 20) {
        iwin.experiment.effects.initTimeout();
    } else {
        // done playing, what have you won
        // alert(iwin.experiment.effects.awardTxt);
    }

    var effectsDiv = $(iwin.experiment.effects.idStr);
    // todo: add guarding for non-existing div
    if (effectsDiv) {
        if (iwin.experiment.effects.on === 1) {
            // end fadein if not already over
            window.clearTimeout(this.timeout2);
            
            // setup for fade out
            iwin.experiment.effects.on = 0;
            iwin.experiment.effects.fadeTarget = 0;
            this.timeout2 = window.setTimeout('iwin.experiment.effects.blink.fade(-1)', 0.1);
        } else {
            // turn on and randomly position
            iwin.experiment.effects.on = 1;
            iwin.experiment.effects.fadeTarget = Math.random();

            // position
            var top = Math.ceil(Math.random() * iwin.experiment.effects.boxWidth);
            var left = Math.ceil(Math.random() * iwin.experiment.effects.boxHeight);
            effectsDiv.style.top = top + 'px';
            effectsDiv.style.left = left + 'px';

            // hide the payout
            var payoutDiv = $(iwin.experiment.effects.payoutIdStr);
            payoutDiv.hide();
    
            // fade in
            this.timeout2 = window.setTimeout('iwin.experiment.effects.blink.fade(1)', 0.1);
            effectsDiv.setOpacity(iwin.experiment.effects.fade);
            effectsDiv.show();
        }
    }
};

            
            
iwin.experiment.effects.blink.fade = function (direction) {
    var effectsDiv = $(iwin.experiment.effects.idStr);
    if (effectsDiv) {
        if (direction === 1) {
            // fadein
            if (iwin.experiment.effects.fadeTarget > iwin.experiment.effects.fade) {
                iwin.experiment.effects.stepNum = iwin.experiment.effects.stepNum + 1;
    
                // setup next step
                this.timeout2 = window.setTimeout('iwin.experiment.effects.blink.fade(1)', 0.1);
    
                // fade
                iwin.experiment.effects.fade = iwin.experiment.effects.fade + iwin.experiment.effects.fadeIncrement;
                effectsDiv.setOpacity(iwin.experiment.effects.fade);
    
                // console.debug('fading in' + iwin.experiment.effects.fade + ' ' + iwin.experiment.effects.stepNum);
            }
        } else {
            // assume fadeout
            if (iwin.experiment.effects.fadeTarget < iwin.experiment.effects.fade) {
                iwin.experiment.effects.stepNum = iwin.experiment.effects.stepNum + 1;
    
                // setup next step
                this.timeout2 = window.setTimeout('iwin.experiment.effects.blink.fade(-1)', 0.1);
    
                // fade
                iwin.experiment.effects.fade = iwin.experiment.effects.fade - iwin.experiment.effects.fadeIncrement;
                effectsDiv.setOpacity(iwin.experiment.effects.fade);
    
                // console.debug('fading out' + iwin.experiment.effects.fade + ' ' + iwin.experiment.effects.stepNum);
            } else {
                // done fading out, turn off and reset
                effectsDiv.hide();
                iwin.experiment.effects.stepNum = 0;
            }
        }
    }
};


function DdpInit() {
    console.debug('DDP initialization');
    
    // setup icoins pricing display dynamic updates
    Event.observe(document, 'iwin:auth:login:success', updateDdpForIcoins);
    Event.observe(document, 'iwin:auth:logout:success', function () {
        updateDdpDisplayForIcoins(false); // force to don't have icoins
    });
    updateDdpForIcoins();
    
    // setup tracking user logged in state for games with buy behavior that changed based on this (online party)
    Event.observe(document, 'iwin:auth:login:success', function () {
        updateDdpForUser(true);
    });
    Event.observe(document, 'iwin:auth:logout:success', function () {
        updateDdpForUser(false);
    });
    if (iwin.AuthUI) {
        console.debug('DDP initialization trying to setup login on blue button');

        updateDdpForUser(iwin.Auth.getCurrentUsername());
    
        var displayForNonUser = $('action_buy_button_requires_signin');
        if (Object.isElement(displayForNonUser)) {
            Event.observe(displayForNonUser, 'click', function (event) {
                iwin.AuthUI.Login.show(event.element());
                Event.stop(event);
            }); 
        }
    } else {
        console.debug('DDP initialization missing iwin.AuthUI');
    }
    
    download_award_types();
    awardTypesInit();
    
    // Add 'game of interest' cookie
    iwin.Util.createCookie("last-ddp", window.location.pathname,7);
     
}

// after dom loaded, init ddp display properly
Event.observe(document, 'dom:loaded', DdpInit);

// after dom is loaded, start the effect and start blinking
// Disabled for now but left in place for use on upcoming promo.
// Event.observe(document, 'dom:loaded', iwin.experiment.effects.init);
