//Custom Dynamic Shopping Cart - built by Angel Leon - Copyright 2009 - FrostWire LLC

/////////////////////////////////////////////////////////
// util DOM functions
/////////////////////////////////////////////////////////
function createNode(tagName,attributes) {
    var node = document.createElement(tagName);
    if (attributes != null)
        for (var key in attributes)
            node.setAttribute(key,attributes[key]);
    return node;
} //createNode                                                                                                                                                                                                                         

function removeChildrenNodes(id) {
    if ($(id).hasChildNodes()) {
        var node = $(id);
        while (node.firstChild)
            node.removeChild(node.firstChild);
    }
} //removeChildrenNodes
/////////////////////////////////////////////////////////

function digits(n) { return 1+Math.floor(Math.log(n)/Math.log(10)); }

/////////////////////////////////////////////////////////
// Classes to model an Order and it's items.
/////////////////////////////////////////////////////////

function Item(index) {
  this.color = COLOR_BLUE;
  this.quantity = 1;
  this.size = SIZE_L;
  this.price = 17.49;  
  this.index = index;

  this.getSubTotal = function () {
      var subTotal = new Number(this.price * this.quantity);
      return subTotal.toFixed(2);
  };

  this.getProductName = function () {
      var colorName =  (this.color == COLOR_BLUE) ? 'Blue' : 'Black';
      return colorName + ' T-Shirt (' + SIZE_NAMES[this.size] + ')';
  };
} //Item

function Order() {
    //A list of (Order) Items
    this.items = new Array();
    this.nextItemId = 1;
    
    this.getItemCount = function() {
	return this.items.length;
    };
    
    this.getNextItemId = function() {
	return this.nextItemId;
    };

    this.findSimilarItemArrayIndex = function (item) {
	for (i in this.items) {
	    var temp = this.items[i];
            if (temp.color == item.color &&
                temp.size == item.size) {
		return i;
	    }
	}
	return null;
    };

    /** 
     * adds or updates an existing item in the order.
     * returns a dictionary that looks like the following:
     * {'item':itemObject,'updated':boolean}
     * 
     */
    this.addItem = function(item) {
	var i = this.findSimilarItemArrayIndex(item);

	if (i != null) {
	    this.items[i].quantity += new Number(item.quantity);
	    return {'updated':true,
		    'item':this.items[i]};
	}

	this.items.push(item);
	this.nextItemId++;
	return {'updated':false,
		'item':item};
    };

    this.removeItem = function(itemId) {
	for (i in this.items) {
	    if (this.items[i].index == itemId) {
		delete (this.items[i])
		this.nextItemId++;//guarantees no repetitions in ids.
	    }
	}
    };
    
    this.getTotal = function() {
	var t=0;
	for (i in this.items) {
	    t += new Number(this.items[i].getSubTotal());
	}
	return t;
    };

    this.getQuantity = function() {
	var q = 0;
	for (i in this.items) {
	    q += this.items[i].quantity;
	}
	return q;
    };
} //class Order

var THE_ORDER = new Order();

/**
 * creates and submits a checkout form to the given payment gateway
 */
function checkOut(paymentGateway) {
    //validate car
    if (THE_ORDER.getTotal() <= 0) {
	alert("There's nothing to check out.\n\nAdd one shirt or more to check out.");
	return;
    }

    //dinamic form to be sent. 
    $('<form>').appendTo('#cart-panel');
    $('form').attr({'method':'POST',
		    'id':'checkOut'});

    // coForm as in check out form
    var coForm = $('#checkOut');

    if (paymentGateway == GOOGLE_GATEWAY) {
	coForm.attr('action',GOOGLE_CHECKOUT_URL);
    } else if (paymentGateway == PAYPAL_GATEWAY) {
	coForm.attr('action',PAYPAL_CHECKOUT_URL);
	coForm.append(getHiddenInputField('cmd','_cart'));//_cart|add_cart
	coForm.append(getHiddenInputField('upload','1'));
	coForm.append(getHiddenInputField('business','contributions@frostwire.com'));
    }

    //now create all the hidden fields
    var index = 1;
    for (var i in THE_ORDER.items) {
	addItemHiddenFormFields(coForm,THE_ORDER.items[i],paymentGateway,index);
	index++;
    }

    //hide buttons and show progress bar
    $('#paypalButton').hide('slow');
    $('#googleButton').hide('slow',function() {
	    $('#ajaxProgressBar').show();
	});

    coForm.submit();
} //checkOut

