var CONTENT_EL = "#contenido"; 
$(document).ready(function() {	
	$("#query").focus();
	if(location.href.indexOf("#/buscar.html?") != -1) {	
		searchAgain(CONTENT_EL,location.href.substring(location.href.indexOf("#/buscar.html?") + "#/buscar.html?".length,location.href.length));
	}
	initAjaxLoaders();		
	$("a.fancybox").fancybox({
		'titlePosition'	:	'over',
		'transitionIn'	:	'elastic',
		'transitionOut'	:	'elastic',
		'speedIn'		:	600, 
		'speedOut'		:	200,
		'onComplete'	:	function() {
			$("#fancybox-wrap").hover(function() {
				$("#fancybox-title").show();
			}, function() {
				$("#fancybox-title").hide();
			});
		}
	});	
	
	// PNG IE 6 fix	
	if(typeof DD_belatedPNG == "object") {		
		DD_belatedPNG.fix('.screenshot');		
	}
});

function initAjaxLoaders() {
	var js_function = "javascript:searchAgain('"+CONTENT_EL+"')";	
	if(document.getElementById("searchForm")) {		
		document.getElementById("searchForm").action = js_function;
	} else if(document.getElementById("searchAdvancedForm")) {
		document.getElementById("searchAdvancedForm").action = js_function;
	}
	/*
	$('a').each(function() {
		if($(this).attr('href')) {
			if($(this).attr('href').substr(0,"/pages.html?id=".length) == "/pages.html?id=") {
				var url = $(this).attr('href').replace("/pages.html?id=","javascript:getPage(");
				url += ");"
				$(this).attr('href',url);		
			}
		}
	});*/
}

Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

function toggleMenu(id) {
	$("#"+id+ " ul").toggle();	
	
}

function updatePagination(id,resultsLength, offset, resultsPerPage, num_display_entries,callback_function) {
	$("#"+id).pagination(resultsLength, {
		current_page: offset/resultsPerPage,
		items_per_page: resultsPerPage,
		num_display_entries: num_display_entries, 
		callback:eval(callback_function)
	});	
	(resultsLength < resultsPerPage ) ?	$("#"+id).hide() : $("#"+id).show();
}

function changeLocale(lang) {
	var url = "locale.do?";		
	$.get(url,{lang: lang}, function() {
		window.location.reload( true);
	});
}
var LOADING_EL = "<p class=\"loading\"><span>Cargando ...</span></p>";

function getPage(id) {
	var url = "/json/pages/getPage.html";
	
	$.getJSON(url, {id: id, processMarkdown: 'true'}, function(json){
		var page = new PageDTO(json.id, json.title, json.intro,  json.content, json.category, json.attachments);
		var html = page.toHTML();
		$(CONTENT_EL).html(html);
	});
}

function searchAgain(content_el, url_parameters) {	
	if(!document.getElementById("hits")) {
		$(CONTENT_EL).html(LOADING_EL);
	} else {
		$("#hits").html(LOADING_EL);
	}	
	var url = "/json/buscar.html";
	
	var bookmark_url = "";
	var parameters =  {};	
	if(url_parameters && ((typeof url_parameters) != "object")) {
		var utf8_chart_table = new UTFChartTable(url_parameters);
		url_parameters = utf8_chart_table.getStringWithReplacedCharacters();
		var arr = url_parameters.split("&");		
		for(var i = 0; i < arr.length;i++) {
			var name_value = arr[i].split("=");			
			parameters[name_value[0]] = name_value[1]; 	
		}		
		bookmark_url = "/buscar.html?" + url_parameters;		
	} else {		
		if (document.getElementById("searchAdvancedForm")) {
			var search_parameters = new SearchAdvancedParameters();
			search_parameters.populate();
			parameters = search_parameters.toArr();
			bookmark_url = "/buscar.html?" + search_parameters.toURLParameters();
		} else {
			var search_parameters = new SearchSimpleParameters();
			search_parameters.populate();
			parameters = search_parameters.toArr();
			bookmark_url = "/buscar.html?" + search_parameters.toURLParameters();
		}
	}
	
	parameters['output'] = "json";	
	$.ajax({
		url: url, 
		data: parameters,
	    contentType: "application/json; charset=utf-8",
	    dataType: "json", 
		success: function(json) {
			$.address.value(bookmark_url);
			if(!document.getElementById("entriesnumber")) {
				$(CONTENT_EL).append("<p id=\"entriesnumber\"><span class=\"value\">"+json.entriesnumber+"</span> resultados para el término " + json.query + "</p>");
			} else {
				$("#entriesnumber .value").html(json.entriesnumber);
			}
			if(!document.getElementById("pagination")) {
				$(CONTENT_EL).append("<p id=\"pagination\" class=\"pagination noprint\"></p>");
			}		
			if(!document.getElementById("hits")) {
				$(CONTENT_EL).append("<ul id=\"hits\" class=\"results\"></ul>");
			}
			var searchResults = new SearchResults(json.results.results);
			searchResults.appendHits();			
			updatePagination("pagination",json.entriesnumber, json.offset, json.resultsPerPage, 8,"searchAgain");
			$(".loading").remove();
		}	
	});	
}

