if (typeof(BCNTRY) == 'undefined') { BCNTRY = {}; }
if (typeof(BCNTRY.community) == 'undefined') { BCNTRY.community = {}; }
if (typeof(BCNTRY.community.widget) == 'undefined') { BCNTRY.community.widget = {}; }
if (typeof(BCNTRY.pdp) == 'undefined') {BCNTRY.pdp = {};}
if (typeof(BCNTRY.review) == 'undefined') { BCNTRY.review = {}; }
if (typeof(BCNTRY.container) == 'undefined') { BCNTRY.container = {}; }

/*Large image panel*/

BCNTRY.pdp.large_image_panel_init = function () {
    // Instantiate a Panel from markup 
    BCNTRY.large_image = new YAHOO.widget.Panel(
        "large_image_panel", {
        width:"506px", visible:false, modal: true, constraintoviewport:true, fixedcenter:true
    });

    BCNTRY.large_image.render();
    // IE6 does not handle drop shadows well.  Need to add other class
    if (YAHOO.env.ua.ie == 6) {
        yd.addClass('large_image_panel','ie6');
    }

    // Unsubscribe from default handlers - IE bug
    BCNTRY.large_image.showMaskEvent.unsubscribe();
    BCNTRY.large_image.hideMaskEvent.unsubscribe();

    BCNTRY.show_large_panel = function () {
        yd.setStyle('large_image_panel','display','block');
        BCNTRY.large_image.show();
    };
    BCNTRY.center_large_panel = function() {
        BCNTRY.large_image.center();
    };

    BCNTRY.hide_large_panel = function () {
        BCNTRY.large_image.hide();
    };

    ye.addListener("close_large_image", "click", function () { BCNTRY.hide_large_panel(); return false;} , BCNTRY.large_image, true);
    ye.addListener("large_image_panel_mask", "mousedown", function () { BCNTRY.hide_large_panel(); return false;}, BCNTRY.large_image, true);
    ye.addListener("large_product_image", "load", function () { BCNTRY.center_large_panel(); return false;}, BCNTRY.large_image, true);
};

/*End large image panel*/

/*Modal Window*/
BCNTRY.dialog_init = function () {

    // Instantiate the Dialog
    BCNTRY.container.share_gearlist = new YAHOO.widget.Dialog( "share_gearlist", {
        width:"600px", visible:false, modal: true, constraintoviewport:true, fixedcenter:true
    });
    BCNTRY.container.share_gearlist.render();

    ye.addListener("show_share_list", "click", BCNTRY.container.share_gearlist.show, BCNTRY.container.share_gearlist, true);
    yd.removeClass('share_gearlist', 'none');
};
/*End Modal Window*/

function clearShareDialog(){
    $('friendsemail').value = '';
    $('yourname').value = '';
    $('youremail').value = '';
    $('message').value = '';
    $('sendbox').checked = false;
    yd.addClass('to_required', 'none');
    yd.addClass('name_required', 'none');
    yd.addClass('from_required', 'none');
    yd.addClass('invalid_email', 'none');
    yd.addClass('invalid_from_email', 'none');
}

/*Mail sending function*/
function sendEmail(){
  
    var error_count = 0;

    var your_name = $('yourname').value;
    your_name = your_name.replace(/^\s+|\s+$/gi,'');

    var to_email = $('friendsemail').value;
    to_email = to_email.replace(/^\s+|\s+$/gi,'');

    var from_email = $('youremail').value;
    from_email = from_email.replace(/^\s+|\s+$/gi,'');

    if (to_email == '') {
        yd.removeClass('to_required', 'none');
        error_count = error_count + 1;
    }
    else {
        yd.addClass('to_required', 'none');
    }
    
    if (your_name == '') {
        yd.removeClass('name_required', 'none');
        error_count = error_count + 1;
    }
    else {
        yd.addClass('name_required', 'none');
    }
    
    if (from_email == '') {
        yd.removeClass('from_required', 'none');
        error_count = error_count + 1;
    }
    else {
        yd.addClass('from_required', 'none');
    }

    var objRegExp = /^[A-Z0-9._%+-]+\@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
    //Tests the regular expression, and also that the value is not blank, because if it is blank the error has been catched up and then we don't need to display another warning here 
    if (!objRegExp.test(from_email) && from_email != '') {
        yd.removeClass('invalid_from_email', 'none');
        error_count = error_count + 1;
    }
    else {
        yd.addClass('invalid_from_email', 'none');
    }

    var emails=$('friendsemail').value;
    var emails_array=emails.split(",");

    var part_num=0;
    while (part_num < emails_array.length)
    {
        var temp_email = emails_array[part_num].replace(/^\s+|\s+$/gi,'');
        part_num+=1;

        //This is for knowing if there are errors on the emails entered, in order to display or not the validation of format
        var initial_error_value = error_count;

        //Tests the regular expression, and also that the value is not blank, because if it is blank the error has been catched up and then we don't need to display another warning here
        if (!objRegExp.test(temp_email) && temp_email != '') {
            yd.removeClass('invalid_email', 'none');
            error_count = error_count + 1;
        }
        
        //If there were no errors on the emails entered
        if (initial_error_value == error_count) {
            yd.addClass('invalid_email', 'none');
        }
    }

    if (error_count > 0) {
        error_count = 0;
        return;
    }

    yd.addClass('to_required', 'none');
    yd.addClass('name_required', 'none');
    yd.addClass('from_required', 'none');
    yd.addClass('invalid_email', 'none');
    yd.addClass('invalid_from_email', 'none');

    var url = '/' + BCNTRY.site.catalog + '/gearlist/rest/list/' + $('list_id').value  + '/send_email';
    var args =  'friends_email=' + $('friendsemail').value
                + '&your_name=' + $('yourname').value
                + '&your_email=' + $('youremail').value
                + '&message=' + $('message').value
                + '&sendcopy=' + $('sendbox').checked;

        var callback = {
            success: function(response) {
                var respObj = eval('('+response.responseText+')');
                if (respObj.success) {
                    BCNTRY.container.share_gearlist.hide();
                    $('friendsemail').value = '';
                    $('yourname').value = '';
                    $('youremail').value = '';
                    $('message').value = '';
                    $('sendbox').checked = false;
                    /*Haven't defined what a succesful insertion displays to the user */
                }
                else {
                    alert(respObj.errorMessage);
                }
            }
        };

    yc.initHeader("accept-charset", "UTF-8");
    yc.asyncRequest('post', url, callback, args);
    yc.resetDefaultHeaders();
}
/*End of mail sending function*/

function openPrintPage(listId) { 
    var url = '/' + BCNTRY.site.catalog + '/gearlist/print/list/' + listId  + '.html';
    openWindow = window.open(
    url,'openPrintPage','height=700,width=1200,left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes')
}

BCNTRY.community.widget.AnchoredMessage = function(el, args) { this.init(el, args); };
YAHOO.extend(BCNTRY.community.widget.AnchoredMessage, YAHOO.widget.Overlay, {
	coordsInContainer: function(mouse_coords) {
		var region = yd.getRegion(this.element);
		return this._coordsInRegion(mouse_coords, region);
	},
	_coordsInRegion: function(mouse_coords, region) {
		return (mouse_coords[1] >= region.top
			&& mouse_coords[0] >= region.left
			&& mouse_coords[1] <= region.bottom
			&& mouse_coords[0] <= region.right
		);
	},
	init: function(el, args) {
		if (typeof(args) == 'undefined') { args = {}; }
		if (typeof(args.context) == 'undefined') { args.context = [el,"tl","bl"]; }
		if (typeof(args.visible) == 'undefined') { args.visible = false; }
		if (typeof(args.constraintoviewport) == 'undefined') { args.constraintoviewport = true; }
		BCNTRY.community.widget.AnchoredMessage.superclass.init.call(this, el, args);
	},
	render: function() {
		BCNTRY.community.widget.AnchoredMessage.superclass.render.call(this);
		// IE6 does not handle drop shadows well.  Need to add other class
		//if (YAHOO.env.ua.ie == 6) {
			//yd.addClass(this.id, 'help_popup_ie6');
		//}
	}
});