function getHiddenInputField(name,value) {
    return createNode('input',{'type':'hidden','name':name,'value':value});
} //getHiddenInputField

/**
 * form - form Node
 * item - Item object
 * gateway - char indicating if it's GOOGLE_GATEWAY | PAYPAL_GATEWAY
 * index - integer that's concatenated to field names item_option_price_3, item_name_3
 */
function addItemHiddenFormFields(form,item,gateway,index) {
    if (gateway == GOOGLE_GATEWAY) {
	form.append(getHiddenInputField('item_selection_'+index,index));
	form.append(getHiddenInputField('item_option_name_'+index,item.getProductName()));
	form.append(getHiddenInputField('item_option_price_'+index,item.price));
	form.append(getHiddenInputField('item_option_description_'+index,'American Apparel FrostWire ' + item.getProductName()));
	form.append(getHiddenInputField('item_option_quantity_'+index,String(item.quantity)));
	form.append(getHiddenInputField('item_option_currency_'+index,'USD'));
    } else if (gateway == PAYPAL_GATEWAY) {
	form.append(getHiddenInputField('item_name_'+index,'FrostWire ' + item.getProductName()));
	form.append(getHiddenInputField('amount_'+index,item.price));
	form.append(getHiddenInputField('item_description_'+index,'American Apparel FrostWire ' + item.getProductName()));
	form.append(getHiddenInputField('quantity_'+index,String(item.quantity)));
	form.append(getHiddenInputField('currency_code_'+index,'USD'));
	//form.append(getHiddenInputField('return','http://beta.frostwire.com/shop'));
    }
} //addItemFormFields

/////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////
// Global variables to keep track of the state of the
// item the user might add to the cart.
/////////////////////////////////////////////////////////
var PAYPAL_GATEWAY='0';
var GOOGLE_GATEWAY='1';
var PAYPAL_CHECKOUT_URL="https://www.paypal.com/cgi-bin/webscr";
var GOOGLE_CHECKOUT_URL="https://checkout.google.com/api/checkout/v2/checkoutForm/Merchant/267330020940473";

var BLACK_SHIRT_URL='http://static.frostwire.com/images/tshirts/black_tee.png';
var BLUE_SHIRT_URL='http://static.frostwire.com/images/tshirts/blue_tee.png';

var COLOR_BLUE='0';
var COLOR_BLACK='1';

var CURRENT_COLOR=COLOR_BLUE;
var CURRENT_SIZE=SIZE_L;
var CURRENT_QUANTITY=1;

var SIZE_S='s';
var SIZE_M='m';
var SIZE_L='l';
var SIZE_XL='x';

var SIZE_NAMES = new Array();
SIZE_NAMES[SIZE_S]='Small';
SIZE_NAMES[SIZE_M]='Medium';
SIZE_NAMES[SIZE_L]='Large';
SIZE_NAMES[SIZE_XL]='X-Large';
/////////////////////////////////////////////////////////

function swapTShirts() {
    var black = $('#blackShirt');
    var blue = $('#blueShirt');

    var blackSelector = $('#blackSelector');
    var blueSelector = $('#blueSelector');

    if (CURRENT_COLOR==COLOR_BLUE) {
	blue.hide('slow');
	blueSelector.removeClass('selected');
	blueSelector.addClass('unselected');
	    
	black.show('slow');
	blackSelector.removeClass('unselected');
	blackSelector.addClass('selected');
	CURRENT_COLOR=COLOR_BLACK;
    } else {
	blue.show('slow');
	blueSelector.removeClass('unselected');
	blueSelector.addClass('selected');

	black.hide('slow');
	blackSelector.removeClass('selected');
	blackSelector.addClass('unselected');
        CURRENT_COLOR=COLOR_BLUE;
    }
} //swapTShirts