/////////////////////////////////////////////////////
// PageDTO
////////////////////////////////////////////////////

function PageDTO(id, title, intro,  content, category, attachments) {
	this.id = id;
	this.title = title;
	this.intro = intro;
	this.content = content;
	if(category) {
		this.category = new SimpleDTO(category.id,category.title,category.intro,category.content);
	}
	this.attachements = new Array();
	for(var i = 0; i < attachments.length;i++) {
		this.attachements[i] = new AttachmentDTO(attachments[i].id, attachments[i].name, attachments[i].intro,  attachments[i].description, attachments[i].size, attachments[i].type);
	}
}

PageDTO.prototype.toHTML = function() {
	var html = "";
	if(this.category) {
		html += "<p class=\"breadcrumbs\"><a href=\"/index.html\">Inicio</a><span> &rarr; </span><span>" + this.category.title + "</span><span> &rarr; </span><a href=\"/pages.html?id="+this.id+"\">"+this.title+"</a></p>";						
	}
	html += "<h1>"+ this.title +"</h1>";
	html += "<div class=\"content\">"+this.content+"</div>";
	return html;	
};


function AttachmentDTO(id, name, intro,  description, size, type) {
	this.id = id;
	this.name = intro;
	this.description = description;
	this.size = size;
	this.type = type;
}
/////////////////////////////////////////////////////
//SearchResults
////////////////////////////////////////////////////

function SearchResults(results) {
	this.results = results;
}

SearchResults.prototype.appendHits = function() {
	if(this.results.length > 0) {
		var html = "";
		for(var i = 0;i < this.results.length; i++) {
			if(this.results[i].id.substr(0,"DUBLINCORE".length) != "DUBLINCORE") {
				var page = new SimpleDTO();
				page.populateWithJSON(this.results[i]);
				html += page.toLi();
			}			
		}
		var even_odd_counter = 0;
		for(var i = 0;i < this.results.length; i++) {			
			if(this.results[i].id.substr(0,"DUBLINCORE".length) == "DUBLINCORE") {
				var dc = new DublinCore();
				dc.populateWithJSON(this.results[i]);
				html += dc.toLiDC(even_odd_counter);
				even_odd_counter++;
			}			
		}		
		$("#hits").append(html);
	} else {
		html = "<p class=\"help\">No se han encontrado resultados para su búsqueda. Pruebe a seleccionar otro fondo o archivo.</p>";		
	}
};

/////////////////////////////////////////////////////
// Search Parameters
////////////////////////////////////////////////////

function SearchParameters(resultsPerPage, current_page, offset, entriesnumber, visualization, catalogueId) {
	this.resultsPerPage = resultsPerPage;
	this.current_page = current_page;
	this.offset = offset;
	//this.entriesnumber = entriesnumber;
	this.visualization = visualization;
	this.catalogueId = catalogueId;	  		
}

SearchParameters.prototype.populate = function() {	
	this.resultsPerPage = $("#resultsPerPage").val();
	this.current_page 	= $("#pagination span.current").text().replace('Siguiente','').replace('Anterior','');	
	this.offset 		= (this.current_page==0) ? 0 : ((this.current_page*this.resultsPerPage)-this.resultsPerPage);
	//this.entriesnumber 	= $("#entriesnumber .value").html();
	//alert(this.entriesnumber);
	this.visualization 	= $("#visualization").val();
	this.catalogueId 	= $("#catalogueId").val();  	
};

SearchParameters.prototype.toArr = function() {
	var arr = {};
	arr['resultsPerPage'] 	= this.resultsPerPage;
	arr['current_page'] 	= this.current_page;
	arr['offset'] 			= this.offset;
	//arr['entriesnumber'] 	= this.entriesnumber;
	arr['visualization'] 	= this.visualization;
	arr['catalogueId'] 		= this.catalogueId;	
	return arr;  	
};

SearchParameters.prototype.toURLParameters = function() {
	var url_parameters = "";
	
	url_parameters += "resultsPerPage=" + this.resultsPerPage + "&";
	
	url_parameters += "current_page=" + this.current_page + "&";
		
	url_parameters += "offset=" + this.offset + "&";
	
	//url_parameters += "entriesnumber=" + this.entriesnumber + "&";
	
	url_parameters += "visualization=" + this.visualization + "&";
	
	url_parameters += "catalogueId=" + this.catalogueId + "&";
			
	return url_parameters;  	
};

/////////////////////////////////////////////////////
// Search Simple Parameters
////////////////////////////////////////////////////

function SearchSimpleParameters(resultsPerPage, current_page, offset, entriesnumber, visualization, catalogueId,query) {
	this.parameters = new SearchParameters(resultsPerPage, current_page, offset, entriesnumber, visualization, catalogueId);
	this.query = query;
}

