// global variables ////////////////////////////////////////////////////////////

function BuildTags()
{
	var msg = '';
	msg += '<div align="center" id="tag_playarea" style="position:absolute;top:50;left:50;width:720;height:500;" onmousemove="playarea.mouseMove(event);">';
	msg += '<div id="tag_deck" style="position:absolute;width:200;height:100;top:20;left:20;background-color:blue;visibility:hidden;"></div>';
	msg += '<img id="tag_stack1" src="images/stack.gif" style="position:absolute;width:71;height:96;top:20;left:320;"></img>';
	msg += '<img id="tag_stack2" src="images/stack.gif" style="position:absolute;width:71;height:96;top:20;left:420;"></img>';
	msg += '<img id="tag_stack3" src="images/stack.gif" style="position:absolute;width:71;height:96;top:20;left:520;"></img>';
	msg += '<img id="tag_stack4" src="images/stack.gif" style="position:absolute;width:71;height:96;top:20;left:620;"></img>';
	msg += '<div id="tag_row1" style="position:absolute;width:71;height:96;top:150;left:20;"></div>';
	msg += '<div id="tag_row2" style="position:absolute;width:71;height:96;top:150;left:120;background-color:blue;visibility:hidden;"></div>';
	msg += '<div id="tag_row3" style="position:absolute;width:71;height:96;top:150;left:220;background-color:blue;visibility:hidden;"></div>';
	msg += '<div id="tag_row4" style="position:absolute;width:71;height:96;top:150;left:320;background-color:blue;visibility:hidden;"></div>';
	msg += '<div id="tag_row5" style="position:absolute;width:71;height:96;top:150;left:420;background-color:blue;visibility:hidden;"></div>';
	msg += '<div id="tag_row6" style="position:absolute;width:71;height:96;top:150;left:520;background-color:blue;visibility:hidden;"></div>';
	msg += '<div id="tag_row7" style="position:absolute;width:71;height:96;top:150;left:620;background-color:blue;visibility:hidden;"></div>';
	msg += '<img id="h2" src="images/h2.gif" style="position:absolute;width:71;height:96" onclick="card_h2.mouseClick(event);"></img>';
	msg += '<img id="h3" src="images/h3.gif" style="position:absolute;width:71;height:96" onclick="card_h3.mouseClick(event);"></img>';
	msg += '<img id="h4" src="images/h4.gif" style="position:absolute;width:71;height:96" onclick="card_h4.mouseClick(event);"></img>';
	msg += '<img id="h5" src="images/h5.gif" style="position:absolute;width:71;height:96" onclick="card_h5.mouseClick(event);"></img>';
	msg += '<img id="h6" src="images/h6.gif" style="position:absolute;width:71;height:96" onclick="card_h6.mouseClick(event);"></img>';
	msg += '<img id="h7" src="images/h7.gif" style="position:absolute;width:71;height:96" onclick="card_h7.mouseClick(event);"></img>';
	msg += '<img id="h8" src="images/h8.gif" style="position:absolute;width:71;height:96" onclick="card_h8.mouseClick(event);"></img>';
	msg += '<img id="h9" src="images/h9.gif" style="position:absolute;width:71;height:96" onclick="card_h9.mouseClick(event);"></img>';
	msg += '<img id="h10" src="images/h10.gif" style="position:absolute;width:71;height:96" onclick="card_h10.mouseClick(event);"></img>';
	msg += '<img id="h11" src="images/h11.gif" style="position:absolute;width:71;height:96" onclick="card_h11.mouseClick(event);"></img>';
	msg += '<img id="h12" src="images/h12.gif" style="position:absolute;width:71;height:96" onclick="card_h12.mouseClick(event);"></img>';
	msg += '<img id="h13" src="images/h13.gif" style="position:absolute;width:71;height:96" onclick="card_h13.mouseClick(event);"></img>';
	msg += '<img id="h14" src="images/h14.gif" style="position:absolute;width:71;height:96" onclick="card_h14.mouseClick(event);"></img>';
	msg += '<img id="d2" src="images/d2.gif" style="position:absolute;width:71;height:96" onclick="card_d2.mouseClick(event);"></img>';
	msg += '<img id="d3" src="images/d3.gif" style="position:absolute;width:71;height:96" onclick="card_d3.mouseClick(event);"></img>';
	msg += '<img id="d4" src="images/d4.gif" style="position:absolute;width:71;height:96" onclick="card_d4.mouseClick(event);"></img>';
	msg += '<img id="d5" src="images/d5.gif" style="position:absolute;width:71;height:96" onclick="card_d5.mouseClick(event);"></img>';
	msg += '<img id="d6" src="images/d6.gif" style="position:absolute;width:71;height:96" onclick="card_d6.mouseClick(event);"></img>';
	msg += '<img id="d7" src="images/d7.gif" style="position:absolute;width:71;height:96" onclick="card_d7.mouseClick(event);"></img>';
	msg += '<img id="d8" src="images/d8.gif" style="position:absolute;width:71;height:96" onclick="card_d8.mouseClick(event);"></img>';
	msg += '<img id="d9" src="images/d9.gif" style="position:absolute;width:71;height:96" onclick="card_d9.mouseClick(event);"></img>';
	msg += '<img id="d10" src="images/d10.gif" style="position:absolute;width:71;height:96" onclick="card_d10.mouseClick(event);"></img>';
	msg += '<img id="d11" src="images/d11.gif" style="position:absolute;width:71;height:96" onclick="card_d11.mouseClick(event);"></img>';
	msg += '<img id="d12" src="images/d12.gif" style="position:absolute;width:71;height:96" onclick="card_d12.mouseClick(event);"></img>';
	msg += '<img id="d13" src="images/d13.gif" style="position:absolute;width:71;height:96" onclick="card_d13.mouseClick(event);"></img>';
	msg += '<img id="d14" src="images/d14.gif" style="position:absolute;width:71;height:96" onclick="card_d14.mouseClick(event);"></img>';
	msg += '<img id="c2" src="images/c2.gif" style="position:absolute;width:71;height:96" onclick="card_c2.mouseClick(event);"></img>';
	msg += '<img id="c3" src="images/c3.gif" style="position:absolute;width:71;height:96" onclick="card_c3.mouseClick(event);"></img>';
	msg += '<img id="c4" src="images/c4.gif" style="position:absolute;width:71;height:96" onclick="card_c4.mouseClick(event);"></img>';
	msg += '<img id="c5" src="images/c5.gif" style="position:absolute;width:71;height:96" onclick="card_c5.mouseClick(event);"></img>';
	msg += '<img id="c6" src="images/c6.gif" style="position:absolute;width:71;height:96" onclick="card_c6.mouseClick(event);"></img>';
	msg += '<img id="c7" src="images/c7.gif" style="position:absolute;width:71;height:96" onclick="card_c7.mouseClick(event);"></img>';
	msg += '<img id="c8" src="images/c8.gif" style="position:absolute;width:71;height:96" onclick="card_c8.mouseClick(event);"></img>';
	msg += '<img id="c9" src="images/c9.gif" style="position:absolute;width:71;height:96" onclick="card_c9.mouseClick(event);"></img>';
	msg += '<img id="c10" src="images/c10.gif" style="position:absolute;width:71;height:96" onclick="card_c10.mouseClick(event);"></img>';
	msg += '<img id="c11" src="images/c11.gif" style="position:absolute;width:71;height:96" onclick="card_c11.mouseClick(event);"></img>';
	msg += '<img id="c12" src="images/c12.gif" style="position:absolute;width:71;height:96" onclick="card_c12.mouseClick(event);"></img>';
	msg += '<img id="c13" src="images/c13.gif" style="position:absolute;width:71;height:96" onclick="card_c13.mouseClick(event);"></img>';
	msg += '<img id="c14" src="images/c14.gif" style="position:absolute;width:71;height:96" onclick="card_c14.mouseClick(event);"></img>';
	msg += '<img id="s2" src="images/s2.gif" style="position:absolute;width:71;height:96" onclick="card_s2.mouseClick(event);"></img>';
	msg += '<img id="s3" src="images/s3.gif" style="position:absolute;width:71;height:96" onclick="card_s3.mouseClick(event);"></img>';
	msg += '<img id="s4" src="images/s4.gif" style="position:absolute;width:71;height:96" onclick="card_s4.mouseClick(event);"></img>';
	msg += '<img id="s5" src="images/s5.gif" style="position:absolute;width:71;height:96" onclick="card_s5.mouseClick(event);"></img>';
	msg += '<img id="s6" src="images/s6.gif" style="position:absolute;width:71;height:96" onclick="card_s6.mouseClick(event);"></img>';
	msg += '<img id="s7" src="images/s7.gif" style="position:absolute;width:71;height:96" onclick="card_s7.mouseClick(event);"></img>';
	msg += '<img id="s8" src="images/s8.gif" style="position:absolute;width:71;height:96" onclick="card_s8.mouseClick(event);"></img>';
	msg += '<img id="s9" src="images/s9.gif" style="position:absolute;width:71;height:96" onclick="card_s9.mouseClick(event);"></img>';
	msg += '<img id="s10" src="images/s10.gif" style="position:absolute;width:71;height:96" onclick="card_s10.mouseClick(event);"></img>';
	msg += '<img id="s11" src="images/s11.gif" style="position:absolute;width:71;height:96" onclick="card_s11.mouseClick(event);"></img>';
	msg += '<img id="s12" src="images/s12.gif" style="position:absolute;width:71;height:96" onclick="card_s12.mouseClick(event);"></img>';
	msg += '<img id="s13" src="images/s13.gif" style="position:absolute;width:71;height:96" onclick="card_s13.mouseClick(event);"></img>';
	msg += '<img id="s14" src="images/s14.gif" style="position:absolute;width:71;height:96" onclick="card_s14.mouseClick(event);"></img>';

	var tag = document.getElementById('kabal');
	tag.innerHTML += msg;
}