function switchColor(color) {
    if (color != CURRENT_COLOR)
	swapTShirts();
} //switchColor

function switchSize(size) {
    if (size != CURRENT_SIZE) {
	$('#size_'+CURRENT_SIZE).css('border','1px solid orange');
	CURRENT_SIZE = size;
	$('#size_'+CURRENT_SIZE).css('border','4px solid orange');
    }
} //switchSize

function createTShirtDisplay() {
  var selectionPanel = $('#selection-panel');

  var shirtContainer = createNode('div');
  $(shirtContainer).css('width','205px');
  $(shirtContainer).css('height','185px');

  var blackShirt = createNode('img',{'id':'blackShirt','src':BLACK_SHIRT_URL,'width':'200','height':'185','onClick':'zoomTShirt()'});
  $(blackShirt).css('cursor','pointer');
  $(blackShirt).hide();

  var blueShirt = createNode('img',{'id':'blueShirt','src':BLUE_SHIRT_URL,'width':'200','height':'185','onClick':'zoomTShirt()'});
  $(blueShirt).css('cursor','pointer');
  $(blueShirt).hide();
  $(blueShirt).show('slow');

  $(shirtContainer).append(blackShirt);
  $(shirtContainer).append(blueShirt);
  selectionPanel.append(shirtContainer);
} //createTShirtDisplay

function createZoomTShirtControl() {
  var selectionPanel = $('#selection-panel');
  var zoomTShirtControl = $("<div id=\"zoomInControl\"><a href=\"#\" onClick=\"zoomTShirt()\">Zoom In</div>");
  zoomTShirtControl.css({'position':'absolute','left':'220px','top':'50px'});
  selectionPanel.append(zoomTShirtControl);
}

function zoomTShirt() {
    //disable the zoomInControl
    $("#zoomInControl").hide();

    //get a hold of the current t-shirt
    var currentTShirt = (CURRENT_COLOR == COLOR_BLACK) ? $('#blackShirt'):$('#blueShirt');
    var originalWidth = currentTShirt.attr('width');
    var originalHeight = currentTShirt.attr('height');

    var originalPosition = currentTShirt.css('position');
    var originalZIndex = currentTShirt.css('z-index');

    //disable the onClick event (but keep it for later)
    var originalOnClick = currentTShirt.attr('onClick');
    currentTShirt.attr('onClick','');

    //put it in front
    currentTShirt.css('position','absolute');
    currentTShirt.css('z-index','10');

    //zoom back and restore onClick and z-Index.
    function zoomBack() {
	currentTShirt.animate({'width':originalWidth,'height':originalHeight},
			      2000,
			      function() { 
				  //restore t-shirt and zoom button
				  currentTShirt.css('position',originalPosition);
				  currentTShirt.css('z-index',originalZIndex);
				  currentTShirt.attr('onClick',originalOnClick); 
				  $('#zoomInControl').show();
			      });
   }

    currentTShirt.animate({'width':originalWidth*3, 'height':originalHeight*3},
			  2000,
			  function() { setTimeout(zoomBack,2500); }
			  );
}

function createColorSelectors() {
  //add color selectors container
  var colorSelectors = createNode('div');
  colorSelectors.style.width='110px';
  colorSelectors.style.position='absolute';
  colorSelectors.style.float='right';
  colorSelectors.style.top='145px';
  colorSelectors.style.left='200px';

  // text and line break
   var p = createNode('p');
   $(p).html("Choose Color");
   $(p).css('font-weight','bolder')

  // blue box
  var blueSelector = createNode('div',{'id':'blueSelector',
				       'onClick':'switchColor(COLOR_BLUE)'});
  blueSelector.style.width='40px';
  blueSelector.style.height='40px';
  blueSelector.style.backgroundColor='#baeefb';
  blueSelector.style.float='left';
  blueSelector.style.position='absolute';
  blueSelector.style.display='inline';
  blueSelector.style.cursor='pointer';
  $(blueSelector).addClass('selected');

  // black box
  var blackSelector = createNode('div',{'id':'blackSelector',
					'onClick':'switchColor(COLOR_BLACK)'});
  blackSelector.style.width='40px';
  blackSelector.style.height='40px';
  blackSelector.style.position='absolute';
  blackSelector.style.backgroundColor='#000';
  blackSelector.style.marginLeft='50px';
  blackSelector.style.cursor='pointer';
  $(blackSelector).addClass('unselected');

  colorSelectors.appendChild(p);  
  colorSelectors.appendChild(blueSelector);
  colorSelectors.appendChild(blackSelector);

  var selectionPanel = $('#selection-panel');
  selectionPanel.append(colorSelectors);
} //createColorSelectors