SearchSimpleParameters.prototype.populate = function() {
	var search_param = new SearchParameters();
	search_param.populate();
	this.parameters = search_param;
	this.query = $("#query").val();
};

SearchSimpleParameters.prototype.toArr = function() {
	var arr = this.parameters.toArr();
	arr['query'] = this.query;
	return arr;
};


SearchSimpleParameters.prototype.toURLParameters = function() {
	var url_parameters = this.parameters.toURLParameters();
	if(this.query != "")	
		url_parameters += "query=" + this.query + "&";
	return url_parameters;
};

/////////////////////////////////////////////////////
// Search Advanced
////////////////////////////////////////////////////  
	
function SearchAdvancedParameters(resultsPerPage, current_page, offset, entriesnumber, visualization, catalogueId, queryCreator, occurCreator, queryTitle, occurTitle, queryPublisher, occurPublisher, queryDate, occurDate, queryIdentifier, occurIdentifier, queryDescription, occurDescription, querySubject, occurSubject) {
	this.parameters = new SearchParameters(resultsPerPage, current_page, offset, entriesnumber, visualization, catalogueId);
			  	
	this.queryCreator = queryCreator; 
	this.occurCreator = occurCreator;
	this.queryTitle = queryTitle;
	this.occurTitle = occurTitle;
	this.queryPublisher = queryPublisher;
	this.occurPublisher = occurPublisher;
	this.queryDate = queryDate;
	this.occurDate = occurDate;
	this.queryIdentifier = queryIdentifier;
	this.occurIdentifier = occurIdentifier;
	this.queryDescription = queryDescription;
	this.occurDescription = occurDescription;
	this.querySubject = querySubject;
	this.occurSubject = occurSubject;	
}

SearchAdvancedParameters.prototype.populate = function() {
	var search_param = new SearchParameters();
	search_param.populate();
	this.parameters = search_param;
	this.queryCreator = $("#queryCreator").val();
	this.occurCreator = $("#occurCreator").val();
	this.queryTitle = $("#queryTitle").val();
	this.occurTitle = $("#occurTitle").val();
	this.queryPublisher = $("#queryPublisher").val();
	this.occurPublisher = $("#occurPublisher").val();
	this.queryDate = $("#queryDate").val();		
	this.occurDate = $("#occurDate").val();
	this.queryIdentifier =  $("#queryIdentifier").val();
	this.occurIdentifier = $("#occurIdentifier").val();
	this.queryDescription = $("#queryDescription").val();
	this.occurDescription = $("#occurDescription").val();
	this.querySubject = $("#querySubject").val();
	this.occurSubject = $("#occurSubject").val();  
};

SearchAdvancedParameters.prototype.toArr = function() {
	var arr = this.parameters.toArr();
  	
	arr['queryCreator'] 		= this.queryCreator;
	arr['occurCreator'] 		= this.occurCreator;
	arr['queryTitle'] 		= this.queryTitle;
	arr['occurTitle'] 		= this.occurTitle;
	arr['queryPublisher'] 	= this.queryPublisher;
	arr['occurPublisher'] 	= this.occurPublisher;
	arr['queryDate'] 		= this.queryDate;		
	arr['occurDate'] 		= this.occurDate;
	arr['queryIdentifier'] 	=  this.queryIdentifier;
	arr['occurIdentifier'] 	= this.occurIdentifier;
	arr['queryDescription'] 	= this.queryDescription;
	arr['occurDescription'] 	= this.occurDescription;
	arr['querySubject'] 		= this.querySubject;
	arr['occurSubject'] 		= this.occurSubject;  	
  	return arr;  	
};

SearchAdvancedParameters.prototype.toURLParameters = function() {
	var url_parameters = this.parameters.toURLParameters();
	if(this.queryCreator && this.queryCreator != "")	 {
		url_parameters += "queryCreator=" + this.queryCreator + "&";		
		url_parameters += "occurCreator=" + this.occurCreator + "&";
	}
	if(this.queryTitle && this.queryTitle != "") {	
		url_parameters += "queryTitle=" + this.queryTitle + "&";		
		url_parameters += "occurTitle=" + this.occurTitle + "&";
	}
	if(this.queryPublisher && this.queryPublisher != "") {	
		url_parameters += "queryPublisher=" + this.queryPublisher + "&";		
		url_parameters += "occurPublisher=" + this.occurPublisher + "&";
	}
	if(this.queryDate && this.queryDate != "") {	
		url_parameters += "queryDate=" + this.queryDate + "&";		
		url_parameters += "occurDate=" + this.occurDate + "&";
	}
	if(this.queryIdentifier && this.queryIdentifier != "") {	
		url_parameters += "queryIdentifier=" + this.queryIdentifier + "&";		
		url_parameters += "occurIdentifier=" + this.occurIdentifier + "&";
	}
	if(this.queryDescription && this.queryDescription != "") {	
		url_parameters += "queryDescription=" + this.queryDescription + "&";		
		url_parameters += "occurDescription=" + this.occurDescription + "&";
	}
	if(this.querySubject && this.querySubject != "")	{
		url_parameters += "querySubject=" + this.querySubject + "&";		
		url_parameters += "occurSubject=" + this.occurSubject + "&";
	}
	return url_parameters;
};