// building tags
BuildTags();

front_image = 'images/card_robot.gif';

playarea = new PlayArea('tag_playarea');
deck = new Deck('tag_deck');
row1 = new Row('tag_row1');
row2 = new Row('tag_row2');
row3 = new Row('tag_row3');
row4 = new Row('tag_row4');
row5 = new Row('tag_row5');
row6 = new Row('tag_row6');
row7 = new Row('tag_row7');
cardstack1 = new CardStack('tag_stack1');
cardstack2 = new CardStack('tag_stack2');
cardstack3 = new CardStack('tag_stack3');
cardstack4 = new CardStack('tag_stack4');

card_h2 = new Card(null, 'front', 'heart', 2, 'h2');
card_h3 = new Card(null, 'front', 'heart', 3, 'h3'); 
card_h4 = new Card(null, 'front', 'heart', 4, 'h4');
card_h5 = new Card(null, 'front', 'heart', 5, 'h5'); 
card_h6 = new Card(null, 'front', 'heart', 6, 'h6'); 
card_h7 = new Card(null, 'front', 'heart', 7, 'h7');
card_h8 = new Card(null, 'front', 'heart', 8, 'h8'); 
card_h9 = new Card(null, 'front', 'heart', 9, 'h9'); 
card_h10 = new Card(null, 'front', 'heart', 10, 'h10');
card_h11 = new Card(null, 'front', 'heart', 11, 'h11'); 
card_h12 = new Card(null, 'front', 'heart', 12, 'h12'); 
card_h13 = new Card(null, 'front', 'heart', 13, 'h13');
card_h14 = new Card(null, 'front', 'heart', 14, 'h14');