function createSizeSelector(size) {
    var sizeBox = createNode('div',{'id':'size_'+size,
				    'onClick':'switchSize(\''+size+'\')'});
    var text = document.createTextNode(SIZE_NAMES[size]);

    $(sizeBox).css('border','1px solid orange');
    $(sizeBox).css('padding','10px 10px');
    $(sizeBox).css('text-align','center');
    $(sizeBox).css('font-size','11px');
    $(sizeBox).css('position','relative');
    $(sizeBox).css('display','inline');
    $(sizeBox).css('top','15px');
    $(sizeBox).css('margin-right','12px');
    $(sizeBox).css('cursor','pointer');
    $(sizeBox).append(text);

    return $(sizeBox);
} //createSizeSelector

function createSizeSelectors() {
   var sizeSelectors = createNode('div',{'id':'sizeSelectors'});
   var ss = $(sizeSelectors);
   ss.css('width','300px');
   ss.css('height','70px');
   ss.css('margin','10px 10px');
   ss.css('float','left');

   var text = document.createTextNode('Choose T-Shirt Size');
   var p = createNode('p');
   $(p).append(text);
   $(p).css('font-weight','bolder');

   ss.append(p);

   var selS = createSizeSelector(SIZE_S);
   var selM = createSizeSelector(SIZE_M);
   var selL = createSizeSelector(SIZE_L);
   var selXL = createSizeSelector(SIZE_XL);

   CURRENT_SIZE=SIZE_L;
   selL.css('border','4px solid orange');

   //Comment here if you're running out of t-shirt sizes
   ss.append(selS);
   ss.append(selM);
   ss.append(selL);
   ss.append(selXL);

   var selectionPanel = $('#selection-panel');
   selectionPanel.append(ss);

} //createSizeSelectors

function createQuantitySelector() {
    var quantitySelector = createNode('div');
    var qs = $(quantitySelector);
    qs.css('width','290px');
    qs.css('height','100px');
    qs.css('float','left');
    qs.css('position','relative');
    qs.css('top','15px');
    qs.css('left','10px');

    var text = document.createTextNode('How Many do you want?');
    var p = createNode('p');
    $(p).append(text);
    $(p).css('font-weight','bolder');
    $(p).css('display','inline');
    
    qs.append(p);

    var select = createNode('select',
			    {'id':'quantity',
			     'onChange':'updateQuantity()'});
    $(select).css('position','relative');
    $(select).css('left','10px');

    var i=0;
    for (i=0; i < 20; i++) {
	var option = createNode('option',
				{'value':i+1});
	option.value=i+1;
	option.text=i+1;
	select.options.add(option);
    }

    qs.append(select);

    var selectionPanel = $('#selection-panel');
    selectionPanel.append(qs);
} //createQuanitySelector

function updateQuantity() {
    var quantity = $('#quantity').val()

    if (quantity == CURRENT_QUANTITY ||
	quantity < 1)
	return;

    if (quantity > 1) {
	$('#addToCartButton').val('Add Shirts To Cart');
	//console.log('plural');
    } else {
	$('#addToCartButton').val('Add Shirt To Cart');
	//console.log('singular');
    }

    CURRENT_QUANTITY = quantity;
}//updateQuantity

