var Cart = Class.create({

	initialize: function(capacity) {
		this.seats = new Hash();
		this.singleSeatCount = 0;
		this.gaSeatCount = 0;
		this.seatId = 1;
		this.capacity = capacity;
		
		//todo explain the structure of the hash
	},

	setMaxTicketLimit: function(capacity) {
		this.capacity = capacity;
	},

	getNextId: function() {
		if(this.seats.length == 0) {
			return 1;
		}
		else {
			return (this.seats.last().getId() + 1);
		}
	},
	
	addSeat: function(seat) {
		
		if(this.isFull())
			return;
		
		if(seat.isGA())   // is this piece really valid??
		{
			seat.setId(this.seatId);
			this.seatId++;

			if(this.contains(seat))				
				this.seats.get(seat.getSeatId()).push(seat);
			else
			{	
				var GASeats = new Array();
				GASeats.push(seat);
				this.seats.set(seat.getSeatId(),GASeats);
			}	
			
			this.gaSeatCount++;
		}
		else if(!this.contains(seat))
		{	
			this.seats.set(seat.getSeatId(),seat);
			this.singleSeatCount++;
		}
	},
	
	removeSeat: function(seatId, gaId)
	{
		var seat = this.getSeat(seatId);
		
		if(!this.contains(seat))
			return false;
		
//		var seatId = seat.getSeatId();
		if(seat.isGA())
		{
			for(var i = 0; i < this.seats.get(seatId).length; i++) {
				if(this.seats.get(seatId)[i].getId() == gaId) {
					this.seats.get(seatId).splice(i, 1);
				}				
			}
			
			if(this.seats.get(seatId).length == 0)
				this.seats.unset(seatId);
			this.gaSeatCount--;
		}
		else {
			this.seats.unset(seatId);
			this.singleSeatCount--;
		}
	},
	

	getSeat: function(seatId) {
		var seat = this.seats.get(seatId);

		//if(!this.contains(seat))
		//	return false;

		if(Object.isArray(seat)) // Then it's GA
			return this.seats.get(seatId).first();
		else
			return this.seats.get(seatId);  

	},
	
	getSeats: function() {
		return this.seats;
	},

	getSeatsArray: function() {
		var seatArray = new Array();
		this.seats.each(function(s) {
			// General admission
			if(Object.isArray(s.value)) {
				s.value.each(function(gas) {
					seatArray.push(gas);
				});
			// Single seat
			} else {
				seatArray.push(s.value);
			}
		});
		return seatArray;
	},
	
	getSeatById: function(id) {
		var seat;
		this.seats.each(function(s) {
			if(s.getId() == id) {
				seat = s;
			}
		});
		return seat;
	},
	
	updatePriceType: function(seat, rowId, priceTypeNumber) {
		var priceTypeInfo = seatmap.getPriceTypeInfo(priceTypeNumber);
		var formattedPrice = seatmap.getPriceInfo(seat.getPriceCategory(), priceTypeNumber).priceFormatted;
		if(seat.isGA()) {
			var seats = this.seats.get(seat.getSeatId());
			for(var i=0; i<seats.length; i++) {
				if(seats[i].getId() == seat.getId()) {
					seats[i].setPriceTypeNumber(priceTypeInfo.number);
					seats[i].setPriceTypeCode(priceTypeInfo.code);
					$(rowId).childElements()[5].update(formattedPrice);
				}
			}
		} else {
			seat.setPriceTypeNumber(priceTypeInfo.number);
			seat.setPriceTypeCode(priceTypeInfo.code);
			$(rowId).childElements()[5].update(formattedPrice);
		}
		seatmap.cartView.updateTotalPrice();
	},
	
	/** 
	 * return 1 if cart contains the single seat
	 * if it is a GA seat it will return the number of GA seats
	 */
	contains: function(seat)
	{
		var seatId = seat.getSeatId();
		if(this.seats.get(seatId)==undefined)
			return 0;
		else 
		{
			if(seat.isGA())
				return this.seats.get(seatId).length;
			else
				return 1;
		};
	},

	empty:function()
	{
		this.seats = new Hash();
		this.singleSeatCount = 0;
		this.gaSeatCount = 0;
	},
	
	getSize:function()
	{		
		return (this.singleSeatCount + this.gaSeatCount);
	},
	isFull:function()
	{
		if(this.getSize() >= this.capacity)
			return true;
		else 
			return false;
	},
	
	toArray:function(){
		
		var arr = new Array()
		this.seats.each(function(pair){
			if(Object.isArray(pair.value)) //GA seats
			{
				for(var i =0; i<pair.value.length;i++)
					arr.push(pair.value[i]);
			}
			else
				arr.push(pair.value);
		});
		
		return arr;	
	},
	
	getTotalPrice: function() {
		var totalPrice = 0;
		var priceInfo;
		
		this.toArray().each(function(s) {
			priceInfo = seatmap.getPriceInfo(s.getPriceCategory(), s.getPriceTypeNumber());
			
			if(priceInfo != undefined)
				totalPrice += parseInt(priceInfo.price);
		});
		
		return totalPrice;
	},
	
	toWidgetJson:function() 
	{
		var arr = new Array();
		
		this.seats.each(function(pair){
			var value = pair.value;
			if(Object.isArray(value)) //GA seats
			{
/* 				//Currently do not send the GA seats to the widget
				value.each(function(a) {
					arr.push(a.toWidgetJson());
				});
*/
			}
			else
				arr.push(value.toWidgetJson());
		});
			
		return arr;
	}

});
			

