1 function Board(options) { 2 3 //PRIVATE INSTANCE VARIABLES 4 options = options || {}; 5 var __MY_ROOT = options.rootId || "BoardRoot"; 6 var __HAND_HOLDER = options.handId || "HandRoot"; 7 var __DECK_OPACITY = options.cardOpacity || .9; 8 var __EXTENSION_TYPE = options.extensionType || "gif"; 9 var __IMAGES_DIRECTORY = options.imagesDirectory || "images/"; 10 var __CARD_WIDTH = options.cardWidth || 73; 11 var __CARD_HEIGHT = options.cardHeight || 102; 12 var __DECK_HEIGHT = options.deckHeight || 204; 13 var __MAGICAL_UNIT_X = options.magicalX || 150; 14 var __MAGICAL_UNIT_Y = options.magicalY || 220; 15 var __HAND_WIDTH = options.handWidth || 500; 16 var __MULTI_DRAG = (options.multiDrag===false) ? false : true; 17 var handHolder=$("#"+__HAND_HOLDER); 18 handHolder.addClass("board"); 19 var root=$("#"+__MY_ROOT); 20 root.addClass("board"); 21 var decks = new Array(); 22 var appendString = "cardHolder"; 23 var counter = 0; 24 var cardHash = {}; 25 var maxX = 0; 26 var maxY = 0; 27 28 //PUBLIC TYPE PROPERTIES 29 30 this.defaultType = function(deck) { 31 var isHand = isNaN(deck.getX()); 32 //the offset for hands is proportional to the size of the hand 33 var minOverlapX = __CARD_WIDTH / 2; 34 var maxOverlapX = ((__HAND_WIDTH - __CARD_WIDTH) / deck.getSize()); 35 var overlapX = (minOverlapX < maxOverlapX) ? minOverlapX : maxOverlapX; 36 var offsetX = isHand ? overlapX : 0; 37 //the offset for decks is proportional to the size of the deck 38 var minOverlap = __CARD_HEIGHT / 5; 39 var maxOverlap = ((__DECK_HEIGHT - __CARD_HEIGHT) / deck.getSize()); 40 var overlap = (minOverlap < maxOverlap) ? minOverlap : maxOverlap; 41 var offsetY = isHand ? 0 : overlap; 42 return [offsetX, offsetY]; 43 }; 44 this.collapsedType = function(deck) { 45 return [0,0]; 46 }; 47 this.horizontalType = function(deck) { 48 //the offset for hands is proportional to the size of the hand 49 var minOverlapX = __CARD_WIDTH / 2; 50 var maxOverlapX = ((__HAND_WIDTH - __CARD_WIDTH) / deck.getSize()); 51 var overlapX = (minOverlapX < maxOverlapX) ? minOverlapX : maxOverlapX; 52 var offsetX = overlapX; 53 var offsetY = 0; 54 return [offsetX, offsetY]; 55 }; 56 57 //PRIVATE FUNCTIONS 58 59 function createDeck(deck) { 60 //observe events 61 deck.observe(function() { 62 for(var i = 0; i < decks.length; i++) { 63 if(deck == decks[i][0]) { 64 return reDrawDeck(decks[i]); 65 } 66 } 67 return null; 68 }); 69 var isHand = isNaN(deck.getX()); 70 //add ui 71 var div = $("<div>"); 72 div.droppable({ 73 accept : function(el) { 74 var cards=getCards(el[0]); 75 return deck.getFilter()(cards[cards.length-1],getDeck(el[0]),cards.length); 76 }, 77 drop : function(event, ui) { 78 var srcDeck=event.srcElement.parentElement; 79 var cards=getCards(srcDeck); 80 for(var i=cards.length-1;i>=0;i--) { 81 try { 82 console.log(cards[i]); 83 getDeck(srcDeck).remove(cards[i]); 84 deck.addTop(cards[i]); 85 } catch(e) { 86 continue; 87 } 88 } 89 reDrawDeck([getDeck(srcDeck), div]); 90 reDrawDeck([deck, $(event.target)]); 91 } 92 }); 93 div.addClass(isHand ? "hand" : "deck"); 94 if(isHand&&deck.isActive()) { 95 handHolder.append(div); 96 } else if(!isHand) { 97 root.append(div); 98 } 99 return reDrawDeck([deck, div]); 100 } 101 102 function getSuitName(card) { 103 var suit=card.getSuit().toUpperCase(); 104 switch(suit) { 105 case "H": 106 suit="of hearts"; 107 break; 108 case "D": 109 suit="of diamonds"; 110 break; 111 case "C": 112 suit="of clubs"; 113 break; 114 case "S": 115 suit="of spades"; 116 break; 117 } 118 return suit; 119 } 120 121 function getOffsetByType(deck) { 122 return deck.getType()(deck); 123 } 124 125 function getCard(element) { 126 return cardHash[element.id][1]; 127 } 128 129 function getCards(element) { 130 var cards=[]; 131 if(__MULTI_DRAG) { 132 var children=$(element).children(".card"); 133 if(children) { 134 for(var i = 0; i < children.length; i++) { 135 cards.push(getCard(children[i])); 136 } 137 } 138 } 139 cards.push(getCard(element)); 140 return cards; 141 } 142 143 function getDeck(element) { 144 return cardHash[element.id][0]; 145 } 146 147 function reDrawDeck(deckArr) { 148 var deck = deckArr[0]; 149 var div = deckArr[1]; 150 div[0].onclick=deck.getAction(); 151 maxX = deck.getX() > maxX ? deck.getX() : maxX; 152 maxY = deck.getY() > maxY ? deck.getY() : maxY; 153 root.css("width",((maxX+1)*__MAGICAL_UNIT_X)+"px"); 154 root.css("height",((maxY+1)*__MAGICAL_UNIT_Y)+"px"); 155 div.empty(); 156 var isHand = isNaN(deck.getX()); 157 if(!isHand) { 158 div.css("left", deck.getX()*__MAGICAL_UNIT_X); 159 div.css("top", deck.getY()*__MAGICAL_UNIT_Y); 160 } 161 var offsets=getOffsetByType(deck); 162 var offsetX=offsets[0]; 163 var offsetY=offsets[1]; 164 var cards = deck.getCards(); 165 var soFar=new Array(); 166 for(var i = cards.length - 1; i >= 0; i--) { 167 var newDiv=(function (stack,i) { 168 var card = cards[i]; 169 var holder = $("<div>"); 170 cardHash[appendString+counter]=[deck,card]; 171 holder.attr("id", appendString+(counter++)); 172 holder.css("z-index",i+deck.getzOffset()); 173 if(card.isFaceUp()&&deck.isDraggable()) { 174 holder.draggable({ 175 revert : "invalid", 176 start : function(event, ui) { 177 holder.css("z-index",99+deck.getzOffset()); 178 if(__MULTI_DRAG) { 179 for(var j = 0; j < stack.length; j++) { 180 stack[j][1].detach(); 181 holder.append(stack[j][1]); 182 } 183 } 184 }, 185 stop : function(event, ui) { 186 var srcDeck=event.srcElement.parentElement; 187 holder.css("z-index",i+deck.getzOffset()); 188 reDrawDeck([getDeck(srcDeck),div]); 189 } 190 }); 191 } 192 holder.addClass("card"); 193 holder.css("left", (offsetX * i)+"px"); 194 holder.css("top", (offsetY * i)+"px"); 195 holder.css("position", "absolute"); 196 var img = $("<img>"); 197 if(card.isFaceUp()) { 198 img.attr("alt", card.getRankAsString()+" "+getSuitName(card)); 199 img.attr("title", card.getRankAsString()+" "+getSuitName(card)); 200 } 201 img.attr("src", card.isFaceUp() ? (__IMAGES_DIRECTORY+card.getRank()+card.getSuit()+"."+__EXTENSION_TYPE) : (__IMAGES_DIRECTORY+"back."+__EXTENSION_TYPE)); 202 img.css("opacity", __DECK_OPACITY); 203 holder.append(img); 204 div.append(holder); 205 return holder; 206 })(soFar.concat(),i); 207 soFar.push([cards[i],newDiv]); 208 } 209 div.css("width",((cards.length)*offsetX)+__CARD_WIDTH); 210 div.css("height",((cards.length)*offsetY)+__CARD_HEIGHT); 211 return div; 212 } 213 214 //PUBLIC FUNCTIONS 215 216 this.addDeck = function (deck) { 217 return decks.push([deck, createDeck(deck)]); 218 }; 219 220 this.getDecks = function() { 221 return decks; 222 }; 223 }