card_d2 = new Card(null, 'front', 'diamond', 2, 'd2'); 
card_d3 = new Card(null, 'front', 'diamond', 3, 'd3'); 
card_d4 = new Card(null, 'front', 'diamond', 4, 'd4');
card_d5 = new Card(null, 'front', 'diamond', 5, 'd5'); 
card_d6 = new Card(null, 'front', 'diamond', 6, 'd6'); 
card_d7 = new Card(null, 'front', 'diamond', 7, 'd7');
card_d8 = new Card(null, 'front', 'diamond', 8, 'd8'); 
card_d9 = new Card(null, 'front', 'diamond', 9, 'd9'); 
card_d10 = new Card(null, 'front', 'diamond', 10, 'd10');
card_d11 = new Card(null, 'front', 'diamond', 11, 'd11'); 
card_d12 = new Card(null, 'front', 'diamond', 12, 'd12'); 
card_d13 = new Card(null, 'front', 'diamond', 13, 'd13');
card_d14 = new Card(null, 'front', 'diamond', 14, 'd14');

card_c2 = new Card(null, 'front', 'club', 2, 'c2'); 
card_c3 = new Card(null, 'front', 'club', 3, 'c3'); 
card_c4 = new Card(null, 'front', 'club', 4, 'c4');
card_c5 = new Card(null, 'front', 'club', 5, 'c5'); 
card_c6 = new Card(null, 'front', 'club', 6, 'c6'); 
card_c7 = new Card(null, 'front', 'club', 7, 'c7');
card_c8 = new Card(null, 'front', 'club', 8, 'c8'); 
card_c9 = new Card(null, 'front', 'club', 9, 'c9'); 
card_c10 = new Card(null, 'front', 'club', 10, 'c10');
card_c11 = new Card(null, 'front', 'club', 11, 'c11'); 
card_c12 = new Card(null, 'front', 'club', 12, 'c12'); 
card_c13 = new Card(null, 'front', 'club', 13, 'c13');
card_c14 = new Card(null, 'front', 'club', 14, 'c14');

card_s2 = new Card(null, 'front', 'spade', 2, 's2'); 
card_s3 = new Card(null, 'front', 'spade', 3, 's3'); 
card_s4 = new Card(null, 'front', 'spade', 4, 's4');
card_s5 = new Card(null, 'front', 'spade', 5, 's5'); 
card_s6 = new Card(null, 'front', 'spade', 6, 's6'); 
card_s7 = new Card(null, 'front', 'spade', 7, 's7');
card_s8 = new Card(null, 'front', 'spade', 8, 's8'); 
card_s9 = new Card(null, 'front', 'spade', 9, 's9'); 
card_s10 = new Card(null, 'front', 'spade', 10, 's10');
card_s11 = new Card(null, 'front', 'spade', 11, 's11'); 
card_s12 = new Card(null, 'front', 'spade', 12, 's12'); 
card_s13 = new Card(null, 'front', 'spade', 13, 's13');
card_s14 = new Card(null, 'front', 'spade', 14, 's14');

selected_card = null;
selected_card_owner = null;

// classes /////////////////////////////////////////////////////////////////////
function Card(owner, face, type, number, id)
{
  this.owner = owner;
  this.face = face;
  this.type = type;
  this.number = number;
  this.id = id;

  this.nextCard = null;
  this.previousCard = null;

  var tag = document.getElementById(id);
  tag.src = front_image;
}

function CardmouseClickIE()
{
  with(this)
  {
    if(owner != null)
      owner.mouseClick(this);
  }
}
function CardmouseClickNS(evt)
{
  with(this)
  {
    if(owner != null)
      owner.mouseClick(this, evt);
  }
}
if(document.all)
	Card.prototype.mouseClick = CardmouseClickIE;
else
	Card.prototype.mouseClick = CardmouseClickNS;

function CardmouseMove()
{
  with(this)
  {
  }
}
Card.prototype.mouseMove = CardmouseMove;

function CardisSameColor(card)
{
  with(this)
  {
    if((card.type == 'heart' || card.type == 'diamond') && (type == 'heart' || type == 'diamond'))
    {
      return true;
    }

    if((card.type == 'spade' || card.type == 'club') && (type == 'spade' || type == 'club'))
    {
      return true;
    }

    return false;
  }
}
Card.prototype.isSameColor = CardisSameColor;

function CardisPointInside(x, y)
{
  with(this)
  {
    var tag = document.getElementById(id);

    if(x > parseInt(tag.style.left) && x < (parseInt(tag.style.left) + parseInt(tag.style.width)))
	{
      if(y > parseInt(tag.style.top) && y < (parseInt(tag.style.top) + parseInt(tag.style.height)))
	  {
	    return true;
	  }
	}

	return false;
  }
}
Card.prototype.isPointInside = CardisPointInside;

function CardgetCount()
{
  with(this)
  {
    count=0;
	c = nextCard;
	while(c != null)
	{
	  count++;
	  c = c.nextCard;
	}
	
	return count;
  }
}
Card.prototype.getCount = CardgetCount;

function CardisLastCard()
{
  with(this)
  {
    if(nextCard == null)
	  return true;
	else
	  return false;
  }
}
Card.prototype.isLastCard = CardisLastCard;

function CardgetLastCard()
{
  with(this)
  {
    if(nextCard == null)
	  return this;
	else
	{
	  c = nextCard;
	  while(c.nextCard != null)
	    c = c.nextCard;
		
	  return c;
	}
  }
}
Card.prototype.getLastCard = CardgetLastCard;

function Node(data, next)
{
  this.next = next;
  this.data = data;
}

function List()
{
  this.head = null;
  this.size = 0;
}