/////////////////////////////////////////////////////
// SimpleDTO
////////////////////////////////////////////////////	

function SimpleDTO(id,title,intro,content,url ) {
	this.id 		= id;
	this.title 		= title;	
	this.intro 		= intro;	
	this.content 	= content;
	this.url 		= url;
}

SimpleDTO.prototype.populateWithJSON = function(json) {
	this.id 		= json.id;
	this.title 		= json.title;
	this.url 		= json.url;
	this.intro 		= json.intro;	
	this.content 	= json.content;
};

SimpleDTO.prototype.toLi = function() {
	var html = "<li><h3>";
	if(this.id.substr(0,"POST".length) == "POST") {
		html += "<span class=\"post\">Nota de prensa</span>";
	}
	html += "<a href=\"" +this.url + "\">" + this.title + "</a></h3>";
	html += "<div>" + this.intro + "</div></li>";					
	return html;
};


/////////////////////////////////////////////////////
// DublinCore
////////////////////////////////////////////////////

function DublinCore(id, title, url, intro, content, dcCreator, dcTitle, dcPublisher, dcDate, dcDescription, dcIdentifier, dcCatalogue, dcSubject, dcContributor, dcFormat, dcSource, dcRelation, dcCoverage, dcRights) {
	this.page = new SimpleDTO(id,title,intro,content,url);		
	
	if(dcCreator)
		this.dcCreator 		= dcCreator;
	
	if(dcTitle)
		this.dcTitle 		= dcTitle;
	
	if(dcPublisher)
		this.dcPublisher 	= dcPublisher;
	
	if(dcDate)
		this.dcDate 		= dcDate;
	
	if(dcDescription)
		this.dcDescription 	= dcDescription;
	
	if(dcIdentifier)
		this.dcIdentifier	= dcIdentifier;
	
	if(dcCatalogue)
		this.dcCatalogue  	= dcCatalogue;
	
	if(dcSubject)	
		this.dcSubject		= dcSubject;
	
	if(dcContributor)	
		this.dcContributor 	= dcContributor;
	
	if(dcFormat)
		this.dcFormat		= dcFormat;
	
	if(dcSource)
		this.dcSource		= dcSource;
	
	if(dcRelation)
		this.dcRelation		= dcRelation;
	
	if(dcCoverage)
		this.dcCoverage		= dcCoverage;
	
	if(dcRights)
		this.dcRights		= dcRights;		
}

DublinCore.prototype.populateWithJSON = function(json) {
	this.page = new SimpleDTO(json.id, json.title, json.intro, json.content, json.url);	
	
	// Dublin Core
	if(json.dcCreator)
		this.dcCreator 		= json.dcCreator;
	
	if(json.dcTitle)
		this.dcTitle 		= json.dcTitle;
	
	if(json.dcPublisher)
		this.dcPublisher 	= json.dcPublisher;
	
	if(json.dcDate)
		this.dcDate 		= json.dcDate;
	
	if(json.dcDescription)
		this.dcDescription 	= json.dcDescription;
	
	if(json.dcIdentifier)
		this.dcIdentifier	= json.dcIdentifier;
	
	if(json.dcCatalogue && json.dcCatalogue.id && json.dcCatalogue.title)
		this.dcCatalogue  	= new SimpleDTO(json.dcCatalogue.id,json.dcCatalogue.title);
	
	if(json.dcSubject) 
		this.dcSubject		= json.dcSubject;
	
	if(json.dcContributor)	
		this.dcContributor 	= json.dcContributor;
	
	if(json.dcFormat)
		this.dcFormat		= json.dcFormat;
	
	if(json.dcSource)
		this.dcSource			= json.dcSource;
	
	if(json.dcRelation)
		this.dcRelation		= json.dcRelation;
	
	if(json.dcCoverage)
		this.dcCoverage		= json.dcCoverage;
	
	if(json.dcRights)
		this.dcRights		= json.dcRights;	
};