function testAdd()
{
	var testData = createTestData();
	var cart = new Cart();

    for(var i = 0;i<testData.length;i++)
    	cart.addSeat(testData[i]);
	    
	    //verify that the elements is contained 
	    var exists = true;

	    var seat = testData[0];
	    var seat2 = testData[1];
	    var seatGA = testData[2];
	    
	    var errorcount = 0;
	    if(!cart.contains(seat))
	    {
	    	log("seat is not added correctly");
	    	errorcount++;
	    }
	    if(!cart.contains(seat2) )
	    {	
	    	log("seat2 is not added correctly");
	    	errorcount++;
	    }
	    if(cart.contains(seatGA) !=2)
	    {
	    	log("seatGA is not added correctly");
	    	errorcount++;
	    }
	   
	    
	    //verify that all elements in the cart exists
	    var expectedSize = 4;
	    if(cart.getSize()!=expectedSize)
	    {
	    	//log("size is"+ cart.getSize()+ "expected" + expectedSize)
	    	errorcount++;
	    }	
	    	
	     log("testAdd finished errors found: " + errorcount);

				
	
}


function testRemove()
{
	var testData = createTestData();
	var cart = new Cart();

    for(var i = 0;i<testData.length;i++)
    	cart.addSeat(testData[i]);
    
    //test to remove a single seat 
    //verify that it does not exist anymore
    //testto remove a ga seat, verify that only one is removed
    var seat = testData[0];
    var seat2 = testData[1];
    var seatGA = testData[2];
    
    
    cart.removeSeat(seat2);
    
    var errorcount = 0;
    if(cart.contains(seat2))  // the cart should no longer contain the removed seat
    {
    	log("seat 2 is not removed");
    	errorcount++;
    }
    
    cart.removeSeat(seatGA); 
    if(cart.contains(seatGA)!= 1) //the cart should still contain one of the GA seats
    {
    	log("seatGA is not removed correctly");
    	errorcount++;
    }	
    	
    if(cart.getSize()!= 2)
    {
    	log("cart size is: " + cart.getSize() +" expected cart size to be 2" );
    	errorcount++;
    }
    
    //verify that the rest of the cart is unchanged
    if(!cart.contains(seat) || !cart.contains(seatGA))
    {
    	log("cart state is not valid");
    	errorcount++;
    }
    
    
    log("testRemove finished errors found: " + errorcount);  
}


function testToArray()
{
	var testData = createTestData();
	var cart = new Cart();

    for(var i = 0;i<testData.length;i++)
    	cart.addSeat(testData[i]);
    
  
    var result = cart.toArray();
    
    var errorcount = 0; 
    if(result.length !=testData.length)
    {
    	log("sizes dont match, expected size is "+ testData.length +" resulting size is " + result.length);
    	errorcount++;
    }	
	
    //TODO should match the contents also, could not find an easy way to check the equality of objects
    
    log("testToArray finished errors found: " + errorcount);  

}

//should return an empty json object
function testToArrayEmpty()
{
}

function testToWidgetJson()
{
	var testData = createTestData();
	var cart = new Cart();

    for(var i = 0;i<testData.length;i++)
    	cart.addSeat(testData[i]);
	
	//call to widget json
    var json = cart.toWidgetJson();
    
    var errorcount = 0;
    var expected = 4;
	if(json.seats.length != expected)
		log("sizes dont match, expected size is " +json.seats.length+" resulting size is " + expected);
	
	log("testToWidgetJson finished errors found: " + errorcount);

}

function createTestData()
{
		var arr = new Array();
		
	    var seat =  new Seat();
	    seat.setSeat(1);
	    seat.setRow("ROW1");
	    seat.setLevelSection("LEVEL1-SECTION1");
	    seat.setLevel("LEVEL1");
	    seat.setSection("SECTION1");
	    seat.setGeneralAdmission(false);
	    seat.setPriceCategory("PRICE1");
	    
	    var seat2 =  new Seat();
	    seat2.setSeat(30);
	    seat2.setRow("ROW2");
	    seat2.setLevelSection("LEVEL2");
	    seat2.setLevel("LEVEL2");
	    seat2.setGeneralAdmission(false);
	    seat2.setPriceCategory("PRICE2");
	    
	    var seatGA =  new Seat();
	    seatGA.setLevelSection("LEVEL1-SECTION1");
	    seatGA.setPriceCategory("PRICE3");
	    seatGA.setGeneralAdmission(true);
	    
	    
	    arr.push(seat);
	    arr.push(seat2);
	    arr.push(seatGA);
	    arr.push(seatGA);
	    
	    return arr;
	    
		
}

			
function runTests()
{
	testAdd();
	testRemove();
	testToArray();
	testToWidgetJson();
	
	
}
			

			