function Listadd(data)
{
  with(this)
  {
    head = new Node(data, head);
	size++;
  }
}
List.prototype.add = Listadd;

function Listremove(position)
{
  with(this)
  {
    i = 0;	  
	next = head;
	previous = null;
	
	for(;next != null; previous = next, next = next.next, i++)
	{
	  if(i == position)
	  {
	    if(previous == null)
		  head = next.next;
		else
		  previous.next = next.next;
	  
	    size--;
	    return next.data;
	  }
	}
	
	alert('hubba');
	return null;
  }
}
List.prototype.remove = Listremove;

function ListgetHead()
{
  with(this)
  {
    return head;
  }
}
List.prototype.getHead = ListgetHead;

function ListgetSize()
{
  with(this)
  {
    return size;
  }
}
List.prototype.getSize = ListgetSize;

function Stack()
{
  this.head = null;
  this.size = 0;
}

function Stackpush(data)
{
  with(this)
  {
    temp = head;
    head = new Node(data, temp);
	size++;
  }
}
Stack.prototype.push = Stackpush;

function Stackpop()
{
  with(this)
  {
    if(head == null)
    {
      return null;
    }
    else
    {
      temp = head;
      head = head.next;
	  size--;
      return temp.data;
    }
  }
}
Stack.prototype.pop = Stackpop;

function StackgetHead()
{
  with(this)
  {
    return head;
  }
}
Stack.prototype.getHead = StackgetHead;

function StackisEmpty()
{
  with(this)
  {
    if(head == null)
	  return true;
	else
	  return false;
  }
}
Stack.prototype.isEmpty = StackisEmpty;

function StackgetSize()
{
  with(this)
  {
    return size;
  }
}
Stack.prototype.getSize = StackgetSize;

function Deck(id)
{
  this.id = id;
  this.leftstack = null;
  this.rightstack = null;
}

function Deckreset()
{
	with(this)
	{
		leftstack = null;
		rightstack = null;
	}
}
Deck.prototype.reset = Deckreset;

function DeckaddCard(card)
{
  with(this)
  {
    var tag = null;

    card.owner = this;
  
    // check if card is front facing -> deck is being initialized
	// card is being added to the left stack
	if(card.face == 'front')
	{
	  if(leftstack == null)
	  {
	    leftstack = card;
		
		// making card selectable
        tag = document.getElementById(card.id);
		tag.style.cursor = 'hand';
	  }
	  else
	  {
	    lastcard = leftstack.getLastCard();
		lastcard.nextCard = card;
		card.previousCard = lastcard;

		// updating selectability
        tag = document.getElementById(card.id);		
	    tag.style.cursor = 'hand';
        tag = document.getElementById(lastcard.id);
		tag.style.cursor = 'default';
	  }
	  
	  return;
	}
  
    // adding card to the right stack
    if(rightstack == null)
	{
	  rightstack = card;
	}
	else
	{
	  lastcard = rightstack.getLastCard();
	  lastcard.nextCard = card;
	  card.previousCard = lastcard;
	  
	  // make previous card unselectable
      tag = document.getElementById(lastcard.id);
	  tag.style.cursor = 'default';
	}
  }
}
Deck.prototype.addCard = DeckaddCard;

function DeckremoveCard(card)
{
  with(this)
  {
    var tag = null;

    // check if card is last card
	if(card == rightstack)
	{
	  rightstack = null;
	}
	else
	{
      tag = document.getElementById(card.previousCard.id);
	  tag.style.cursor = 'hand';
	  card.previousCard.nextCard = null;
	  card.previousCard = null;
	}
	
    return card;
  }
}
Deck.prototype.removeCard = DeckremoveCard;

function DeckreturnCard(card)
{
  with(this)
  {
    var tag = null;

	card.owner = this;

    // returning card to the right stack
    if(rightstack == null)
	{
	  rightstack = card;
	}
	else
	{
	  lastcard = rightstack.getLastCard();
	  lastcard.nextCard = card;
	  card.previousCard = lastcard;
	  
	  // make previous card unselectable
      tag = document.getElementById(lastcard.id);
	  tag.style.cursor = 'default';
	}
  }
}
Deck.prototype.returnCard = DeckreturnCard;

function Deckupdate()
{
  with(this)
  {
    var ptag = document.getElementById(id);
    var tag = null;

    // updating left stack
		if(leftstack != null)
		{
      z = ptag.style.zIndex + 1;
	
      for(var card = leftstack, i = 0; card != null; card = card.nextCard, i++)
      {
        tag = document.getElementById(card.id);
        tag.style.top = parseInt(ptag.style.top) + (parseInt(ptag.style.height) - parseInt(tag.style.height))/2;
        tag.style.left = parseInt(ptag.style.left) + 20 + Math.floor(i/2);
        tag.style.zIndex = z + i;
      }
	  
      // make top card selectable
      tag = document.getElementById(leftstack.getLastCard().id);
      tag.style.cursor = 'hand';
    }
	
    // updating right stack
	  if(rightstack != null)
	  {
      z = ptag.style.zIndex + 1;

      for(var card = rightstack, i = 0; card != null; card = card.nextCard, i++)
	    {
        tag = document.getElementById(card.id);
	      tag.style.top = parseInt(ptag.style.top) + (parseInt(ptag.style.height) - parseInt(tag.style.height))/2;
	      tag.style.left = parseInt(ptag.style.left) + 120 + i*10;
	      tag.style.zIndex = z + i;
	    }
	  }
  }
}
Deck.prototype.update = Deckupdate;

function DeckevaluatePosition(x, y)
{
  with(this)
  {
  }
}
Deck.prototype.evaluatePosition = DeckevaluatePosition;