DublinCore.prototype.toLiDC = function (i) {
	var html = "";
	if(this.page.intro.substr(0,"<img".length) == "<img") {
		html += "<li class=\"image\">";				
		html += "<a href=\"" + this.page.url + "\">";
		html += "<span class=\"title\">" + this.dcIdentifier + "</span>";
		if(this.page.intro) {
			html += "<span class=\"intro noprint\">"+ this.page.intro  + "</span>";
		}	
		html += "</a>";
		if(this.page.title!=null) {
			html += "<span class=\"title\">" + this.page.title + "</span>";
		}					
		html += "</li>";
	} else {			
		html += "<li class=\"dc "+ (((i % 2) == 0) ? "even" : "odd") +"\">";
		html += "<span class=\"identifier noprint\"><a href=\"" + this.page.url + "\">[Detalles]</a></span>";	
		if(this.dcDate && this.dcDate!= "") {			
			html += " <span class=\"date\">"+ this.dcDate +"</span>";
		}	
		if(this.dcTitle && this.dcTitle != "") {
			html += " <span class=\"title\">"+ this.dcTitle +"</span>";
		}	
		if(this.dcCreator && this.dcCreator!="") {			
			html += " <span class=\"creator\">"+ this.dcCreator +"</span>";
		}
		if(this.dcDescription && this.dcDescription!="") {
			html += " <span class=\"description\">"+ ((this.dcDescription.length > 164) ? this.dcDescription.substring(0, 164) + " ..." : this.dcDescription) +"</span>";		
		}
		html += "</li>";
	}
	return html;
};


//////////////////////////////////////////////////////////
//ShoppingCart Class
//////////////////////////////////////////////////////////
function ShoppingCart(items, countryId, shippingCosts) {
	if(items==null) {
		var arr = new Array();
		var itemsInCookie = readCookie("items")
		if(itemsInCookie!=null) {
			var json = jsonParse(itemsInCookie);	
			for(var i = 0; i <json.items.length;i++) {
				arr[i] = new Item(json.items[i].id, json.items[i].price, json.items[i].quantity, json.items[i].description);
			}
		}	 	
	 	this.items = arr;
	} else {
		this.items = items;
	}
	this.countryId = countryId;
	this.shippingCosts = (shippingCosts !=null) ? shippingCosts : null;	
}
ShoppingCart.prototype.setShippingCosts = function(costs) {
	this.shippingCosts = costs;
};

ShoppingCart.prototype.updateItemQuantity = function(itemId,quantity) {
		for(var i = 0; i < this.items.length;i++) {
			if(itemId == this.items[i].id) {
				this.items[i].quantity = parseInt(quantity);
				this.items[i].subtotal = parseInt(quantity) * this.items[i].price;
				return;
			}
		}
};

ShoppingCart.prototype.deleteOfferFromCart = function(offerId) {
	for(var i = 0; i < this.items.length;i++) {
		if(offerId == this.items[i].id) {
			this.items.remove(i);
		}
	}
	if($("body").attr("id") == "checkout") {
		$("tr#offer"+offerId).remove();					
	}		
	this.makePersistent();
	this.updateScreen();	
};

ShoppingCart.prototype.updateScreen = function() {	
	if(this.items.length == 0) {
		$("#emptybasket").show();
		$("#checkoutForm").hide();
		if(document.getElementById("checkoutFormLegend")) {
			$("#checkoutFormLegend").hide();
		}
	} else {
		$("#checkoutForm").show();
		if(document.getElementById("checkoutFormLegend")) {
			$("#checkoutFormLegend").show();
		}
		$("#emptybasket").hide();		
	}
};

ShoppingCart.prototype.addToShoppingCart = function (form) {
	var offerId  	= form["id"].value;
	var price 	 	= form["price"].value;
	var quantity 	= form["quantity"].value;
	var description = form["description"].value;
	var item = new Item(offerId,price,quantity,description)
	this.makePersistent(item);
	this.updateCartMenu();	
	$("div#offer"+offerId).effect("highlight",{},2500);
	$("#cartMenu").effect("highlight",{},2500);
};

ShoppingCart.prototype.makePersistent = function(item) {
	if(item!=null) {
		var alreadyInCart = false;
		for(var i = 0; i < this.items.length;i++) {
			if(item.id == this.items[i].id) {
				this.items[i].quantity = parseInt(this.items[i].quantity) + parseInt(item.quantity);
				alreadyInCart = true;			
			}
		}
		if(!alreadyInCart) {
			this.items[this.items.length] = item;
		}
	}
	var jsonstring = this.toJSONString();	
	writeCookie("items",jsonstring,5*365);	
};

ShoppingCart.prototype.updateCartMenu = function() {
	var subtotal = this.getSubtotal();
	var quantity = this.getNumberOfArticles();
	$("#cartMenu span.quantity").html(quantity);
	$("#cartMenu span.price").html(subtotal.toFixed(2));
};

ShoppingCart.prototype.getNumberOfArticles = function() {
	var numberOfArticles = 0;
	for(var i = 0; i < this.items.length;i++) {
		numberOfArticles += parseInt(this.items[i].quantity);
	}
	return numberOfArticles;
};

ShoppingCart.prototype.toJSONString = function() {
	var jsonString  = "{\"items\": [";
	for(var count=0;count < this.items.length; count++) {
		jsonString += this.items[count].toJSON();
		if(count+1 != this.items.length) {
			jsonString += ",";
		}
	}        
	jsonString += "]}";
	return jsonString;	
};

ShoppingCart.prototype.toHTMLTable = function() {
	for(var i = 0; i < this.items.length;i++) {
		$("#cartItems").prepend(this.items[i].toTR());
	}		
	this.updateOrderOverview();	
};		