function createAddToCartButton() {
    var button = createNode('input',
			    {'id':'addToCartButton',
			     'onClick':'addToOrder()',
			     'value':'Add Shirt To Cart',
			     'type':'button'});
    button.value='Add Shirt To Cart';
    $(button).css('position','relative');
    $(button).css('width','310px');
    $(button).css('height','50px');
    $(button).css('font-size','30px');
    $(button).css('font-weight','bolder');
    $(button).css('top','-50px');

    var selectionPanel = $('#selection-panel');
    selectionPanel.append(button);
} //createAddToCartButton

/**
 * Creates the controls on the left to choose the t-shirt you're about to add to the shopping cart.
 */
function createSelectionPanel() {
  createTShirtDisplay();
  createZoomTShirtControl();
  createColorSelectors();
  createSizeSelectors();
  createQuantitySelector();
  createAddToCartButton();
} //createSelectionPanel

function createTotalsContainer() {
    //Checkout Controls
    var checkoutControls = createNode('div',{'clear':'bottom'});
    $(checkoutControls).css('float','left');
   
    var paypalButton = createNode('input',{'type':'image',
					   'id':'paypalButton',
					   'src':'http://static.frostwire.com/images/143x26paypal_checkout_button.png',
	                                   'onClick':'checkOut(PAYPAL_GATEWAY);'});
    $(paypalButton).css('display','block');
    $(paypalButton).css('position','relative');
    $(paypalButton).css('top','10px');
    $(paypalButton).css('margin-bottom','10px');

    var googleButton = createNode('input',{'type':'image',
					   'id':'googleButton',
					   'src':'http://static.frostwire.com/images/143x26google_checkout_button.png',
					   'onClick':'checkOut(GOOGLE_GATEWAY);'});
    $(googleButton).css('position','relative');
    $(googleButton).css('top','10px');

    //ajax progress bar, hidden until checkout is submitted
    var ajaxProgressBar = createNode('img',{'id':'ajaxProgressBar',
					    'src':'http://static1.frostwire.com/images/ajax_progress_bar.gif'});
    $(ajaxProgressBar).hide();

    $(checkoutControls).append(paypalButton);
    $(checkoutControls).append(googleButton);
    $(checkoutControls).append(ajaxProgressBar);
    
    //Totals Display
    var totalsContainer = createNode('span',{'id':'totalsContainer'});
    $(totalsContainer).css('width','250px');
    $(totalsContainer).css('height','80px');

    var totalsLabels = createNode('div',{'id':'totalsLabels'});
    $(totalsLabels).css('font-size','25px');
    $(totalsLabels).css('float','right');
    $(totalsLabels).html("<strong>Total</strong>: $0 <br/>Shirts: 0");
    
    $(totalsContainer).append(totalsLabels);


    // All contained on a cart header
    var cartHeaderContainer = createNode('div',{'clear':'all'});
    $(cartHeaderContainer).css('margin-top','10px');
    $(cartHeaderContainer).css('width','100%');
    $(cartHeaderContainer).append(checkoutControls);
    $(cartHeaderContainer).append(totalsContainer);
    
    var br = createNode('br',{'clear':'all'});
    $(cartHeaderContainer).append(br);

    // Free Shipping
    var freeShippingLabel = createNode('div');
    $(freeShippingLabel).css('margin-top','20px');
    $(freeShippingLabel).css('text-align','center');
    $(freeShippingLabel).html("<h2>Free Shipping World Wide</h2>");

    $(cartHeaderContainer).append(freeShippingLabel);

   $('#cart-panel').append(cartHeaderContainer);
} //createTotalsContainer

function updateTotalsLabels() {
    var totals = "<strong>Total</strong>: $"+ Number(THE_ORDER.getTotal()).toFixed(2) + "<br/>Shirts: "+THE_ORDER.getQuantity();

    var checkoutControls = "";
    $('#totalsLabels').html(totals + checkoutControls);
} //updateTotalsLabels

/**
 * Adds the current t-shirt on the controls to the order, and to the
 * cart panel (visually) see addNewItemContainer(newItem)
 */
function addToOrder() {
    //1. Create Item Object from parameters.
    var newItem = new Item(THE_ORDER.getNextItemId());
    newItem.color = CURRENT_COLOR;
    newItem.quantity = new Number(CURRENT_QUANTITY);
    newItem.size = CURRENT_SIZE;

    var result =  THE_ORDER.addItem(newItem);

    if (!result['updated']) {
	addNewItemContainer(result['item']);
    } else {
	updateItemContainer(result['item']);
    }

    updateTotalsLabels();
} //addToCart