function DeckmouseClick(card)
{
  with(this)
  {
     var ptag = document.getElementById(id);
     var tag = null;

      // ensure that card is top card
	  if(card.nextCard != null)
      return;
  
      // check if card is from left or right stack
      if(card.face == 'front') // left stack
      {
	    // move open cards in right stack back to left stack
	    if(rightstack != null)
	    {
        c = rightstack;
        for(c = rightstack, nextcard = null; c != null; c = nextcard)
        {
          nextcard = c.nextCard;
          addToLeftStack(c);

          // make card face front
          tag = document.getElementById(c.id);
          tag.src = front_image;
          c.face = 'front';

          c = nextcard;
        }
        rightstack = null;
	    }
	
        // check if card if the last one
		ncards = 0;
	    if(card == leftstack)
	    {
	      leftstack = null;
		  ncards = 1;
        }
		else if(card.previousCard.previousCard == null)
		  ncards = 2;
		else
		  ncards = 3;
	
	    // Move cards in left stack to right stack
		for(i=0, c = card, previouscard = null; i<ncards; i++, c = previouscard)
		{
        previouscard = c.previousCard;
	      addToRightStack(c);
        }
	    update();
	  }
	  else // right stack
	  {
	    // check if card is valid
	    if(card.nextCard != null)
	      return;
	
	    selected_card = removeCard(card);
	    selected_card.owner = playarea;
	    selected_card_owner = this;
      tag = document.getElementById(selected_card.id);
	    tag.style.zIndex = ptag.style.zIndex + 250;
	  }
  }
}
Deck.prototype.mouseClick = DeckmouseClick;

function DeckmouseMove()
{
  with(this)
  {
  }
}
Deck.prototype.mouseMove = DeckmouseMove;

function DeckaddToRightStack(card)
{
  with(this)
  {
    tag = null;

    // remove old pointers
    if(card.previousCard != null)
	{
	  card.previousCard.nextCard = null;
	  card.previousCard = null;
	}

    // check if right stack is empty
    if(rightstack == null)  
	{
	  rightstack = card;
	}
	else
	{
	  lastcard = rightstack.getLastCard();
	  lastcard.nextCard = card;
	  card.previousCard = lastcard;
      tag = document.getElementById(lastcard.id);
	  tag.style.cursor = 'default';
	} 

	// make card visible and selectable
    tag = document.getElementById(card.id);
    card.face = 'back';
	tag.src = getCardImage(card);
	tag.style.cursor = 'hand';
  }
}
Deck.prototype.addToRightStack = DeckaddToRightStack;

function DeckaddToLeftStack(card)
{
  with(this)
  {
    var tag = document.getElementById(card.id);

    if(leftstack == null)
    {
      leftstack = card;
      card.nextCard = null;
      card.previousCard = null;

	  tag.style.cursor = 'hand';
    }
    else
    {
      card.previousCard = null;
      card.nextCard = leftstack;
      leftstack.previousCard = card;
      leftstack = card;
	  
	  tag.style.cursor = 'default';
    }
  }
}
Deck.prototype.addToLeftStack = DeckaddToLeftStack;

function CardStack(id)
{
  this.id = id;
  this.firstcard = null;
}

function CardStackreset()
{
	with(this)
	{
		firstcard = null;
	}
}
CardStack.prototype.reset = CardStackreset;

function CardStackaddCard(card)
{
  with(this)
  {
    var tag = null;

    if(firstcard == null)
	{
	  // add card
	  firstcard = card;
	  
	  // make first card unselectable (an ace)
      tag = document.getElementById(firstcard.id);
	  tag.style.cursor = 'default';
	}
	else
	{
	  // add card
	  lastcard = firstcard.getLastCard();
	  lastcard.nextCard = card;
	  card.previousCard = lastcard;
	  
	  // make previous card unselectable
      tag = document.getElementById(lastcard.id);
	  tag.style.cursor = 'default';
	}

	card.owner = this;
  }
}
CardStack.prototype.addCard = CardStackaddCard;

function CardStackremoveCard(card)
{
  with(this)
  {
    var tag = null;

    // make previous card selectable
	if(card.previousCard != firstcard)
    {
      tag = document.getElementById(card.previousCard.id);
	  tag.style.cursor = 'hand';
    }
  
    // remove pointers
	card.previousCard.nextCard = null;
	card.prevousCard = null;
  }
}
CardStack.prototype.removeCard = CardStackremoveCard;

function CardStackreturnCard(card)
{
  with(this)
  {
    var tag = null;

    // making previous card unselectable
	lastcard = firstcard.getLastCard();
    tag = document.getElementById(lastcard.id);
	tag.style.cursor = 'default';
	
	// updating pointers
	lastcard.nextCard = card;
	card.previousCard = lastcard;
	
	card.owner = this;
  }
}
CardStack.prototype.returnCard = CardStackreturnCard;

function CardStackupdate()
{
  with(this)
  {
    var ptag = document.getElementById(id);
    var tag = null;

	  if(firstcard != null)
		{
		  z = ptag.style.zIndex + 1;
		  // update all cards position
		  for(var i = 0, c = firstcard; c != null; i++, c = c.nextCard)
		  {
	      tag = document.getElementById(c.id);
		    tag.style.top = parseInt(ptag.style.top);
		    tag.style.left = parseInt(ptag.style.left);
				tag.style.zIndex = z + i;
		  }
		}
  }
}
CardStack.prototype.update = CardStackupdate;

function CardStackisNextCard(card)
{
  with(this)
  {
    // check that card has no subcards
	if(card.nextCard != null)
	  return false;
  
    // check if stack is empty
    if(firstcard == null)
	{
	  if(card.number == 14)
	    return true;
	  else
	    return false;
	}

    // check color	
	lastcard = firstcard.getLastCard();
	if(lastcard.type == card.type)
	{
	  // find next number
	  next_number = 0;
	  if(lastcard.number == 14)
	    next_number = 2;
	  else
	    next_number = lastcard.number+1;
		
	  // check number
	  if(card.number == next_number)
	    return true;
    }
	
	return false;
  }
}
CardStack.prototype.isNextCard = CardStackisNextCard;