ShoppingCart.prototype.getSubtotal = function() {
	var subtotal = 0;
	for(var i=0;i < this.items.length; i++) {
		subtotal += this.items[i].subtotal;
	}
	return subtotal;
};

ShoppingCart.prototype.updateOrderOverview = function() {
	this.countryId = $("#shipping_country").val();
 for(var i=0;i < this.items.length; i++) {
		$("tr#offer"+this.items[i].id + " td.subtotal span.value").html(this.items[i].subtotal.toFixed(2))
	}    	
	var subtotal = this.getSubtotal();
 $("#subtotal").html(subtotal.toFixed(2));
 var shippingCost = this.getShippingCosts();
	$("#shippingCost").html(shippingCost.toFixed(2));
	var total = subtotal + shippingCost;
	$("#total").html(total.toFixed(2));	 
};

ShoppingCart.prototype.getShippingCosts = function() {
	if(this.shippingCosts != null) {
		return this.shippingCosts;
	} else {
		var cartPrice = this.getSubtotal();	
		if(cartPrice==0)
			return 0;
		var envelopePrice = 1.00;		
		var CODCost = 0;
		var extra = 0;				
		if(this.countryId == "194") { //	España
			CODCost = 1.60;
			extra 	 = 4.55;						
		} else if(ShoppingCart.isInCountriesWithCostOnDelivery(this.countryId)) {				
			CODCost = 1.86;
			extra 	 = 4.77;
		}
		var total = cartPrice + envelopePrice + CODCost;
		var moneyOrderCost = total * 0.008; 
		return (CODCost + moneyOrderCost +envelopePrice + extra);
	}
};

//Class Method. Does not access any instance variables
ShoppingCart.isInCountriesWithCostOnDelivery = function(countryId) {
	return (countryId == "81" || // Alemania
		countryId == "3" || // Argelia Algeria
		countryId == "14" || // Austria
		countryId == "21" || // Bélgica
		countryId == "39" || // Cabo Verde
		countryId == "191" || // Eslovenia
		countryId == "73" || // Francia
		countryId == "221" || // Gran Bretaña
		countryId == "103" || // Irlanda
		countryId == "105" || // Italia
		countryId == "117" || // Letonia / LATVIA
		countryId == "124" || // Luxenburgo
		countryId == "144" || // Marruecos
		countryId == "171" || // Portugal
		countryId == "203" || // Suiza
		countryId == "213" || // Túnez
		countryId == "214" || //Turquía
		countryId == "227" // Vaticano
		) ? true : false;		
};

//////////////////////////////////////////////////////
//ITEM constructor
//////////////////////////////////////////////////////
function Item(id,price,quantity,description, subtotal) {
	this.id = id;
	this.price = price;
	this.quantity = quantity;
	this.description = description;
	if(subtotal == null) {
		if(isNaN(quantity) || isNaN(this.price)) {
			this.subtotal = 0;
	 	} else {
			this.subtotal = parseInt(this.quantity) * parseFloat(this.price);
		}
	} else {
		this.subtotal = subtotal;
	}
}

Item.prototype.toTR = function() {
	var html = "<tr class=\"item\" id=\"offer"+this.id+"\">";
	html += "<td>"+this.description+"</td>";
	html += "<td><input type=\"text\" name=\"offer"+this.id+"\" value=\""+this.quantity+"\" maxlength=\"2\" class=\"text quantity\" />&nbsp;&nbsp;<a href=\"javascript:deleteOfferFromCart("+this.id+");\" class=\"red\" title=\"Eliminar este libro de la cesta de la compra\">Eliminar</a></td>";
	html += "<td class=\"price\"><span class=\"value\">"+this.price.toFixed(2)+"</span> €</td>";
	html += "<td class=\"subtotal price\"><span class=\"value\">"+(this.price * this.quantity).toFixed(2)+"</span> €</td>";
	html += "</tr>";
	return html;		
};	

Item.prototype.toJSON = function() {
	return '{ "id": '+this.id+', "price": '+this.price+', "quantity": '+this.quantity+', "description": "'+this.description+'"}';
};

//////////////////////////////////////////////////////
//UTFChartTable constructor
//////////////////////////////////////////////////////
function UTFChartTable(utf_encoded_string) {
	this.utf_encoded_string = utf_encoded_string;
}