function removeFromOrder(itemId) {
    THE_ORDER.removeItem(itemId);
    $('#itemContainer_'+itemId).slideUp('fast',
	function() {
	    $('#itemContainer_'+itemId).remove();
	});
    
    updateTotalsLabels();
}

/**
 * Where all the order items will be visible.
 */
function createItemsContainer() {
    var itemsContainer = createNode('div',{'id':'itemsContainer'});
    $('#cart-panel').append(itemsContainer);    
} //createItemsContainer

/**
 * Ads a new visible item to the cart given an Item object
 */
function addNewItemContainer(newItem) {
    var itemContainer = createNode('div',{'id':'itemContainer_'+newItem.index});

    var shirt = createNode('img',{'src': (newItem.color == COLOR_BLUE) ? BLUE_SHIRT_URL : BLACK_SHIRT_URL,
				  'width':'50',
				  'height':'46'});
    $(shirt).css('display','inline');
    $(itemContainer).append(shirt);

    var fontSize = (digits(newItem.getSubTotal())<5) ? '28px':'26px';

    //how many t-shirts, what size.
    var itemDescription = createNode('span', {'id':'itemDescription_'+newItem.index});
    $(itemDescription).css('font-size','24px');
    $(itemDescription).css('position','relative');
    $(itemDescription).css('top','-10px');
    $(itemDescription).css('margin-left','5px');
    $(itemDescription).html('x ' + newItem.quantity + ' (' + SIZE_NAMES[newItem.size] + ')');

    var removeButton = createNode('input',{'type':'image',
					   'value':'remove',
					   'width':'35','height':'35',
					   'src':'http://static.frostwire.com/images/35x35remove_button.png',
					   'onClick':'removeFromOrder('+newItem.index+')'});
    $(removeButton).css('float','right');
    $(removeButton).css('position','relative');
    $(removeButton).css('top','10px');

    var itemSubTotal = createNode('span',{'id':'itemSubTotal_'+newItem.index});
    $(itemSubTotal).css('font-size','24px');
    $(itemSubTotal).css('position','relative');
    $(itemSubTotal).css('top','16px');
    $(itemSubTotal).css('margin-right','10px');
    $(itemSubTotal).css('float','right');
    $(itemSubTotal).css('color','#7af');
    $(itemSubTotal).html('$'+ newItem.getSubTotal());

    $(itemContainer).append(itemDescription);
    $(itemContainer).append(removeButton);
    $(itemContainer).append(itemSubTotal);

    //finally add to the items container
    $('#itemsContainer').append(itemContainer);
    $(itemContainer).hide();
    $(itemContainer).slideDown('fast');

    repackFontSizes(newItem);
} //addNewItemContainer

function updateItemContainer(item) {
    $('#itemDescription_'+item.index).html('x ' + item.quantity + ' (' + SIZE_NAMES[item.size] + ')');
    $('#itemSubTotal_'+item.index).html('$'+ item.getSubTotal());
    repackFontSizes(item);
} //updateItemContainer

function repackFontSizes(item) {
    //make font smaller if numbers are growing too much
    if (digits(item.getSubTotal())>3) {
	$('#itemDescription_'+item.index).css('font-size','24px');
	$('#itemSubTotal_'+item.index).css('font-size','24px');
	$('#itemSubTotal_'+item.index).css('top','16px');
    } 

    if (digits(item.getSubTotal())>4) {
	$('#itemDescription_'+item.index).css('font-size','18px');
	$('#itemDescription_'+item.index).css('top','-15px');
	$('#itemSubTotal_'+item.index).css('font-size','18px');
	$('#itemSubTotal_'+item.index).css('top','17px');
    }
} //repackFontSizes

/**
 * Creates the elements that display all the items in the order
 */
function createCartPanel() {
    createItemsContainer();
    createTotalsContainer();
} //createCartPanel

createSelectionPanel();
createCartPanel();