function CardStackmouseClick(card)
{
  with(this)
  {
    var ptag = document.getElementById(id);
    var tag = null;

    // check if card is top card (ace = not selectable)
    if(card == firstcard)
	  return;
	  
		// check that card is last card
		lastcard = firstcard.getLastCard();
		if(card != lastcard)
		  return;
	  
		// removing card from stack
		removeCard(card);
		  
		// hand over card to playarea
		selected_card = card;
		selected_card_owner = this;
		selected_card.owner = playarea;
	  tag = document.getElementById(selected_card.id);
		tag.style.zIndex = ptag.style.zIndex + 250;
  }
}
CardStack.prototype.mouseClick = CardStackmouseClick;

function CardStackevaluatePosition(x, y)
{
  with(this)
  {
    var tag = document.getElementById(id);

    if(x > parseInt(tag.style.left) && x < (parseInt(tag.style.left) + parseInt(tag.style.width)))
	{
	  if(y > parseInt(tag.style.top) && y < (parseInt(tag.style.top) + parseInt(tag.style.height)))
	  {
	    return this;
	  }
	}

	return null;
  }
}
CardStack.prototype.evaluatePosition = CardStackevaluatePosition;

function Row(id)
{
  this.id = id;
  this.firstcard =  null;
}

function Rowreset()
{
	with(this)
	{
		firstcard = null;
	}
}
Row.prototype.reset = Rowreset;

function RowaddCard(card)
{
  with(this)
  {
	var tag = null;

    if(firstcard == null)
    {
      // first card in row
      firstcard = card;
	  firstcard.previousCard = null;
    }
    else
    {
	  // add card to last card
	  lastcard = firstcard.getLastCard(); 
	  lastcard.nextCard = card;
	  card.previousCard = lastcard;
	  
	  // check if card was returned -> remove hand cursor on front faceing card
	  if(lastcard.face == 'front')
	  {
        tag = document.getElementById(lastcard.id);
	    tag.style.cursor = 'default';
	  }
    }
	
	// Update all subcards - owner property
	for(c = card; c != null; c = c.nextCard)
	{
	  c.owner = this;
	}
  }
}
Row.prototype.addCard = RowaddCard;

function RowremoveCard(card)
{
  with(this)
  {
	var tag = null;

    // check if card is firstcard
	if(card == firstcard)
	{
	  firstcard = null;
	  return card;
	}
  
    // check if card face is front
	if(card.previousCard.face == 'front')
	{
	  tag = document.getElementById(card.previousCard.id)
	  tag.style.cursor = 'hand';
	}
	
	card.previousCard.nextCard = null;
	card.previousCard = null;

	return card;
  }
}
Row.prototype.removeCard = RowremoveCard;

function RowreturnCard(card)
{
  with(this)
  {
    if(firstcard == null)
    {
      // first card in row
      firstcard = card;
	  firstcard.previousCard = null;
    }
    else
    {
	  // add card to last card
	  lastcard = firstcard.getLastCard(); 
	  lastcard.nextCard = card;
	  card.previousCard = lastcard;
	  
	  // remove hand cursor on previous front faceing card
	  if(lastcard.face == 'front')
	  {
        var tag = document.getElementById(lastcard.id);
	    tag.style.cursor = 'default';
	  }
    }

	// Update all subcards - owner property
	for(c = card; c != null; c = c.nextCard)
	{
	  c.owner = this;
	}
  }
}
Row.prototype.returnCard = RowreturnCard;

function Rowupdate()
{
  with(this)
  {
		var tag = null;
		var ptag = document.getElementById(id);

    if(firstcard == null)
      return;

    // Update all cards in row
    offset = 0;
    z = ptag.style.zIndex + 1;
	
    for(var card = firstcard, i = 0; card != null; card = card.nextCard, i++)
    {
      if(card == firstcard)
        offset = 0;
      else if(card.face == 'front')
        offset += 7;
      else if(card.previousCard.face == 'front')
        offset += 7;
      else
        offset += 14;

      tag = document.getElementById(card.id);
      tag.style.top = parseInt(ptag.style.top) + offset;
      tag.style.left = parseInt(ptag.style.left) + (parseInt(ptag.style.width)-parseInt(tag.style.width))/2;
      tag.style.zIndex = z + i;
    }
  }
}
Row.prototype.update = Rowupdate;

function Rowinitialize()
{
  with(this)
  {
	var ptag = document.getElementById(id);
	var tag = null;

    if(firstcard == null)
	  return;

	// Update all cards in row
    z = ptag.style.zIndex + 1;
    offset = 0;

    for(card = firstcard, i=0; card != null; i++, card = card.nextCard)
    {
      if(card == firstcard)
        offset = 0;
      else if(card.face == 'front')
        offset += 7;
      else if(card.previousCard.face == 'front')
        offset += 7;
      else
        offset += 14;

	  tag = document.getElementById(card.id);
      tag.style.top = parseInt(ptag.style.top) + offset;
      tag.style.left = parseInt(ptag.style.left) + (parseInt(ptag.style.width)-parseInt(tag.style.width))/2;
      tag.style.zIndex = z + i;
      tag.style.cursor = 'default';
   }

    // Make last card visible
    card = firstcard.getLastCard();
    tag = document.getElementById(card.id);
    card.face = 'back';
    tag.src = getCardImage(card);
    tag.style.cursor = 'hand';
  }
}
Row.prototype.initialize = Rowinitialize;