UTFChartTable.prototype.getStringWithReplacedCharacters = function () {
	var return_string = "";
			
	return_string = this.utf_encoded_string.replace(/%c2%a1/i,"¡"); // INVERTED EXCLAMATION MARK
	return_string = return_string.replace(/%c2%a2/i,"¢"); // CENT SIGN
	return_string = return_string.replace(/%c2%a3/i,"£"); //POUND SIGN
	return_string = return_string.replace(/%c2%a4/i,"¤"); //CURRENCY SIGN
	return_string = return_string.replace(/%c2%a5/i,"¥"); //YEN SIGN
	return_string = return_string.replace(/%c2%a6/i,"¦"); //BROKEN BAR
	return_string = return_string.replace(/%c2%a7/i,"§"); // SECTION SIGN
	return_string = return_string.replace(/%c2%a8/i,"¨"); //DIAERESIS
	return_string = return_string.replace(/%c2%a9/i,"©"); //COPYRIGHT SIGN
	return_string = return_string.replace(/%c2%aa/i,"ª"); // FEMININE ORDINAL INDICATOR
	return_string = return_string.replace(/%c2%ab/i,"«"); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
	return_string = return_string.replace(/%c2%ac/i,"¬"); //NOT SIGN
	return_string = return_string.replace(/%c2%ad/i,""); //SOFT HYPHEN
	return_string = return_string.replace(/%c2%ae/i,"®"); // REGISTERED SIGN
	return_string = return_string.replace(/%c2%af/i,"¯"); // MACRON
	return_string = return_string.replace(/%c2%b0/i,"°"); // DEGREE SIGN
	return_string = return_string.replace(/%c2%b1/i,"±"); // PLUS-MINUS SIGN
	return_string = return_string.replace(/%c2%b2/i,"²"); // SUPERSCRIPT TWO
	return_string = return_string.replace(/%c2%b3/i,"³"); // SUPERSCRIPT THREE
	return_string = return_string.replace(/%c2%b4/i,"´"); // ACUTE ACCENT
	return_string = return_string.replace(/%c2%b5/i,"µ"); // MICRO SIGN
	return_string = return_string.replace(/%c2%b6/i,"¶"); // PILCROW SIGN
	return_string = return_string.replace(/%c2%b7/i,"·"); // MIDDLE DOT
	return_string = return_string.replace(/%c2%b8/i,"¸"); // CEDILLA
	return_string = return_string.replace(/%c2%b9/i,"¹"); // SUPERSCRIPT ONE
	return_string = return_string.replace(/%c2%ba/i,"º"); // MASCULINE ORDINAL INDICATOR
	return_string = return_string.replace(/%c2%bb/i,"»"); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
	return_string = return_string.replace(/%c2%bc/i,"¼"); // VULGAR FRACTION ONE QUARTER
	return_string = return_string.replace(/%c2%bd/i,"½"); // VULGAR FRACTION ONE HALF
	return_string = return_string.replace(/%c2%be/i,"¾"); // VULGAR FRACTION THREE QUARTERS
	return_string = return_string.replace(/%c2%bf/i,"¿"); // INVERTED QUESTION MARK
	return_string = return_string.replace(/%c3%80/i,"À"); // LATIN CAPITAL LETTER A WITH GRAVE
	return_string = return_string.replace(/%c3%81/i,"Á"); // LATIN CAPITAL LETTER A WITH ACUTE
	return_string = return_string.replace(/%c3%82/i,"Â"); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%83/i,"Ã"); // LATIN CAPITAL LETTER A WITH TILDE
	return_string = return_string.replace(/%c3%84/i,"Ä"); // LATIN CAPITAL LETTER A WITH DIAERESIS
	return_string = return_string.replace(/%c3%85/i,"Å"); // LATIN CAPITAL LETTER A WITH RING ABOVE
	return_string = return_string.replace(/%c3%86/i,"Æ"); // LATIN CAPITAL LETTER AE
	return_string = return_string.replace(/%c3%87/i,"Ç"); // LATIN CAPITAL LETTER C WITH CEDILLA
	return_string = return_string.replace(/%c3%88/i,"È"); // LATIN CAPITAL LETTER E WITH GRAVE
	return_string = return_string.replace(/%c3%89/i,"É"); // LATIN CAPITAL LETTER E WITH ACUTE
	return_string = return_string.replace(/%c3%8a/i,"Ê"); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%8b/i,"Ë"); // LATIN CAPITAL LETTER E WITH DIAERESIS
	return_string = return_string.replace(/%c3%8c/i,"Ì"); // LATIN CAPITAL LETTER I WITH GRAVE
	return_string = return_string.replace(/%c3%8d/i,"Í"); // LATIN CAPITAL LETTER I WITH ACUTE
	return_string = return_string.replace(/%c3%8e/i,"Î"); // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%8f/i,"Ï"); // LATIN CAPITAL LETTER I WITH DIAERESIS
	return_string = return_string.replace(/%c3%90/i,"Ð"); // LATIN CAPITAL LETTER ETH
	return_string = return_string.replace(/%c3%91/i,"Ñ"); // LATIN CAPITAL LETTER N WITH TILDE
	return_string = return_string.replace(/%c3%92/i,"Ò"); // LATIN CAPITAL LETTER O WITH GRAVE
	return_string = return_string.replace(/%c3%93/i,"Ó"); // LATIN CAPITAL LETTER O WITH ACUTE
	return_string = return_string.replace(/%c3%94/i,"Ô"); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%95/i,"Õ"); // LATIN CAPITAL LETTER O WITH TILDE
	return_string = return_string.replace(/%c3%96/i,"Ö"); // LATIN CAPITAL LETTER O WITH DIAERESIS
	return_string = return_string.replace(/%c3%97/i,"×"); // MULTIPLICATION SIGN
	return_string = return_string.replace(/%c3%98/i,"Ø"); // LATIN CAPITAL LETTER O WITH STROKE
	return_string = return_string.replace(/%c3%99/i,"Ù"); // LATIN CAPITAL LETTER U WITH GRAVE	
	return_string = return_string.replace(/%c3%9a/i,"Ú"); // LATIN CAPITAL LETTER U WITH ACUTE
	return_string = return_string.replace(/%c3%9b/i,"Û"); // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%9c/i,"Ü"); // LATIN CAPITAL LETTER U WITH DIAERESIS
	return_string = return_string.replace(/%c3%9d/i,"Ý"); // LATIN CAPITAL LETTER Y WITH ACUTE
	return_string = return_string.replace(/%c3%9e/i,"Þ"); // LATIN CAPITAL LETTER THORN
	return_string = return_string.replace(/%c3%9f/i,"ß"); // LATIN SMALL LETTER SHARP S
	return_string = return_string.replace(/%c3%a0/i,"à"); // LATIN SMALL LETTER A WITH GRAVE
	return_string = return_string.replace(/%c3%a1/i,"á"); //LATIN SMALL LETTER A WITH ACUTE
	return_string = return_string.replace(/%c3%a2/i,"â"); // LATIN SMALL LETTER A WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%a3/i,"ã"); // LATIN SMALL LETTER A WITH TILDE
	return_string = return_string.replace(/%c3%a4/i,"ä"); // LATIN SMALL LETTER A WITH DIAERESIS
	return_string = return_string.replace(/%c3%a5/i,"å"); // LATIN SMALL LETTER A WITH RING ABOVE
	return_string = return_string.replace(/%c3%a6/i,"æ"); // LATIN SMALL LETTER AE
	return_string = return_string.replace(/%c3%a7/i,"ç"); // LATIN SMALL LETTER C WITH CEDILLA
	return_string = return_string.replace(/%c3%a8/i,"è"); // LATIN SMALL LETTER E WITH GRAVE
	return_string = return_string.replace(/%c3%a9/i,"é"); // LATIN SMALL LETTER E WITH ACUTE
	return_string = return_string.replace(/%c3%aa/i,"ê"); // LATIN SMALL LETTER E WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%ab/i,"ë"); // LATIN SMALL LETTER E WITH DIAERESIS
	return_string = return_string.replace(/%c3%ac/i,"ì"); // LATIN SMALL LETTER I WITH GRAVE
	return_string = return_string.replace(/%c3%ad/i,"í"); // LATIN SMALL LETTER I WITH ACUTE
	return_string = return_string.replace(/%c3%ae/i,"î"); // LATIN SMALL LETTER I WITH CIRCUMFLEX
	return_string = return_string.replace(/%c3%af/i,"ï"); // LATIN SMALL LETTER I WITH DIAERESIS
	return_string = return_string.replace(/%c3%b0/i,"ð"); // LATIN SMALL LETTER ETH
    return_string = return_string.replace(/%c3%b1/i,"ñ"); // LATIN SMALL LETTER N WITH TILDE
    return_string = return_string.replace(/%c3%b2/i,"ò"); // LATIN SMALL LETTER O WITH GRAVE
    return_string = return_string.replace(/%c3%b3/i,"ó"); // LATIN SMALL LETTER O WITH ACUTE
    return_string = return_string.replace(/%c3%b4/i,"ô"); // LATIN SMALL LETTER O WITH CIRCUMFLEX
    return_string = return_string.replace(/%c3%b5/i,"õ"); // LATIN SMALL LETTER O WITH TILDE
    return_string = return_string.replace(/%c3%b6/i,"ö"); // LATIN SMALL LETTER O WITH DIAERESIS
    return_string = return_string.replace(/%c3%b7/i,"÷"); // DIVISION SIGN
    return_string = return_string.replace(/%c3%b8/i,"ø"); // LATIN SMALL LETTER O WITH STROKE
    return_string = return_string.replace(/%c3%b9/i,"ù"); // LATIN SMALL LETTER U WITH GRAVE
    return_string = return_string.replace(/%c3%ba/i,"ú"); // LATIN SMALL LETTER U WITH ACUTE
    return_string = return_string.replace(/%c3%bb/i,"û"); // LATIN SMALL LETTER U WITH CIRCUMFLEX
    return_string = return_string.replace(/%c3%bc/i,"ü"); // LATIN SMALL LETTER U WITH DIAERESIS
    return_string = return_string.replace(/%c3%bd/i,"ý"); // LATIN SMALL LETTER Y WITH ACUTE
    return_string = return_string.replace(/%c3%be/i,"þ"); // LATIN SMALL LETTER THORN
	return_string = return_string.replace(/%c3%bf/i,"ÿ"); // LATIN SMALL LETTER Y WITH DIAERESIS
	return return_string;
};