BCNTRY.community.widget.HelpPopup = function(el, args) { this.init(el, args); };
YAHOO.extend(BCNTRY.community.widget.HelpPopup, YAHOO.widget.Overlay, {
        _coordsInContainer: function(mouse_coords, container) {
                var region = yd.getRegion(container.id);
                return this._coordsInRegion(mouse_coords, region);
        },
        _coordsInRegion: function(mouse_coords, region) {
                return (mouse_coords[1] >= region.top
                        && mouse_coords[0] >= region.left
                        && mouse_coords[1] <= region.bottom
                        && mouse_coords[0] <= region.right
                );
        },
        init: function(el, args) {
                if (typeof(args) == 'undefined') { args = {}; }
                if (typeof(args.context) == 'undefined') { args.context = [el,"tl","bl"]; }
                if (typeof(args.visible) == 'undefined') { args.visible = false; }
                if (typeof(args.constraintoviewport) == 'undefined') { args.constraintoviewport = true; }
                BCNTRY.community.widget.HelpPopup.superclass.init.call(this, el, args);
        },
        render: function() {
                BCNTRY.community.widget.HelpPopup.superclass.render.call(this);
                // IE6 does not handle drop shadows well.  Need to add other class
                if (YAHOO.env.ua.ie == 6) {
                        yd.addClass(this.id, 'help_popup_ie6');
                }
                ye.on(this.id, 'mouseout', function(evt) {
                        var mouse_coords = ye.getXY(evt);
                        if ( ! this._coordsInContainer(mouse_coords, this) ) {
                                this.hide();
                        }
                }, this, true);
        }
});

BCNTRY.review.ERRORS = {
	NO_REVIEW_TITLE: 1<<0,
	NO_REVIEW: 1<<1,
	NO_RATING: 1<<2
};
BCNTRY.review.ERROR_MESSAGES = {
	NO_REVIEW_TITLE:'Need a title. Try: Recommended... Or not.',
	NO_REVIEW:"Umm... Where's the review? Please type it below.",
	NO_RATING:'Please select a star rating.'
};
BCNTRY.review.validate = function(review_form) {
	//BCNTRY.review.error_well.innerHTML='';
	BCNTRY.review.clearErrors();
	var errors=0;
	if(/^\s*$/.test(review_form.review_title.value)) { 
		errors|= BCNTRY.review.ERRORS.NO_REVIEW_TITLE;
		BCNTRY.review.review_title_error.innerHTML = BCNTRY.review.ERROR_MESSAGES.NO_REVIEW_TITLE;
	}
	if(/^\s*$/.test(review_form.review_comments.value)) { 
		errors|= BCNTRY.review.ERRORS.NO_REVIEW; 
		BCNTRY.review.review_comments_error.innerHTML = BCNTRY.review.ERROR_MESSAGES.NO_REVIEW;
	}
	if(/^\s*$/.test(review_form.review_rank.value)) { 
		errors|= BCNTRY.review.ERRORS.NO_RATING; 
		BCNTRY.review.review_rating_error.innerHTML = BCNTRY.review.ERROR_MESSAGES.NO_RATING;
	}
	return errors;
};
BCNTRY.review.clearErrors = function(){
	BCNTRY.review.review_title_error.innerHTML 	  = '';
	BCNTRY.review.review_comments_error.innerHTML = '';
	BCNTRY.review.review_rating_error.innerHTML   = '';
};
BCNTRY.review.review_title_error 	= $('review_title_error');
BCNTRY.review.review_comments_error = $('review_comments_error');
BCNTRY.review.review_rating_error 	= $('review_rating_error');

BCNTRY.community.ui = {
	_getParentElement: function(el, classname) {
		while( (el = el.parentNode) ) {
			if (el.className === classname) {
				return el;
			}   
		}   
	},
	
	closeCpiDisplayBox: function( ){
		yd.addClass('cpi_caption', 'hidden_content');
	},

	get_comments: function(content_type, content_id, callback) {
		// Only allow one connection at a time
		if (BCNTRY.wall.connection) { return; }
		BCNTRY.wall.connection = true;
		yd.addClass(document.body, 'yui-busy');
		var params = 'content_type=' + escape(content_type) + '&content_id=' + escape(content_id);
		var url = '/'+BCNTRY.site.catalog+'/tribe/get_comments';
		var callback = {
			failure: function() {
				yd.removeClass(document.body, 'yui-busy');
				BCNTRY.wall.connection = false;
				if (callback.failure) {
					callback.failure('Unknown error retrieving comments.');
				}
			},
			success: function(response) {
				var respObj = eval('('+response.responseText+')');
				if (respObj.success) {
					if (callback.success) {
						callback.success(respObj.attributes);
					}
				}
				else {
					if (callback.failure) {
						callback.failure(respObj.errorMessage);
					}
				}
				yd.removeClass(document.body, 'yui-busy');
			}
		};
		yc.initHeader("accept-charset", "UTF-8");
		yc.asyncRequest('POST', url, callback, params);
		yc.resetDefaultHeaders();
	},
	
	submitHelpfulVoteOnClick: function(el, is_helpful, update_carousel_cpi ) {
		form = this._getParentElement(el, "helpfulness_form");
		form.is_helpful.value = is_helpful ? '1' : '0';

        if (!form.prev_page) {
            var prev_page = document.createElement('input');
            prev_page.name = 'prev_page';
            prev_page.type = 'hidden';
            prev_page.value = location.pathname;
            form.appendChild(prev_page);
        }
		var content_type = form.content_type.value;
		var content_id   = form.content_id.value;
		var sku          = $('association') ? $('association').value : (form.sku ? form.sku.value : '');

		if (el.className == 'post_yes' || el.className == 'post_no') {
			// If the user has voted already, don't do anything
			return;
		}

		// Gets the node to be highlighted
		var getHighlightNode = function(el) {
			while (1) {
				if (el.className == 'cpi'
					|| el.className == 'review'
					|| el.className == 'question'
					|| el.className == 'answer'
					|| el.className == 'comment threaded'
					|| el.className == 'caption'
					|| el.className == 'gear_list'
				) {
					return el;
				}
				el = el.parentNode;
			}
		};
		
		// Only allow one connection at a time
		if (BCNTRY.wall.connection) { 
			//this method allow more that one connection at a time but thru the BCNTRY.wall.exceptional_connection var
			if( !BCNTRY.wall.exceptional_connection ) { return; }			
			//clean the exception in case it was set
			BCNTRY.wall.exceptional_connection = false;
		}
		BCNTRY.wall.connection = true;
		yd.addClass(document.body, 'yui-busy');
		yc.setForm(form);
		var t = this;
		var url_request = ( content_type == 'gear_list' ) ? '/'+BCNTRY.site.catalog+'/gearlist/rest/submit_helpful_vote' : '/'+BCNTRY.site.catalog+'/tribe/submit_helpful_vote';
		yc.asyncRequest('POST', url_request, {
			failure:function() {
				yd.removeClass(document.body, 'yui-busy');
				BCNTRY.wall.connection = false;
				t.setAnchoredMessage(el, 'There was an unknown error submitting your vote.');
			},
			success:function(response) {
				BCNTRY.wall.connection = false;
				var respObj = eval('('+response.responseText+')');
				if (respObj.success) {
					// update the vote counts
					yd.getElementsBy(function(o){ return o.className == 'post_yes' || o.className == 'pre_yes' }, 'a', form, function(o) {
						o.className = is_helpful ? 'post_yes' : 'pre_yes';
						o.childNodes[1].innerHTML = respObj.attributes.is_helpful_vote_count;
						if( update_carousel_cpi ){
							//also update the carousel cpi
							BCNTRY.pdp_images.mode()[ BCNTRY.pdp_images.current ].helpful_count = respObj.attributes.is_helpful_vote_count;
						}
					});
					yd.getElementsBy(function(o){ return o.className == 'post_no' || o.className == 'pre_no' }, 'a', form, function(o) {
						o.className = !is_helpful ? 'post_no' : 'pre_no';
						o.childNodes[1].innerHTML = respObj.attributes.is_unhelpful_vote_count;
						if( update_carousel_cpi ){
							//also update the carousel cpi
							BCNTRY.pdp_images.mode()[ BCNTRY.pdp_images.current ].unhelpful_count = respObj.attributes.is_unhelpful_vote_count;
						}
					});

                    var scr = new ScSubmitContentHelpful(sku, content_type, content_id, is_helpful);
					var backgroundColor = (content_type == 'gear_list') ? '#F2F2F2' : '#FFFFFF';
					var pulser = new YAHOO.squarebits.YPulse(
						getHighlightNode(form),
						'backgroundColor',
						backgroundColor , is_helpful ? '#c8fbb9' : '#ffc4c4',
						0.75, 1.00,
						0.75, 0.75,
						YAHOO.util.Easing.easeBoth,
						YAHOO.util.Easing.easeBoth
					);
					pulser.go(2);
				}
				else {
					t.setAnchoredMessage(el, respObj.errormessage);
				}
				yd.removeClass(document.body, 'yui-busy');
			}
		});
	},

	setAnchoredMessage: function(el, message) {
		if ( !this._anchoredMessage ) {
			var div = this._getAnchoredMessageEl();
			this._anchoredMessage = new BCNTRY.community.widget.AnchoredMessage(div);
			this._anchoredMessage.render();
			var t = this;
			ye.addListener(document.body, 'click', function(evt) { 
				var mouse_coords = ye.getXY(evt);
				if (!t._anchoredMessage.coordsInContainer(mouse_coords)) {
					t._anchoredMessage.hide() 
				}
			});
		}
		this._anchoredMessage.cfg.setProperty('context', [el, 'tl', 'tr']);
		this._anchoredMessage.setBody('<p>'+message+'</p>');
		this._anchoredMessage.show();
	},
	_getAnchoredMessageEl: function() {
		if (this._anchoredMessageDiv) { return this._anchoredMessageDiv; }
		var div = document.createElement('DIV');
		div.className = 'login_modal';
		document.body.appendChild(div);
		div.innerHTML = this._anchoredMessageTemplate;
		this._anchoredMessageDiv = div;
		return div;
	},
	_anchoredMessageDiv: null,
	_anchoredMessage: null,

	_anchoredMessageTemplate:
		'<div class="hd"></div><div class="bd">'+
		'<p>Padding text.</p>'+
		'</div>'+
		'<div class="bot"></div>'+
		'<div class="top_left"></div>'+
		'<div class="top_right"></div>'+
		'<div class="bottom_left"></div>'+
		'<div class="bottom_right"></div>'
};