function RowmouseClick(card)
{
  with(this)
  {
		var ptag = document.getElementById(id);
		var ctag = document.getElementById(card.id);
		var tag = null;
	
	  // check if card is valid
	  if(card.face == 'front')
		{
		  if(card.isLastCard())
		  {
				card.face = 'back';
				ctag.src = getCardImage(card);
				ctag.style.cursor = 'hand';
		  }
	
	    return;
		}
		
		// remove card from row stack
		removeCard(card);
	
		// remove card from row and update z-index of card + subcards
	  selected_card = card;
		selected_card_owner = this;
		selected_card.owner = playarea;
	
		ctag.style.zIndex = ptag.style.zIndex + 250;
		for(var c = card.nextCard, i=1; c != null; c = c.nextCard, i++)
		{
	    tag = document.getElementById(c.id);
		  tag.style.zIndex = ctag.style.zIndex + i;
		  c.owner = playarea;
		}
  }
}
Row.prototype.mouseClick = RowmouseClick;

function RowmouseMove()
{
  with(this)
  {
  }
}
Row.prototype.mouseMove = RowmouseMove;

function RowevaluatePosition(x, y)
{
  with(this)
  {
    var tag = document.getElementById(id);

    if(firstcard != null)
	{
	  lastcard = firstcard.getLastCard();
	  if(lastcard.isPointInside(x, y))
	    return this;
	}
	else
	{
      if(x > parseInt(tag.style.left) && x < (parseInt(tag.style.left) + parseInt(tag.style.width)))
	    if(y > parseInt(tag.style.top) && y < (parseInt(tag.style.top) + parseInt(tag.style.height)))
	      return this;
	}

	return null;
  }
}
Row.prototype.evaluatePosition = RowevaluatePosition; 

function RowisNextCard(card)
{
  with(this)
  {
    // if row is empty -> check that card is a king
    if(firstcard == null)
	{
	  if(card.number == 13)
	    return true;
	  else 
	    return false;
	}
	
    lastcard = firstcard.getLastCard();
	
	// Check color and number of card
	if(!card.isSameColor(lastcard))
	{
	  if(card.number == (lastcard.number-1))
	    return true;
	}
	
	return false;
  }
}
Row.prototype.isNextCard = RowisNextCard;

function PlayArea(id)
{
  this.id = id;
}

function PlayAreamouseClickIE(card)
{
  with(this)
  {
	var tag = document.getElementById(id);

 	object = evaluatePosition(window.event.x - parseInt(tag.style.left), window.event.y - parseInt(tag.style.top));

	if(object != null)
	{
	  if(object.isNextCard(selected_card))
	  {
        object.addCard(selected_card);
        object.update();
        selected_card_owner.update();
        selected_card = null;
        selected_card_owner = null;
		return;
      }
	}

	// return card to original owner
    selected_card_owner.returnCard(selected_card);
    selected_card_owner.update();
    selected_card = null;
    selected_card_owner = null;
  }
}
function PlayAreamouseClickNS(card, evt)
{
  with(this)
  {
	var tag = document.getElementById(id);

	var x = evt.pageX - parseInt(tag.style.left);
	var y = evt.pageY - parseInt(tag.style.top);

 	object = evaluatePosition(x, y);

	if(object != null)
	{
	  if(object.isNextCard(selected_card))
	  {
        object.addCard(selected_card);
        object.update();
        selected_card_owner.update();
        selected_card = null;
        selected_card_owner = null;
		return;
      }
	}

	// return card to original owner
    selected_card_owner.returnCard(selected_card);
    selected_card_owner.update();
    selected_card = null;
    selected_card_owner = null;
  }
}
if(document.all)
{
	PlayArea.prototype.mouseClick = PlayAreamouseClickIE;
}
else
{
	PlayArea.prototype.mouseClick = PlayAreamouseClickNS;
}

function PlayAreamouseMoveIE()
{
  with(this)
  {
	var ptag = document.getElementById(id);
	var stag = null;
    var tag = null;

    if(selected_card != null)
    {
      stag = document.getElementById(selected_card.id);
      // moving first card
      stag.style.left = parseInt(window.event.x) - parseInt(ptag.style.left) - 10;
      stag.style.top = parseInt(window.event.y) - parseInt(ptag.style.top) - 10;
	
	  // moving subcards
	  for(card = selected_card.nextCard, i=1; card != null; card = card.nextCard, i++)
	  {
        tag = document.getElementById(card.id);
	    tag.style.left = parseInt(stag.style.left);
	    tag.style.top = parseInt(stag.style.top) + i*14;
	  }
    }
  }
}
function PlayAreamouseMoveNS(evt)
{
  with(this)
  {
	var ptag = document.getElementById(id);
	var stag = null;
    var tag = null;

    if(selected_card != null)
    {
      stag = document.getElementById(selected_card.id);
      // moving first card
      stag.style.left = parseInt(evt.pageX) - parseInt(ptag.style.left) - 10;
      stag.style.top = parseInt(evt.pageY) - parseInt(ptag.style.top) - 10;
	
	  // moving subcards
	  for(card = selected_card.nextCard, i=1; card != null; card = card.nextCard, i++)
	  {
        tag = document.getElementById(card.id);
	    tag.style.left = parseInt(stag.style.left);
	    tag.style.top = parseInt(stag.style.top) + i*14;
	  }
    }
  }
}
if(document.all)
{
	PlayArea.prototype.mouseMove = PlayAreamouseMoveIE;
}
else
{
	PlayArea.prototype.mouseMove = PlayAreamouseMoveNS;
}