if (BCNTRY.community.delayedVote) {
    var v = BCNTRY.community.delayedVote;
    var el = $(v.element_id);
    if (v.content_type == 'question') {
        yd.getElementsByClassName('question', 'div', el, function(o) { el = o; });
    }

	var finder = function(o) {
		return (v.is_helpful)
		? (o.className == 'pre_yes')
		: (o.className == 'pre_no');
	};
	var apply = function(o) {
		BCNTRY.community.ui.submitHelpfulVoteOnClick(o, v.is_helpful);
	};
	// 'click' the link
	yd.getElementsBy(finder, 'a', el, apply);
}

/**
 * YPulse v0.9
 * Copyright(C) 2008
 * Author: Kent Johnson <kent13304@yahoo.com>
 * License: MIT (http://www.opensource.org/licenses/mit-license.php)
 * 
 * http://blog.trendics.com/development/yui/using-yui-to-pulse-elements-on-web-pages-to-improve-usability/
 */
YAHOO.namespace('squarebits');
YAHOO.squarebits.YPulse = function(element, attributeName, startValue, endValue, s2eDuration, s2eWait, e2sDuration, e2sWait, s2eMethod, e2sMethod) {	
	var _s2eAttributeValues = {}, _s2eAttributes = {}, _s2eAnim, _e2sAttributes = {}, _e2sAnim, _e2sAttributeValues = {};
	if (startValue) { _s2eAttributeValues['from'] = startValue; }
	if (endValue) { _s2eAttributeValues['to'] = endValue; }
	_s2eAttributes[attributeName] = _s2eAttributeValues;
	if (attributeName.indexOf('olor')>0) {
		_s2eAnim = new YAHOO.util.ColorAnim(element, _s2eAttributes, s2eDuration, s2eMethod);
	}
	else {
		_s2eAnim = new YAHOO.util.Anim(element, _s2eAttributes, s2eDuration, s2eMethod);
	}
	_s2eAnim.onComplete.subscribe(function() {
		YAHOO.lang.later(s2eWait*1000.0, null, function() {
			_nextAnimation();
		});
	});
	if (startValue) { _e2sAttributeValues['to'] = startValue; }
	if (endValue) { _e2sAttributeValues['from'] = endValue; }
	_e2sAttributes[attributeName] = _e2sAttributeValues;
	if (attributeName.indexOf('olor')>0) {
		_e2sAnim = new YAHOO.util.ColorAnim(element, _e2sAttributes, e2sDuration, e2sMethod);
	}
	else {
		_e2sAnim = new YAHOO.util.Anim(element, _e2sAttributes, e2sDuration, e2sMethod);
	}
	_e2sAnim.onComplete.subscribe(function() { YAHOO.lang.later(e2sWait*1000.0, null, nextAnimation); });
	var _repeat, _repeatCount, _stopped = false;
	function _nextAnimation() {
		if (_repeat===null || _repeatCount<_repeat) {
			if (_repeatCount % 2 === 0 && !_stopped) { _s2eAnim.animate(); }
			else { _e2sAnim.animate(); }
			_repeatCount++;
		}
	}
	return {
		go: function(repeat) { _stopped = false; _repeat = repeat; _repeatCount = 0; _nextAnimation(); },
		stop: function() { _stopped = true; }
	};
};

if (typeof(BCNTRY) == 'undefined') { BCNTRY = {}; }
if (typeof(BCNTRY.wall) == 'undefined') { BCNTRY.wall = {}; }
if (typeof(BCNTRY.wall.QAndA) == 'undefined') { BCNTRY.wall.QAndA = {}; }