function PlayAreaevaluatePosition(x, y)
{
  with(this)
  {
    object = null;

	// Finner hvor kortet skal
	if((object = row1.evaluatePosition(x, y)) != null)
      return object;
	else if((object = row2.evaluatePosition(x, y)) != null)
      return object;
	else if((object = row3.evaluatePosition(x, y)) != null)
      return object;
	else if((object = row4.evaluatePosition(x, y)) != null)
      return object;
	else if((object = row5.evaluatePosition(x, y)) != null)
      return object;
	else if((object = row6.evaluatePosition(x, y)) != null)
      return object;
	else if((object = row7.evaluatePosition(x, y)) != null)
      return object;
	else if((object = cardstack1.evaluatePosition(x, y)) != null)
      return object;
	else if((object = cardstack2.evaluatePosition(x, y)) != null)
      return object;
	else if((object = cardstack3.evaluatePosition(x, y)) != null)
      return object;
	else if((object = cardstack4.evaluatePosition(x, y)) != null)
      return object;

	return null;
  }
}
PlayArea.prototype.evaluatePosition = PlayAreaevaluatePosition;

function CardRandomizer()
{
  this.cards = new List();
}

function CardRandomizerinitialize()
{
  with(this)
  {
    var tag = null;

    cards.add(card_h2);
    cards.add(card_h3);
    cards.add(card_h4);
    cards.add(card_h5);
    cards.add(card_h6);
    cards.add(card_h7);
    cards.add(card_h8);
    cards.add(card_h9);
    cards.add(card_h10);
    cards.add(card_h11);
    cards.add(card_h12);
    cards.add(card_h13);
    cards.add(card_h14);

    cards.add(card_d2);
    cards.add(card_d3);
    cards.add(card_d4);
    cards.add(card_d5);
    cards.add(card_d6);
    cards.add(card_d7);
    cards.add(card_d8);
    cards.add(card_d9);
    cards.add(card_d10);
    cards.add(card_d11);
    cards.add(card_d12);
    cards.add(card_d13);
    cards.add(card_d14);
	
    cards.add(card_c2);
    cards.add(card_c3);
    cards.add(card_c4);
    cards.add(card_c5);
    cards.add(card_c6);
    cards.add(card_c7);
    cards.add(card_c8);
    cards.add(card_c9);
    cards.add(card_c10);
    cards.add(card_c11);
    cards.add(card_c12);
    cards.add(card_c13);
    cards.add(card_c14);
	
    cards.add(card_s2);
    cards.add(card_s3);
    cards.add(card_s4);
    cards.add(card_s5);
    cards.add(card_s6);
    cards.add(card_s7);
    cards.add(card_s8);
    cards.add(card_s9);
    cards.add(card_s10);
    cards.add(card_s11);
    cards.add(card_s12);
    cards.add(card_s13);
    cards.add(card_s14);

    // resetting cards
    var node = cards.getHead(), card = null;
    while(node != null)
    {
      card = node.data;
      card.owner = null;
      card.nextCard = null;
      card.previousCard = null;
      card.face = 'front';
 
	  tag = document.getElementById(card.id);
      tag.src = front_image;
	  tag.style.cursor = 'default';

      node = node.next;
    }
  }
}
CardRandomizer.prototype.initialize = CardRandomizerinitialize;

function CardRandomizerremoveCard()
{
  with(this)
  {
    pos = Math.floor(Math.random() * cards.getSize());
	return cards.remove(pos);
  }
}
CardRandomizer.prototype.removeCard = CardRandomizerremoveCard;

function CardRandomizerisEmpty()
{
  with(this)
  {
    if(cards.getSize() == 0)
	  return true
	else
	  return false;
  }
}
CardRandomizer.prototype.isEmpty = CardRandomizerisEmpty;

// functions ///////////////////////////////////////////////////////////////////
function initialize()
{
  newgame();
}

function newgame()
{
  selected_card = null;
  selected_card_owner = null;

  // reseting
  row1.reset();
  row2.reset();
  row3.reset();
  row4.reset();
  row5.reset();
  row6.reset();
  row7.reset();
  cardstack1.reset();
  cardstack2.reset();
  cardstack3.reset();
  cardstack4.reset();
  deck.reset();

  deal();
}

function deal()
{
  var dealer = new CardRandomizer();
  dealer.initialize();
  
  row1.addCard(dealer.removeCard());

  row2.addCard(dealer.removeCard());
  row2.addCard(dealer.removeCard());

  row3.addCard(dealer.removeCard());
  row3.addCard(dealer.removeCard());
  row3.addCard(dealer.removeCard());

  row4.addCard(dealer.removeCard());
  row4.addCard(dealer.removeCard());
  row4.addCard(dealer.removeCard());
  row4.addCard(dealer.removeCard());

  row5.addCard(dealer.removeCard());
  row5.addCard(dealer.removeCard());
  row5.addCard(dealer.removeCard());
  row5.addCard(dealer.removeCard());
  row5.addCard(dealer.removeCard());

  row6.addCard(dealer.removeCard());
  row6.addCard(dealer.removeCard());
  row6.addCard(dealer.removeCard());
  row6.addCard(dealer.removeCard());
  row6.addCard(dealer.removeCard());
  row6.addCard(dealer.removeCard());

  row7.addCard(dealer.removeCard());
  row7.addCard(dealer.removeCard());
  row7.addCard(dealer.removeCard());
  row7.addCard(dealer.removeCard());
  row7.addCard(dealer.removeCard());
  row7.addCard(dealer.removeCard());
  row7.addCard(dealer.removeCard());

  while(!dealer.isEmpty())
  {
    deck.addCard(dealer.removeCard());
  }

  deck.update();
  row1.initialize();
  row2.initialize();
  row3.initialize();
  row4.initialize();
  row5.initialize();
  row6.initialize();
  row7.initialize();
}

function getCardImage(card)
{
  return 'images/' + card.id + '.gif';
}

function selectcard(card)
{
  if(selected_card == null)
  {
    selected_card = card;
	selected_card.style.z = 200;
  }
  else
  {
    selected_card = null;
  }
}

// initializing game
initialize();