(function() {

BCNTRY.asyncRequest = function(url, callback, args) {
	// Only allow one connection at a time
	if (BCNTRY.wall.connection) { return; }
	BCNTRY.wall.connection = true;

	yd.addClass(document.body, 'yui-busy');

	yc.initHeader("accept-charset", "UTF-8");
	yc.asyncRequest('POST', url, {
		timeout: ajax_timeout,
		success: function(o) {
			var json_data = o.responseText;
			var resultObj = {};
			try {
				resultObj = eval( '(' + json_data + ')' );
				if (resultObj.success && callback) {
					callback.success(resultObj.attributes);
				}
				else if (callback) {
					callback.error(resultObj);
				}
			}
			catch(e) {
				if (callback) {
					callback.failure(o, e);
				}
			}
			yd.removeClass(document.body, 'yui-busy');
			BCNTRY.wall.connection = false;
		},
		failure: function(o) {
			if (callback) {
				callback.failure(o);
			}
			yd.removeClass(document.body, 'yui-busy');
			BCNTRY.wall.connection = false;
		}
	}, BCNTRY.wall.parse_query_params(args));
	yc.resetDefaultHeaders();
};

//deprecated name for this method
BCNTRY.wall.asyncRequest = BCNTRY.asyncRequest;

BCNTRY.wall.parse_query_params = function(p) {
	var params = [];
	for (var i in p) {
		params.push( i + "=" + encodeURIComponent(p[i]));
	}
	return params.join("&");
};

BCNTRY.wall.Post = function(args) {
	this.init(args);
    this.post_type = args.post_type;
};

// Only allows one connection at a time
BCNTRY.wall.connection = false;
// There are exceptions when an action like a vote must be executed right after the page load so this will have to get executed even is BCNTRY.wall.connection is true
BCNTRY.wall.exceptional_connection = false;

// Base "class" for wall posts
BCNTRY.wall.Post.prototype = {
    obj: {}, // Needs to be subclassed
	validate: function() { }, // Needs to be subclassed
	_submit_url: '',  // Needs to be subclassed
	_submit_params: function() {}, // Needs to be subclassed
	_post_submit: function() {}, // Needs to be subclassed

	_parse_query_params: function(p) {
		return BCNTRY.wall.parse_query_params(p);
	},
	
	submit: function(callback) {
		if (! this.validate() ) {
			return false;
		}

		var r = this;

        // Use the post_type passed
        // i.e. 'pdp' or 'user_contributions'
        var params = this._submit_params();
        params.post_type = this.post_type;
		this.asyncRequest(this._submit_url, {
			success: function(o) {
					r._post_submit(o);
					callback.success(o);
			},
			failure: callback.failure,
			error: function(o) {
				if (o.newurl) {
					// Redirect for login
					r.redirect(o.newurl.replace(/&amp;/, '&'));
				}
				else {
					callback.error(o);
				}
			}
		}, params );
	},

	inactivate: function(callback) {
		var args = this._delete_args();
		var r = this;
		var c = {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		};
		this.asyncRequest(this._delete_url, c, args);
	},

	asyncRequest: function(url, callback, args) {
		BCNTRY.wall.asyncRequest(url, callback, args);
	},

	redirect: function(url) {
		//need to set a cookie so when they come back
		//we know what to do.
		var cookiecontent;
		
		if (this instanceof(BCNTRY.wall.QAndA.Answer)) {
			cookiecontent = "answer";
		}
		else if (this instanceof(BCNTRY.wall.QAndA.Question)) {
			cookiecontent = "question";
		}

		cookiecontent += "," + this.association;
		
		_setCookie('content_to_post', cookiecontent, '', '/');
		window.location.href = url;
	},

	// Sets an error message.  If the element passed is not "error_message",
	// it first recursively checks children for a div who's class is "error_message"
	set_error_message: function(el, message) {
		if (el.className != 'error_message') {
			el = yd.getElementsByClassName('error_message', 'div', el)[0];
		}

		var s = "<p>${message}</p>".process({ message: message});
		el.innerHTML = s;
	}
};

BCNTRY.wall.CommentCollection = function(args) {
	this.init(args);
};
BCNTRY.wall.CommentCollection.prototype = {
	content_type: '',
	content_id: '',
	obj: { comments: [] },

	_load_url: '/'+BCNTRY.site.catalog+'/tribe/get_comments',
	_template_id: 'template_comments',

	init: function(args) {
		this.content_type = args.content_type;
		this.content_id = args.content_id;
	},

	load: function(callback) {
		var cc = this;
		var params = {
			content_type: this.content_type,
			content_id:   this.content_id
		};
		BCNTRY.wall.asyncRequest(this._load_url, {
			success: function(o) {
				cc._post_submit(o);
				callback.success(o);
			},
			failure: function() {
				callback.failure;
			},
			error: callback.error
		}, params);
	},

	_post_submit: function(o) {
		this.obj = o;
	},

	html: function() {
		var comment_els = new Array(this.obj.comments.length);
		var comment_html;
		for (var i = 0; i < comment_els.length; i++) {
			var comment = this.obj.comments[i];
			var comment_post = new BCNTRY.wall.Comment({id:comment.id});
			comment_post._post_submit({comment:comment});
			//added the div clas comment here for each comment, so when the comment.html is used from the template,
			//the div class is not duplicated (nested)
			comment_html = "<div class=\"comment threaded\" id=\"comment_" + comment.id + "\">" + comment_post.html() + " </div>";
			comment_els[i] = comment_html;
		}
		return TrimPath.processDOMTemplate(this._template_id, {comments:comment_els});
	}
};

/**
* Comment is a Wall post object
*/
BCNTRY.wall.Comment = function(attr) {
	BCNTRY.wall.Comment.superclass.constructor.call(this, attr);
};
YAHOO.extend(BCNTRY.wall.Comment, BCNTRY.wall.Post, {
	_flag_id_prefix: 'flag_comment_',
	_flag_url: "/" + BCNTRY.site.catalog + "/tribe/flag_comment",
	_unflag_url: "/" + BCNTRY.site.catalog + "/tribe/unflag_comment",
	_load_url: "/" + BCNTRY.site.catalog + "/tribe/get_comment",
	_template_id: 'template_comment',
	_template_summary_id: 'comment_summary',

	message: '',
	
	_submit_url: '/' + BCNTRY.site.catalog + '/tribe/save_comment',
	_submit_params: function() {
		return {
			content_id: this.content_id,
			content_type: this.content_type,
			body: this.body,
			comment_new: this.comment_new
		};
	},

	init: function(attr) {
		this.id = attr.id;
		this.body = attr.body;
		this.content_type = attr.content_type;
		this.content_id = attr.content_id;
		this.comment_new = attr.comment_new;
	},

	_post_submit: function(a) {
		this.obj = a;
	},

	_delete_url: "/" + BCNTRY.site.catalog + "/tribe/inactivate_comment",
	_delete_args: function() { return { cpi_id : this.cpi_id } },
	
	load: function(callback) {
		var t = this;
		var args = { comment_id: this.id };
		this.asyncRequest(this._load_url, {
			success: function(o) {
				t._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		}, args);
	},

	all_comments_html: function() {
         var comment_els = new Array(this.obj.comments.length);
         for (var i = 0; i < comment_els.length; i++) {
             var comment = this.obj.comments[i];
             var comment_post = new BCNTRY.wall.Comment({id:comment.id});
             comment_post._post_submit({comment:comment});
			 //added the div clas comment here for each comment, so when the comment.html is used from the template,
             //the div class is not duplicated (nested)
             comment_html = "<div class=\"comment threaded\" id=\"comment_" + comment.id + "\">" + comment_post.html() + " </div>";
             comment_els[i] = comment_html;
         }
         return TrimPath.processDOMTemplate('template_comments', {comments:comment_els});

	},

	html: function() {
        this.obj.comment.message = ''; 
		for (var i = 0; i < this.obj.comment.user.badges.length; i++) {
			var badge = this.obj.comment.user.badges[i];
			badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
		}
		var comment_html =  TrimPath.processDOMTemplate(this._template_id, this.obj.comment); 
		return comment_html;
	},

	html_just_posted: function() {
		this.obj.comment.message = '';
		for (var i = 0; i < this.obj.comment.user.badges.length; i++) {
			var badge = this.obj.comment.user.badges[i];
			badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
		}
		var t = TrimPath.processDOMTemplate(this._template_id, this.obj.comment);
		var comment_html = "<div class=\"comment threaded\" id=\"comment_" + this.obj.comment.id + "\">" + t + " </div>";
		return comment_html;
	},
	
	html_summary: function() {
		var t = TrimPath.processDOMTemplate(this._template_summary_id, this.obj);
		return t;
	},

	validate: function() {
		var error = false;
		var content = this.body;

		var html_regex = /<[ ^>]*\/?>|&nbsp;/g; // Remove all html tags and '&nbsp;'
		content = content.replace(html_regex, "");

		if ( (!content) || content.match(/^([\s\n]*|Write your comment here...)$/)) {
			this.invalidContent.fire("Invalid Content");
			error = true;
		}
		
		return !error;
	},


	flag: function(flag_description, callback) {
		var args = {
			comment_id: this.id,
			flag_description: flag_description
		};
		var t = this;
		var c = {
			success: function(a) {
				t._post_submit(a);
				callback.success(a);
			},
			failure: function(o, e) {
				callback.failure(o, e);
			},
			error: function(o) {
				callback.error(o);
			}
		};
		this.asyncRequest(this._flag_url, c, args);
	},
	unflag: function(callback) {
		var args = { comment_id: this.id };
		var t = this;
		var c = {
			success: function(a) {
				t._post_submit(a);
				callback.success(a);
			},
			failure: function(o, e) {
				callback.failure(o, e);
			},
			error: function(o) {
				callback.error(o);
			}
		};
		this.asyncRequest(this._unflag_url, c, args);
	}
});

/**
* CPI is a Wall post object
*/
BCNTRY.wall.CPI= function(attr) {
	BCNTRY.wall.CPI.superclass.constructor.call(this, attr);
};
YAHOO.extend(BCNTRY.wall.CPI, BCNTRY.wall.Post, {
	init: function(attr) {
		this.flag_cpi_id_prefix = 'flag_cpi_';
		this.flag_url = "/" + BCNTRY.site.catalog + "/tribe/flag_cpi";
		this.unflag_url = "/" + BCNTRY.site.catalog + "/tribe/unflag_cpi";
		this.get_obj_url = "/" + BCNTRY.site.catalog + "/tribe/get_cpi";
		this.cpi_template = 'template_cpi_full';
		this.cpi_id = attr.cpi_id;
	},
	_post_submit: function(a) {
		this.obj = a.cpi;
		this.obj.message = null;
		// This is here because we don't want to have a broken image in the template (found by gomez)
		// and because TrimPath is adding '/images/' to the beginning of the url for some reason.
		this.obj.url_small_html = '<img class="cpi_image" src="' + this.obj.image_url_small + '" alt="' + this.obj.img_alt + '" />';
	},

	_delete_url: "/" + BCNTRY.site.catalog + "/tribe/inactivate_cpi",
	_delete_args: function() { return { cpi_id : this.cpi_id } },
	
	_load_url: '/' + BCNTRY.site.catalog + '/tribe/get_cpi',
	_load_args: function() { return { cpi_id: this.cpi_id, post_type: this.post_type } },
	load: function(callback) {
		var r = this;
		this.asyncRequest(this._load_url, {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		}, this._load_args());
	},


	html: function() {
        this.obj.messaging = this.messaging;
		for (var i = 0; i < this.obj.user.badges.length; i++) {
			var badge = this.obj.user.badges[i];
			badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
		}
		return TrimPath.processDOMTemplate("template_cpi_full", this.obj);
	},


	flag: function(flag_description, callback) {
		var args = {
			cpi_id: this.cpi_id,
			flag_description: flag_description
		};
		var t = this;
		var c = {
			success: function(a) {
				t._post_submit(a);
				callback.success(a);
			},
			failure: function(o, e) {
				callback.failure(o, e);
			},
			error: function(o) {
				callback.error(o);
			}
		};
		this.asyncRequest(this.flag_url, c, args);
	},
	unflag: function(callback) {
		var args = { cpi_id: this.cpi_id };
		var t = this;
		var c = {
			success: function(a) {
				t._post_submit(a);
				callback.success(a);
			},
			failure: function(o, e) {
				callback.failure(o, e);
			},
			error: function(o) {
				callback.error(o);
			}
		};
		this.asyncRequest(this.unflag_url, c, args);
	},
	showFlagged: function(callback) {
		var args = { cpi_id: this.cpi_id };
		var t = this;
		var c = {
			success: function(a) {
				t._post_submit(a);
				t.obj.display = 'normal';
				callback.success(a);
			},
			failure: function(o, e) {
				callback.failure(o, e);
			},
			error: function(o) {
				callback.error(o);
			}
		};
		this.asyncRequest(this.get_obj_url, c, args);
	}
});

/** 
* Question is a Wall post object
*/
BCNTRY.wall.QAndA.Question = function(attr) {
	BCNTRY.wall.QAndA.Question.superclass.constructor.call(this, attr);
};

YAHOO.extend(BCNTRY.wall.QAndA.Question, BCNTRY.wall.Post, {

	DEFAULT_TEXT: '',
	init: function(attr) {
		this.obj.question_id = attr.question_id;
		this.obj.content = attr.content;
		this.association = attr.association;
		this.association_type = attr.association_type;

        this.messaging = {
			question: null,
			answer: null
		};

		// Init all events

		// Custom events that fire when validate has something invalid
		this.invalidContent = new YAHOO.util.CustomEvent('invalidContent', this, true);
		this.invalidAssociation = new YAHOO.util.CustomEvent('invalidAssociation', this, true);
		this.invalidAssociationType = new YAHOO.util.CustomEvent('invalidAssociationType', this, true);

		// Other
		this.invalidQuestionID = new YAHOO.util.CustomEvent('invalidQuestionID', this, true);
	},
    obj: {
		question_id: null,
		title: null,
		content: null,
		date: null,
		display: null,
		flagged: null,
		flagged_description: null,
		qanda_link: null,
        product_title: null,
        product_active: null,
        product_status: null,
		helpful_count: null,
		unhelpful_count: null,
		helpful_html: null,
	    user: {
			id: null,
			display_name: null,
			profile_url: null,
			post_count: null,
			badges: []
		},
        answers: [],
        answer: {
            body: {},
            users: []
        },
        curr_user: {
            id: null
        },
		image_url_small: null,
		image_url_large: null
    },
	_submit_url: '/' + BCNTRY.site.catalog + '/tribe/submit_question.html',
	_submit_params: function() {
		return {
			question_id: this.obj.question_id,
			content: this.obj.content,
			association: this.association,
			association_type: this.association_type
		};
	},

	_post_submit: function(o) {
        this.obj = o.question;
        this.obj.curr_user = {
				id: $('qanda_userid').value
        };
        this.obj.messaging = this.messaging;

		return;
	},

	// Makes an async request and loads all the attributes based on the question id
	load: function(success) {
		var url = '/' + BCNTRY.site.catalog + '/tribe/get_question';
		var args = {
			question_id: this.obj.question_id,
			post_type:   this.post_type
		};
		var r = this;
		this.asyncRequest(url, {
			success: function(o) {
				r._post_submit(o);
				if (success) {
					success();
				}
			},
			failure: function(o, e) {
				var error = 'There was an error submitting the question';
				if (e) {
					error += ":\n" + e.message;
				}
				ajax_error(o, error, 'QandA');
			},
			error: function(o) {
				ajax_error("Error getting the question");
			}
		}, args);
	},

	/**
	*  Validates the Question object, and fires events when there is invalid content
	*/
	validate: function() {
		var error = false;
		var default_text = BCNTRY.wall.QAndA.Question.DEFAULT_TEXT;
		if (! this.obj.content || this.obj.content.match(/^[\s\n]*$/) || this.obj.content === default_text) {
			this.invalidContent.fire("Invalid content");
			error = true;
		}
		if (! (this.association_type == 'product' || this.association_type == 'page') ) {
			this.invalidAssociationType.fire("An error occurred: Invalid Association Type");
			error = true;
		}
		if (! this.association) {
			this.invalidAssociation.fire("An error occurred: Invalid Association");
			error = true;
		}
		return !error;
	},

	html: function() {
        this.obj.messaging = this.messaging;
		//create badge image elements
		for (var i = 0; i < this.obj.user.badges.length; i++) {
			var badge = this.obj.user.badges[i];
			badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
		}
		//create badge image elements for answers
		for (var j = 0; j < this.obj.answers.length; j++) {
			var answer = this.obj.answers[j];
			for (var i = 0; i < answer.user.badges.length; i++) {
				var badge = answer.user.badges[i];
				badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
			}
		}
		//create content image elements
		if (this.obj.image_url_small) {
			this.obj.image_el_small = '<img src="'+this.obj.image_url_small+'" />';
		}
		//create content image elements for answers
		for (var j = 0; j < this.obj.answers.length; j++) {
			var answer = this.obj.answers[j];
			if (answer.image_url_small) {
				answer.image_el_small = '<img src="'+answer.image_url_small+'" />';
			}
		}
		return TrimPath.processDOMTemplate("qanda_submitted_question", this.obj);
	},

	_delete_url: '/' + BCNTRY.site.catalog + '/tribe/inactivate_question',
	_delete_args: function() { return { question_id: this.obj.question_id, post_type: this.post_type } },

	/**
	*  Flags a question
	*  I didn't make this part of the base Post, because most it would be potentially different (they're the same for Q&A,
	#  but they will probably different for others
	*  args:
	*	flag_types: an array of flag ids
	*/
	_flag_url: "/" + BCNTRY.site.catalog + "/tribe/flag_question",
	flag: function(flag_description, callback) {
		if (!this.obj.question_id) {
			this.invalidQuestionID.fire("An error occurred: Invalid Question ID");
			return;
		}
		var args = {
			question_id: this.obj.question_id,
			flag_description: flag_description
		};
		var r = this;
		var c = {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		};
		this.asyncRequest(this._flag_url, c, args);
	},
	_unflag_url: "/" + BCNTRY.site.catalog + "/tribe/unflag_question",
	unflag: function(callback) {
		if (!this.obj.question_id) {
			this.invalidQuestionID.fire("An error occurred: Invalid Question ID");
			return;
		}
		var args = {
			question_id: this.obj.question_id
		};
		var r = this;
		var c = {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		};
		this.asyncRequest(this._unflag_url, c, args);
	}
});
//provide static method for unflagging based on id ()
BCNTRY.wall.QAndA.Question.unflag_and_follow = function(id,a) {
  //static method to be used on onclick attribute of anchor tag
  //i.e. <a onclick="BCNTRY.wall.QAndA.unflag_and_follow(13054,this)">
  var q=new BCNTRY.wall.QAndA.Question({question_id:id});
  var callback= {//the ajax callback object
	success:function() {
	  window.location=a.href;
	},
	failure:function() {
	  //silently fail, the user wasn't trying to unflag, and they don't care if it failed.
	  window.location=a.href;
	}
  }
  q.unflag(callback);//do it, (this call is asynchronous)
  return false;//don't follow the link because unflag will do it for you
};
BCNTRY.wall.QAndA.Answer = function(attr) {
	BCNTRY.wall.QAndA.Answer.superclass.constructor.call(this, attr);
};
YAHOO.extend(BCNTRY.wall.QAndA.Answer, BCNTRY.wall.Post, {

	init: function(attr) {
		this.obj.question_id = attr.question_id;
		this.obj.answer.body = attr.content;
		this.obj.answer.answer_id = attr.answer_id;
		this.association = attr.association;
		this.association_type = attr.association_type;

        this.messaging = {
			answer: null,
			question: null
		};
		// Init events
		this.invalidContent = new YAHOO.util.CustomEvent('invalidContent', this, true);
		this.invalidQuestionID = new YAHOO.util.CustomEvent('invalidQuestionID', this, true);
	},

	// Makes an async request and loads all the attributes based on the answer_id
	// (found in this.obj.answer.answer_id)
	load: function(callback) {
		var url = '/' + BCNTRY.site.catalog + '/tribe/get_question';
		var args = {
			answer_id: this.obj.answer.answer_id,
			post_type: this.post_type
		};
		var r = this;
		this.asyncRequest(url, {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		}, args);
	},

	_submit_url: '/' + BCNTRY.site.catalog + '/tribe/submit_answer.html',
	_submit_params: function() {
		return {
			question_id: this.obj.question_id,
			answer_id: this.obj.answer.answer_id,
			content: this.obj.answer.body,
			association: this.association,
			association_type: this.association_type
		};
	},
	obj: {
		question_id: null,
		title: null,
		content: null,
		display: null,
		flagged: null,
		flagged_description: null,
		qanda_link: null,
		date: null,
		helpful_count: null,
		unhelpful_count: null,
		helpful_html: null,
		user: {
            id: null,
            display_name: null,
		    post_count: null,
		    profile_url: null,
			badges: []
        },
		answer: {
            body: null,
            answer_id: null
        },
		answers: [],
        curr_user: {},
		image_url_small: null,
		image_url_large: null,
		image_el_small: null
	},
	_post_submit: function(o) {
		var old_answer_id = this.obj.answer_id;
        this.obj = o.question;

	    this.answer = null;

        // Set the default answer
		for (var i = 0; i < this.obj.answers.length; i++) {
			if (this.obj.answers[i].answer_id == old_answer_id) {
				this.obj.answer = this.obj.answers[i];
			}
		}
		if (!this.obj.answer) {
			this.obj.answer  = this.obj.answers[0];
		}

        // Set the current user
        this.obj.curr_user = {
            id: $('qanda_userid').value
        };
	},

	validate: function() {
		var error = false;
		var content = this.obj.answer.body;

		var html_regex = /<[ ^>]*\/?>|&nbsp;/g; // Remove all html tags and '&nbsp;'
		content = content.replace(html_regex, "");

		if ( (!content) || content.match(/^([\s\n]*|Write your answer here...)$/)) {
			this.invalidContent.fire("Invalid Content");
			error = true;
		}
		if (!this.obj.question_id) {
			this.invalidQuestionID.fire("An error occurred: Invalid Question ID");
			error = true;
		}
		return !error;
	},

	html: function() {
        this.obj.messaging = this.messaging;
		for (var i = 0; i < this.obj.user.badges.length; i++) {
			var badge = this.obj.user.badges[i];
			badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
		}
		for (var j = 0; j < this.obj.answers.length; j++) {
			var answer = this.obj.answers[j];
			for (var i = 0; i < answer.user.badges.length; i++) {
				var badge = answer.user.badges[i];
				badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
			}
		}
		//create content image elements
		if (this.obj.image_url_small) {
			this.obj.image_el_small = '<img src="'+this.obj.image_url_small+'" />';
		}
		//create content image elements for answers
		for (var j = 0; j < this.obj.answers.length; j++) {
			var answer = this.obj.answers[j];
			if (answer.image_url_small) {
				answer.image_el_small = '<img src="'+answer.image_url_small+'" />';
			}
		}
		return TrimPath.processDOMTemplate("qanda_submitted_question", this.obj);
	},

	_delete_url: '/' + BCNTRY.site.catalog + '/tribe/inactivate_answer',
	_delete_args: function() { return {
        question_id: this.obj.question_id,
        answer_id: this.obj.answer.answer_id,
        post_type: this.post_type
    } },

	/**
	*  Flags an answer
	*  I didn't make this part of the base Post, because most it would be potentially different (they're the same for Q&A,
	#  but they will probably different for others
	*  args:
	*	flag_types: an array of string flag types (can have "spam", "offensive", "miscategorized", "duplicate")
	*/
	_flag_url: "/" + BCNTRY.site.catalog + "/tribe/flag_answer",
	flag: function(flag_description, callback) {
		if (!this.obj.question_id) {
			this.invalidQuestionID.fire("An error occurred: Invalid Question ID");
			return;
		}
		var args = {
			question_id: this.obj.question_id,
			answer_id: this.obj.answer.answer_id,
			flag_description: flag_description
		};
		var r = this;
		var c = {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		};
		this.asyncRequest(this._flag_url, c, args);
	},
	_unflag_url: "/" + BCNTRY.site.catalog + "/tribe/unflag_answer",
	unflag: function(callback) {
		if (!this.obj.question_id) {
			this.invalidQuestionID.fire("An error occurred: Invalid Question ID");
			return;
		}
		var args = {
			question_id: this.obj.question_id,
			answer_id: this.obj.answer.answer_id
		};
		var r = this;
		var c = {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		};
		this.asyncRequest(this._unflag_url, c, args);
	}
});

BCNTRY.wall.Review = function(attr) {
	BCNTRY.wall.Review.superclass.constructor.call(this, attr);
};
YAHOO.extend(BCNTRY.wall.Review, BCNTRY.wall.Post, {

	// I separated all review attributes to a new "obj" attribute, something
	// I wished I would have done with the Question and Answer as well
	obj: {
		review_id: null,
		link_id: null,
		date: null,
		body: null,
		helpful_count: null,
		unhelpful_count: null,
		helpful_html: null,
		rank_image: null,
		title: null,
		review_link: null,
		display: null,
		flagged: null,
		flagged_description: null,
		user: {
			profile_url: null,
			display_name: null,
			post_count: null,
			badges: []
		},
        comments: [],
        comment: {
            body: {},
            users: []
        },
		image_url_small: null,
		image_url_large: null,
		image_el_small: null
	},

	init: function(attr) {
		this.obj.review_id = attr.review_id; // currently this is all that is needed
		this.invalidReviewID = new YAHOO.util.CustomEvent('invalidReviewID', this, true);
	},

	_post_submit: function(o) {
		this.obj = o.review;
		this.obj.message = null;
	},
	
    // Makes an async request and loads all the attributes based on the review id
	load: function(success) { 
		var url = '/' + BCNTRY.site.catalog + '/tribe/get_review';
		var args = {
			review_id: this.obj.review_id,
			post_type: this.post_type
		};
		var r = this;
		this.asyncRequest(url, {
			success: function(o) {
				r._post_submit(o);
				if (success) {
					success();
				}
			},
			failure: function(o, e) {
				var error = 'There was an error loading the review';
				if (e) {
					error += ":\n" + e.message;
				}
				ajax_error(o, error, 'Reviews');
			},
			error: function(o) {
				ajax_error("Error getting the review");
			}
		}, args);
	},

	html: function() {
		for (var i = 0; i < this.obj.user.badges.length; i++) {
			var badge = this.obj.user.badges[i];
			badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
		}

		if (this.obj.comments) {
			for (var j = 0; j < this.obj.comments.length; j++) {
				var comment = this.obj.comments[j];
				for (var i = 0; i < comment.user.badges.length; i++) {
					var badge = comment.user.badges[i];
					badge.image_el = '<img class="user_badge" src="'+badge.image_url+'" alt="'+badge.text+'" onmouseover="BCNTRY.wall.PDP.badgeHelpIconMouseOver(this,\''+badge.description+'\')" onmouseout="BCNTRY.wall.PDP.badgeHelpIconMouseOut(event)" />';
				}
			}
		}

		if (this.obj.image_url_small) {
			this.obj.image_el_small = '<img src="'+this.obj.image_url_small+'" />';
		}

		return TrimPath.processDOMTemplate("review_full", this.obj);
	},


	///Inactivate Review
	_inactivate_url: "/" + BCNTRY.site.catalog + "/tribe/inactivate_review",
	inactivate: function(callback) {
		if (!this.obj.review_id) {
			this.invalidReviewID.fire("An error occurred: Invalid Review ID");
			return;
		}

		var args = {
			review_id: this.obj.review_id
		};

		var r = this;
		var c = {
			success: function(o) {
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		};
		this.asyncRequest(this._inactivate_url, c, args);
	},

	//Begin Flags
	/**
	*  Flags a review
	*  I didn't make this part of the base Post, because most it would be potentially different (they're the same for Q&A,
	#  but they will probably different for others 
	*  args:
	*   flag_types: an array of flag ids
	*/
	_flag_url: "/" + BCNTRY.site.catalog + "/tribe/flag_review",
	flag: function(flag_description, callback) {
		if (!this.obj.review_id) {
			this.invalidReviewID.fire("An error occurred: Invalid Review ID");
			return;
		}
		var args = {
	 		review_id: this.obj.review_id,
			flag_description: flag_description
		};
		var r = this;
		var c = {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
				error: callback.error
		};
		this.asyncRequest(this._flag_url, c, args);
	},

	_unflag_url: "/" + BCNTRY.site.catalog + "/tribe/unflag_review",
	unflag: function(callback) {
		if (!this.obj.review_id) {
			this.invalidReviewID.fire("An error occurred: Invalid Review ID");
			return;
		}
		var args = {
			review_id: this.obj.review_id
		};
		var r = this;
		var c = {
			success: function(o) {
				r._post_submit(o);
				callback.success(o);
			},
			failure: callback.failure,
			error: callback.error
		};
		this.asyncRequest(this._unflag_url, c, args);
	}
												
	//End flags

});

})();

// BCNTRY.review.controls.rating
// This is in the BCNTRY.review.controls namespace because
// it's legacy code. That namespace isn't used anywhere else anymore
// so we have to create it here.
if (typeof(BCNTRY.review) == 'undefined') { BCNTRY.review = {}; }
if (typeof(BCNTRY.review.controls) == 'undefined') { BCNTRY.review.controls = {}; }
(function() {
	var rating = function(startDiv, onStyle, offStyle) {
		this.initialize(startDiv, onStyle, offStyle);
	};
	rating.prototype.homeBase = null;
	rating.prototype.starList = null;
	rating.prototype.verbiage = null;
	rating.prototype.hiddenInput = null;
	rating.prototype.onStyle = null;
	rating.prototype.offStyle = null;
	rating.prototype.initialize = function(startDiv, onStyle, offStyle){
		this.homeBase = startDiv;
		this.onStyle = onStyle;
		this.offStyle = offStyle;
		this.starList = startDiv.getElementsByTagName("LI"); 
		this.verbiage = startDiv.getElementsByTagName("SPAN")[0]; 
		this.hiddenInput = startDiv.getElementsByTagName("input")[0]; 

		// get your LIs to fire upon mouseover
		YAHOO.util.Event.addListener(startDiv, 'mouseout', this.setCurrentRating, this, true);
		for (var n=0; n< this.starList.length; n++){
			YAHOO.util.Event.addListener(this.starList[n], 'mouseover', this.highlightRating, this, true);
			YAHOO.util.Event.addListener(this.starList[n], 'click', this.setRating, this, true);
			this.starList[n].className = offStyle;
		}
		// get the rating value in case it was preset
		var initial_value = this.hiddenInput.value && this.hiddenInput.value != '' ? this.hiddenInput.value : 0;
		// Initialize the rating depending on the current value
		this.showVerbiage( initial_value );
		this.setRatingNum( initial_value );
	};
	rating.prototype.setRating = function(e){
		var rating = this.highlightRating(e);
		this.hiddenInput.value = rating;
	};
	rating.prototype.highlightRating = function(e){
		var elTarget = YAHOO.util.Event.getTarget(e);
		var found = false;
		var theClass = this.onStyle;
		var rating;
		for (var n=0; n < this.starList.length; n++){
			if (found){
				theClass = this.offStyle
			}
			
			if (this.starList[n] === elTarget){
				found = true;
				rating = n + 1;
			}
			
			this.starList[n].className = theClass;
		}
		this.showVerbiage(rating);
		return rating;
	};
	rating.prototype.showVerbiage = function(num) {
		if (num == '')
			this.verbiage.innerHTML = '';
		else
			this.verbiage.innerHTML = BCNTRY.msgConfig.ratings[num];
	};
	rating.prototype.setCurrentRating = function(){
		var rating = this.hiddenInput.value || '';
		this.setRatingNum(rating);
	};
	rating.prototype.setRatingNum = function(num){
		num = num - 1;
		var found = false;
		var theClass = this.onStyle;
		if (num < 0){
			theClass = this.offStyle;
			this.showVerbiage(0);
		}
		for (var n=0; n< this.starList.length; n++){
			if (found){
				theClass = this.offStyle
			}

			if (n == num){
				found = true;
				this.hiddenInput.value = n + 1;
				this.showVerbiage(n+1);
			}
			this.starList[n].className = theClass;
		}
	};
	BCNTRY.review.controls.rating = rating;
})();


// Manages a list of tags including which are displayed and what state they are in
BCNTRY.community.TagManager = function(tagsFieldId, tagListId, filterButtonId, resetButtonId) {
	this.init(tagsFieldId, tagListId, filterButtonId, resetButtonId);
};
BCNTRY.community.TagManager.prototype = {
	tagSeparator: ',',
	tagsFieldEl: null,
	tagListEl: null,
	filterButtonEl: null,
	resetButtonEl: null,
	selectedClass: 'selected',
	activeClass: 'active',
	hiddenClass: 'hidden',
	tagsActivated: false,
	numTagsSelected:0,
	init: function(tagsFieldId, tagListId, filterButtonId, resetButtonId) {
		this.tagsFieldEl = $(tagsFieldId);
		this.tagListEl = $(tagListId);
		this.filterButtonEl = $(filterButtonId);
		this.resetButtonEl = $(resetButtonId);
		var oThis = this;
		yd.getElementsBy(
			function(el) { return true; },
			'LI',
			this.tagListEl,
			function(el) { ye.addListener(el, 'click', oThis.handleTagClick, oThis, true) }
		);
		ye.addListener(this.tagsFieldEl, 'keyup', oThis.handleKeyUp, oThis, true);
		this.setSelectedTags();
	},
	handleTagClick: function(evt) {
		var el = ye.getTarget(evt);
		var tag = this.getTagValue(el);
		this.toggleTag(tag);
	},
	handleKeyUp: function() {
		this.setSelectedTags();
	},
	getTagValue: function(el) {
		while (el.firstChild.nodeType != 3) {
			el = el.firstChild;
		}
		return el.title;
	},
	sanitizeTag: function(tag) {
		tag = tag.replace(/^\s+/, "");
		tag = tag.replace(/\s+$/, "");
		tag = tag.toLowerCase();
		return tag;
	},
	getFieldTags: function() {
		var tags = this.tagsFieldEl.value.split(this.tagSeparator);
		for (var i = 0; i < tags.length; i++) {
			tags[i] = this.sanitizeTag(tags[i]);
		}
		return tags;
	},
	fieldHasTag: function(tag) {
		tag = tag.toLowerCase();
		var tags = this.getFieldTags();
		for (var i = 0; i < tags.length; i++) {
			if (tag == tags[i]) {
				return true;
			}
		}
		return false;
	},
	addTag: function(tag) {
		if (this.tagsFieldEl.value.length > 0) {
			this.tagsFieldEl.value += this.tagSeparator;
		}
		this.tagsFieldEl.value += tag;
	},
	removeTag: function(tag) {
		var tags = this.getFieldTags();
		var newTags = new Array();
		for(var i = 0; i < tags.length; i++) {
			if(tags[i] != tag) {
				newTags.push(tags[i]);
			}
		}
		this.tagsFieldEl.value = newTags.join(this.tagSeparator);
	},
	toggleTag: function(tag) {
		if(this.fieldHasTag(tag)) {
			this.removeTag(tag);
		}
		else {
			this.addTag(tag);
		}
		this.setSelectedTags();
		if(this.numTagsSelected && !this.tagsActivated ) {			
			yd.addClass( this.filterButtonEl, this.activeClass );
		}
		else{
			if( yd.hasClass( this.filterButtonEl,  this.activeClass) ) {
				yd.removeClass( this.filterButtonEl, this.activeClass );
			}
		}
	},
	setSelectedTags: function() {
		yd.getElementsBy(
			function(el) { return true; },
			'LI',
			this.tagListEl,
			function(el) {
				var tag = this.getTagValue(el);
				if (this.fieldHasTag(tag)) {
					if (!yd.hasClass(el, this.selectedClass)) {
						yd.addClass(el, this.selectedClass);
						this.numTagsSelected ++;
					}
				}
				else {
					if (yd.hasClass(el, this.selectedClass)) {
						yd.removeClass(el, this.selectedClass);
						this.numTagsSelected --;
					}
				}
			},
			this,
			true
		);
	},
	activateSelectedTags: function() {
		//enable the reset button and disable the filter one
		yd.addClass( this.resetButtonEl, this.activeClass );
		yd.removeClass( this.filterButtonEl, this.activeClass );
		
		this.tagsActivated = true;
		yd.getElementsBy(
			function(el) { return true; },
			'LI',
			this.tagListEl,
			function(el) {
				var tag = this.getTagValue(el);
				if (this.fieldHasTag(tag)) {
					if (yd.hasClass(el, this.selectedClass)) {
						yd.removeClass(el, this.selectedClass);
					}
					if (!yd.hasClass(el, this.activeClass)) {
						yd.addClass(el, this.activeClass);
					}
				}
			},
			this,
			true
		);
	},
	hideUnselectedTags: function() {
		yd.getElementsBy(
			function(el) { return true; },
			'LI',
			this.tagListEl,
			function(el) {
				var tag = this.getTagValue(el);
				if (!this.fieldHasTag(tag) && !yd.hasClass(el, this.hiddenClass)) {
					yd.addClass(el, this.hiddenClass);
				}
			},
			this,
			true
		);
	},
	showAllTags: function() {
		yd.getElementsBy(
			function(el) { return true; },
			'LI',
			this.tagListEl,
			function(el) {
				if (yd.hasClass(el, this.hiddenClass)) {
					yd.removeClass(el, this.hiddenClass);
				}
			},
			this,
			true
		);
	},
	unselectAllTags: function() {
		this.tagsActivated = false;
		this.numTagsSelected = 0;
		yd.getElementsBy(
			function(el) { return true; },
			'LI',
			this.tagListEl,
			function(el) {
				var tag = this.getTagValue(el);
				if (this.fieldHasTag(tag)) {
					this.removeTag(tag);
				}
				if (yd.hasClass(el, this.selectedClass)) {
					yd.removeClass(el, this.selectedClass);
				}
				if (yd.hasClass(el, this.activeClass)) {
					yd.removeClass(el, this.activeClass);
				}
			},
			this,
			true
		);
	},
	reset: function() {
		//disable the reset button.
		yd.removeClass( this.resetButtonEl, this.activeClass );
		this.unselectAllTags();
		this.showAllTags();
	},
	canFilter: function() {
		return yd.hasClass( this.filterButtonEl, this.activeClass);
	},
	canReset: function() {
		return yd.hasClass( this.resetButtonEl, this.activeClass);
	}
};

// Manages gear list searching. This object only performs searches. Subscribers
// to the searchCompleted event actually do something with the results.
BCNTRY.community.GearListSearchManager = function(searchFieldId, tagsFieldId ) {
	this.init(searchFieldId, tagsFieldId);
};
BCNTRY.community.GearListSearchManager.prototype = {
	searchFieldEl: null,
    tagsFieldEl: null,
	searchInitiated: null,
	searchCompleted: null,
	connection: null,
	init: function(searchFieldId, tagsFieldId) {
		this.searchFieldEl = $(searchFieldId);
		this.tagsFieldEl = $(tagsFieldId);
		this.searchCompleted = new YAHOO.util.CustomEvent("searchCompleted");
		this.searchInitiated = new YAHOO.util.CustomEvent("searchInitiated");
	},
    doSearch: function(searchPhrase, tags) {
		this.searchInitiated.fire();
		//if a request is in progress, abort it before continuing
		if (this.connection != null && yc.isCallInProgress(this.connection)) {
			yc.abort(this.connection);
		}
		var oThis = this;
		var url = '/'+BCNTRY.site.catalog+'/gearlist/rest/search';
		var args = {
			'q': searchPhrase,
			'tags': tags
		};
		url += '?' + BCNTRY.wall.parse_query_params(args);
		var callback = {
			success: function(response) {
				var respObj = eval('('+response.responseText+')');
				if (respObj.success) {
					oThis.searchCompleted.fire(respObj.attribs, searchPhrase, tags);
				}
				else {
					var error = respObj.errorMessage || 'Unknown error';
					if(window['console']) console.log('search failed: ' + error);
					//TODO: error messaging to the user
				}
			},
			failure: function() {
				if(window['console']) console.log('search failed completely');
				//TODO: error messaging to the user
			}
		};
		this.connection = yc.asyncRequest('GET', url, callback);
	}
};

// Manages the display of a list of gear lists.
BCNTRY.community.GearListManager = function(listContainerId, searchManager) {
	this.init(listContainerId, searchManager);
};
BCNTRY.community.GearListManager.prototype = {
	listContainerEl: null,
	searchManager: null,
	lists: [],
	init: function(listContainerId, searchManager) {
		this.listContainerEl = $(listContainerId);
		this.searchManager = searchManager;
		this.searchManager.searchCompleted.subscribe(this.handleSearchCompleted, this, true);
	},
	clear: function() {
		while(this.listContainerEl.childNodes.length > 0) {
			this.listContainerEl.removeChild(this.listContainerEl.childNodes[0]);
		}
		this.lists = [];
	},
	addGearList: function(gearList) {
		this.lists.push(gearList);
		var li = document.createElement('li');
		li.innerHTML = gearList.html();
		yd.addClass(li, this.lists.length % 2 == 0 ? 'even' : 'odd');
		this.listContainerEl.appendChild(li);
		var div = document.createElement('div');
		yd.addClass(div, 'clearb');
		this.listContainerEl.appendChild(div);
	},
	handleSearchCompleted: function(e, args) {
		var o = args[0];
		this.clear();
		for(var i = 0; i < o.gear_lists.length; i++) {
			this.addGearList(new BCNTRY.community.GearList(o.gear_lists[i]));
		}
	}
};

//Represents a Gear List. Can display itself as html using TrimPath.
BCNTRY.community.GearList = function(obj) {
	this.init(obj);
};
BCNTRY.community.GearList.prototype = {
	_template_id: 'template_gear_list',
	obj: null,
	init: function(obj) { this.obj = obj; },
	html: function() {
		return TrimPath.processDOMTemplate(this._template_id, this.obj);
	}
};

BCNTRY.delete_gear_list = function(id) {
    document.delete_gear_list_form.listId.value = id;
    document.delete_gear_list_form.submit();
}

//TODO: This shoudn't be here. It should be in product_detail.js probably.
ye.onDOMReady(function() {
    BCNTRY.pdp.large_image_panel_init();
    BCNTRY.dialog_init();
});
