diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/css/gemp-001/deckBuild2.css b/gemp-lotr/gemp-lotr-async/src/main/web/css/gemp-001/deckBuild2.css new file mode 100644 index 000000000..896de74d5 --- /dev/null +++ b/gemp-lotr/gemp-lotr-async/src/main/web/css/gemp-001/deckBuild2.css @@ -0,0 +1,248 @@ +body { + font-size: 12px; + width: 100%; + height: 100%; + margin: 1px; +} + +.borderOverlay { + border: 0px solid #000000; +} + +.foilOverlay { + opacity: 0.2; +} + +.selectableCard > .borderOverlay { + border: 2px solid #00ff00; + cursor: pointer; +} + +.selectedCard > .borderOverlay { + border: 2px solid #00cccc; +} + +.cardCount { + width: 20px; + height: 18px; + background-color: #000000; + color: #ffffff; + font-size: 120%; + font-weight: bolder; + display: table-cell; + text-align: center; + vertical-align: middle; + opacity: 0.7; +} + +.ui-layout-east { + width: 350px; +} + + + +#editingDeck { + vertical-align: top; + padding-left: 3px; +} + +#deckStats { + color: #ffffff; +} + +.ui-button-text-only .ui-button-text { + font-size: 70%; +} + +button.navigation-butt { + padding: 0.5em; +} + +.navigation-butt.ui-button-icon-only > .ui-button-text{ + padding: 0; +} + +.navigation-butt.ui-button-icon-only { + width: 25px; +} + +.ui-button-icon-only .ui-button-icon-primary.ui-icon { + margin: auto auto auto -4px; +} + +#set { + width: 120px; +} + +#cardType { + width: 100px; +} + +#fullFiltering select { + font-size: 80%; +} + +#fullFiltering input { + font-size: 80%; +} + +#filtering select { + font-size: 80%; +} + +#messageDiv { + text-align: center; + color: #ffffff; + font-size: 180%; +} + +.menu-button.ui-button { + padding: 0; +} + +.menu-button > .ui-button-text { + padding: 0; +} + +button.navigation-butt { + padding: 0.5em; +} + +.navigation-butt.ui-button-icon-only > .ui-button-text{ + padding: 0; +} + +.navigation-butt.ui-button-icon-only { + width: 25px; +} + +.ui-button-icon-only .ui-button-icon-primary.ui-icon { + margin: auto auto auto -4px; +} + +#culture-buttons .ui-button { + padding: 0; +} + +#collectionSelect { + order: 100; +} + +#editingDeck { + flex-grow: 1; +} + +.notesText { + flex-grow: 1; + margin: 5px; +} + +.notesDialog { + display: flex; +} + +.flex-horiz { + display: flex; + flex-direction: row; + gap: 2px; +} + +.flex-vert { + display: flex; + flex-direction: column; + gap: 2px; +} + +.card-group { + border-radius: 7px; + width: 100%; + height: 100%; + margin: 5px; +} + + +#top-level { + width: 100%; + height: 100%; + position: absolute; + display: flex; + margin: 0px; +} + +#deckDiv { + flex-grow: 1; + flex-shrink: 1; + padding: 2px !important; +} + +#manage-deck-menu { + color: #ffffff; + font-size: 180%; + display: flex; + flex-grow: 0; + height: 23px; +} + +#formatSelect { + float: right; + width: 100px; +} + +#deck-overview { + height: 100%; + overflow: hidden; +} + +#deck-view { + flex-grow: 1; +} + +#left-deck-parts { + height: 100%; + flex-grow: 0; + width: 30vh; +} + + +#rb-sites-column { + display: flex; + flex-direction: column; +} + +#ring-pair { + flex-grow: 0; + flex-wrap: wrap; + justify-content: space-between; +} + +#ringBearerDiv, #ringDiv, #map-div { + flex-grow: 0; + flex-shrink: 0; + min-width: max(13vw,49%); + min-height: 14vh; +} + +#sitesDiv { + flex-grow: 5; + + padding: 0 10px 30px 0; +} + +#sites-content { + +} + +#decksRegion { + height: 100%; + flex-grow: 1; +} + +#fp-cards, #sh-cards { + flex-grow: 1; +} + +#statsDiv { + flex-grow: 0; + height: 70px; + overflow: auto; +} diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/deckBuild2.html b/gemp-lotr/gemp-lotr-async/src/main/web/deckBuild2.html new file mode 100644 index 000000000..dbff77def --- /dev/null +++ b/gemp-lotr/gemp-lotr-async/src/main/web/deckBuild2.html @@ -0,0 +1,168 @@ + + + + + GEMP: LotR-TCG - Deckbuilder + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + New deck + + +
+ +
+
+
+
+ Ring Bearer +
+
+
+ Ring +
+
+
+ Map +
+
+
+ +
+ Sites +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+ + + + + + \ No newline at end of file diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/deckBuildingUi2.js b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/deckBuildingUi2.js index 1b7c13d89..5fb75084f 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/deckBuildingUi2.js +++ b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/deckBuildingUi2.js @@ -1,72 +1,66 @@ -var GempLotrDeckBuildingUI2 = Class.extend({ +var GempLotrDeckBuildingUI = Class.extend({ comm:null, - collectionType:null, - collectionContentsDiv:null, - collectionContainer:null, - collectionGroup:null, + deckDiv:null, - collectionSelect: null, + ringBearerDiv:null, + ringBearerGroup:null, - deckDiv: null, + ringDiv:null, + ringGroup:null, + + siteDiv:null, + siteGroup:null, + + collectionDiv:null, + formatSelect:null, + currentFormat:null, + notes:null, + + normalCollectionDiv:null, + normalCollectionGroup:null, + + selectionFunc:null, + drawDeckDiv:null, + + fpDeckGroup:null, + shadowDeckGroup:null, + + start:0, + count:18, + filter:null, + + deckName:null, + + filterDirty:false, + deckValidationDirty:true, + deckContentsDirty:true, + + checkDirtyInterval:500, + + deckListDialog:null, + selectionDialog:null, + selectionGroup:null, + packSelectionId:null, + deckImportDialog:null, + notesDialog:null, cardFilter:null, - deckPanel:null, - padding: 3, - cardInCollectionId:0, - cardInDeckId:0, + collectionType:null, - cardInformationDialog: null, - - // Card properties: - // type: pack, card - // blueprintId: id of the blueprint as in server - // count: number of cards of that type - // contents: contents of selection pack - // hor: if card is horizontal - // group: ring, ringBearer, site, fp, shadow - // image: image url - - init:function (filterDiv, pageDiv, collectionContentsDiv, deckDiv) { - this.collectionContentsDiv = collectionContentsDiv; - this.deckDiv = deckDiv; + specialSelection:false, + init:function () { var that = this; - this.collectionContainer = new CardContainer(collectionContentsDiv, this.layoutCollectionContainer, this.layoutCardInCollection, this.widthToHeightScaleInCollection); - this.collectionGroup = new RowCardLayoutCardGroup(collectionContentsDiv, - function() { - return true; - }); - this.collectionGroup.setZIndexBase(10); - this.collectionContainer.addCardGroup("main", this.collectionGroup); - this.comm = new GempLotrCommunication("/gemp-lotr-server", that.processError); - var collectionTypeDiv = $("
"); - var filterDivInternal = $("
"); - - collectionTypeDiv.append("Collection: "); - - this.collectionSelect = $(""); - this.collectionSelect.css({"float":"right", "width":"180px", "font-size": "75%"}); - this.collectionSelect.append(""); - this.collectionSelect.append(""); - - collectionTypeDiv.append(this.collectionSelect); - - this.collectionSelect.change( - function () { - that.collectionType = $("option:selected", this.collectionSelect).prop("value"); - that.cardFilter.getCollection(); - }); - - filterDiv.append(collectionTypeDiv); - filterDiv.append(filterDivInternal); - - this.cardFilter = new CardFilter(filterDivInternal, pageDiv, + this.cardFilter = new CardFilter($("#collectionDiv"), function (filter, start, count, callback) { + if (!that.specialSelection) { + filter = filter + " cardType:-THE_ONE_RING"; + } that.comm.getCollection(that.collectionType, filter, start, count, function (xml) { callback(xml); }, { @@ -79,23 +73,169 @@ var GempLotrDeckBuildingUI2 = Class.extend({ that.clearCollection(); }, function (elem, type, blueprintId, count) { - that.addCardToCollection(type, blueprintId, count, elem.getAttribute("group"), elem.getAttribute("contents")); + that.addCardToCollection(type, blueprintId, count, elem.getAttribute("side"), elem.getAttribute("contents")); }, function () { that.finishCollection(); }); - - this.deckPanel = new DeckPanel(deckDiv, this.layoutCardInDeck, this.widthToHeightScaleInCollection); - this.collectionType = "default"; - this.cardFilter.getCollection(); - this.cardInformationDialog = new CardInformationDialog(); + this.deckDiv = $("#deckDiv"); + + this.formatSelect = $("#formatSelect"); + $("#formatSelect").change( + function () { + that.deckModified(true); + }); + + var collectionSelect = $("#collectionSelect"); + + var newDeckBut = $("#newDeckBut").button(); + + var saveDeckBut = $("#saveDeckBut").button(); + + var renameDeckBut = $("#renameDeckBut").button(); + + var copyDeckBut = $("#copyDeckBut").button(); + + var importDeckBut = $("#importDeckBut").button(); + + var libraryListBut = $("#libraryListBut").button(); + + var deckListBut = $("#deckListBut").button(); + + var notesBut = $("#notesBut").button(); + + this.deckNameSpan = ("#editingDeck"); + + newDeckBut.click( + function () { + that.deckName = null; + $("#editingDeck").text("New deck"); + that.clearDeck(); + }); + + saveDeckBut.click( + function () { + if (that.deckName == null) { + var newDeckName = prompt("Enter the name of the deck", ""); + if (newDeckName == null) + return; + if (newDeckName.length < 3 || newDeckName.length > 100) + alert("Deck name has to have at least 3 characters and at most 100 characters."); + else { + that.deckName = newDeckName; + $("#editingDeck").text(newDeckName); + that.saveDeck(true); + } + } else { + that.saveDeck(false); + } + }); + + renameDeckBut.click( + function () { + if (that.deckName == null) { + alert("You can't rename this deck, since it's not named (saved) yet."); + return; + } + that.renameCurrentDeck(); + }); + + copyDeckBut.click( + function () { + that.deckName = null; + $("#editingDeck").text("New deck"); + }); + + deckListBut.click( + function () { + that.loadDeckList(); + }); + + libraryListBut.click( + function () { + that.loadLibraryList(); + }); + + importDeckBut.click( + function () { + that.deckName = null; + that.importDecklist(); + }); + + notesBut.click( + function () { + that.editNotes(); + }); + + this.collectionDiv = $("#collectionDiv"); + + $("#collectionSelect").change( + function () { + that.collectionType = that.getCollectionType(); + that.cardFilter.getCollection(); + }); + + this.normalCollectionDiv = $("#collection-display"); + this.normalCollectionGroup = new NormalCardGroup(this.normalCollectionDiv, function (card) { + return true; + }); + this.normalCollectionGroup.maxCardHeight = 200; + + this.ringBearerDiv = $("#ringBearerDiv"); + this.ringBearerDiv.click( + function () { + if ($(".card", that.ringBearerDiv).length == 0) { + that.showPredefinedFilter("keyword:CAN_START_WITH_RING type:card", that.ringBearerDiv); + } + }); + this.ringBearerGroup = new NormalFlexGroup(this.ringBearerDiv, function (card) { + return true; + }, false); + + this.ringDiv = $("#ringDiv"); + this.ringDiv.click( + function () { + if ($(".card", that.ringDiv).length == 0) + that.showPredefinedFilter("cardType:THE_ONE_RING type:card", that.ringDiv); + }); + this.ringGroup = new NormalFlexGroup(this.ringDiv, function (card) { + return true; + }, false); + + this.siteDiv = $("#sitesDiv"); + this.siteGroup = new VerticalFlexGroup(this.siteDiv, function (card) { + return true; + }, false); + + this.drawDeckDiv = $("#decksRegion"); + this.fpDeckGroup = new NormalCardGroup($("#freeps-content"), function (card) { + return (card.zone == "FREE_PEOPLE"); + }, false); + this.fpDeckGroup.maxCardHeight = 200; + this.shadowDeckGroup = new NormalCardGroup($("#shadow-content"), function (card) { + return (card.zone == "SHADOW"); + }, false); + this.shadowDeckGroup.maxCardHeight = 200; + + this.bottomBarDiv = $("#statsDiv"); + + this.selectionFunc = this.addCardToDeckAndLayout; $("body").click( function (event) { return that.clickCardFunction(event); }); + $("body")[0].addEventListener("contextmenu", + function (event) { + if(!that.clickCardFunction(event)) + { + event.preventDefault(); + return false; + } + return true; + }); $("body").mousedown( function (event) { return that.dragStartCardFunction(event); @@ -105,10 +245,492 @@ var GempLotrDeckBuildingUI2 = Class.extend({ return that.dragStopCardFunction(event); }); - this.loadExtraCollectionTypes(); + var width = $(window).width(); + var height = $(window).height(); + + this.infoDialog = $("#cardInfoDiv") + .dialog({ + autoOpen:false, + closeOnEscape:true, + resizable:false, + title:"Card information" + }); + + var swipeOptions = { + threshold:20, + swipeUp:function (event) { + that.infoDialog.prop({ scrollTop:that.infoDialog.prop("scrollHeight") }); + return false; + }, + swipeDown:function (event) { + that.infoDialog.prop({ scrollTop:0 }); + return false; + } + }; + this.infoDialog.swipe(swipeOptions); + + this.getCollectionTypes(); + + this.cardFilter.setFilter(""); + this.cardFilter.getCollection(); + + + setInterval(() => { + if (that.deckValidationDirty) { + that.deckValidationDirty = false; + that.updateDeckStats(); + } + }, this.checkDirtyInterval); + + this.updateFormatOptions(); + }, + + renameCurrentDeck:function() { + var that = this; + that.renameDeck(that.deckName, function (newDeckName) { + + if (that.deckContentsDirty && confirm("Do you wish to save this deck?")) + { + that.saveDeck(false); + } + that.deckName = newDeckName; + that.deckModified(that.deckContentsDirty); + }); + }, + + renameDeck:function(oldName, callback) { + var that = this; + + var newDeckName = prompt("Enter new name for the deck", oldName); + if (newDeckName == null) + return; + + if (newDeckName.length < 3 || newDeckName.length > 100) + alert("Deck name has to have at least 3 characters and at most 100 characters."); + else { + that.comm.renameDeck(oldName, newDeckName, () => callback(newDeckName), + { + "404":function () { + alert("Couldn't find the deck to rename on the server."); + } + }); + } }, - dragCardProps:null, + getCollectionType:function () { + return $("#collectionSelect option:selected").prop("value"); + }, + + getCollectionTypes:function () { + var that = this; + this.comm.getCollectionTypes( + function (xml) { + var root = xml.documentElement; + if (root.tagName == "collections") { + var collections = root.getElementsByTagName("collection"); + for (var i = 0; i < collections.length; i++) { + var collection = collections[i]; + $("#collectionSelect").append(""); + } + } + }); + }, + + importDecklist:function () { + var that = this; + if (that.deckImportDialog == null) { + that.deckImportDialog = $('
').dialog({ + closeOnEscape:true, + resizable:true, + title:"Import deck" + }); + } + that.deckImportDialog.html(""); + var deckImport = $(""); + var getDecklistTextBut = $("").button(); + + var importDialogDiv = $("
"); + importDialogDiv.append(deckImport); + importDialogDiv.append(getDecklistTextBut); + that.deckImportDialog.append(importDialogDiv); + + getDecklistTextBut.click( + function () { + var decklist = $('textarea[decklist="decklist"]').val() + that.parseDecklist(decklist); + } + ); + that.deckImportDialog.dialog("open"); + }, + + parseDecklist:function(rawText) { + this.clearDeck(); + var that = this; + var rawTextList = rawText.split("\n"); + var formattedText = ""; + for (var i = 0; i < rawTextList.length; i++) { + if (rawTextList[i] != "") { + var line = that.removeNotes(rawTextList[i]).toLowerCase(); + line = line.replace(/[\*•]/g,"").replace(/’/g,"'") + .replace(/starting|start|ring-bearer:|ring:/g,"") + formattedText = formattedText + line.trim() + "~"; + } + } + + this.importDeckCollection(formattedText, function (xml) { + var cards = xml.documentElement.getElementsByTagName("card"); + for (var i = 0; i < cards.length; i++) { + var cardElem = cards[i]; + var blueprintId = cardElem.getAttribute("blueprintId"); + var side = cardElem.getAttribute("side"); + var group = cardElem.getAttribute("group"); + var cardCount = parseInt(cardElem.getAttribute("count")); + for (var j = 0; j < cardCount; j++) { + if (group == "ringBearer") { + that.addCardToContainer(blueprintId, "special", that.ringBearerDiv, false).addClass("cardInDeck"); + } else if (group == "ring") { + that.addCardToContainer(blueprintId, "special", that.ringDiv, false).addClass("cardInDeck"); + } else { + that.addCardToDeckDontLayout(blueprintId, side); + } + } + } + that.deckModified(true); + that.layoutDeck(); + $("#editingDeck").text("Imported Deck (unsaved)"); + }); + }, + + removeNotes:function(line) { + var processedLine = line; + var hasNotes = false; + var start = line.indexOf("("); + var end = line.indexOf(")", start); + if (start < 0 && end < 0) { + start = line.indexOf("["); + end = line.indexOf("]", start); + } + if (start > 0) { + processedLine = line.slice(0,start) + if (end > 0) { + processedLine = processedLine + line.slice(end+1); + } + } + else if (end > 0) { + processedLine = line.slice(end+1); + } + if (processedLine.indexOf("(") > -1 || processedLine.indexOf(")") > -1 || + processedLine.indexOf("[") > -1 || processedLine.indexOf("]") > -1) { + return this.removeNotes(processedLine); + } + return processedLine; + }, + + importDeckCollection:function (decklist, callback) { + this.comm.importCollection(decklist, function (xml) { + callback(xml); + }, { + "414":function () { + alert("Deck too large to import."); + } + }); + }, + + editNotes:function() { + var that = this; + that.notesDialog = $('
') + .dialog({ + title:"Edit Deck Notes", + autoOpen:false, + closeOnEscape:true, + resizable:true, + width:700, + height:400, + modal:true + }); + + var notesElem = $(""); + + notesElem.val(that.notes); + that.notesDialog.append(notesElem); + + notesElem.change(function() { + that.notes = notesElem.val(); + that.deckModified(true); + }); + + that.notesDialog.dialog("open"); + }, + + loadDeckList:function () { + var that = this; + this.comm.getDecks(function (xml) { + if (that.deckListDialog == null) { + that.deckListDialog = $("
") + .dialog({ + title:"Your Saved Decks", + autoOpen:false, + closeOnEscape:true, + resizable:true, + width:700, + height:400, + modal:true + }); + } + that.deckListDialog.html(""); + + function formatDeckName(formatName, deckName) + { + return "[" + formatName + "] - " + deckName; + } + + var root = xml.documentElement; + if (root.tagName == "decks") { + var decks = root.getElementsByTagName("deck"); + var deckNames = []; + for (var i = 0; i < decks.length; i++) { + var deck = decks[i]; + var deckName = deck.childNodes[0].nodeValue; + deckNames[i] = deckName; + var formatName = deck.getAttribute("targetFormat"); + var openDeckBut = $("").button(); + var renameDeckBut = $("").button(); + var deckListBut = $("").button(); + var deleteDeckBut = $("").button(); + + var deckElem = $("
"); + deckElem.append(openDeckBut); + deckElem.append(renameDeckBut); + deckElem.append(deckListBut); + deckElem.append(deleteDeckBut); + var deckNameDiv = $("").html(formatDeckName(formatName, deckName)); + deckElem.append(deckNameDiv); + + that.deckListDialog.append(deckElem); + + openDeckBut.click( + (function (i) { + return function () { + that.comm.getDeck(deckNames[i], + function (xml) { + that.setupDeck(xml, deckNames[i]); + }); + }; + })(i)); + + + deckListBut.click( + (function (i) { + return function () { + that.comm.shareDeck(deckNames[i], + function(html) { + window.open('/share/deck?id=' + html, "_blank"); + }); + }; + })(i)); + + renameDeckBut.click( + (function (i, formatName, deckNameDiv) { + return function () { + that.renameDeck(deckNames[i], function (newDeckName) { + deckNameDiv.html(formatDeckName(formatName, newDeckName)); + + if (that.deckName == deckNames[i]) + { + that.deckName = newDeckName; + that.deckModified(that.deckContentsDirty); + } + deckNames[i] = newDeckName; + }) + }; + })(i, formatName, deckNameDiv)); + + deleteDeckBut.click( + (function (i) { + return function () { + if (confirm("Are you sure you want to delete this deck?")) { + that.comm.deleteDeck(deckNames[i], + function () { + if (that.deckName == deckNames[i]) { + that.deckName = null; + $("#editingDeck").text("New deck"); + that.clearDeck(); + } + + that.loadDeckList(); + }); + } + }; + })(i)); + } + } + + that.deckListDialog.dialog("open"); + }); + }, + + loadLibraryList:function () { + var that = this; + this.comm.getLibraryDecks(function (xml) { + if (that.deckListDialog == null) { + that.deckListDialog = $("
") + .dialog({ + title:"Library Decks", + autoOpen:false, + closeOnEscape:true, + resizable:true, + width:700, + height:400, + modal:true + }); + } + that.deckListDialog.html(""); + + function formatDeckName(formatName, deckName) + { + return "[" + formatName + "] - " + deckName; + } + + var root = xml.documentElement; + if (root.tagName == "decks") { + var decks = root.getElementsByTagName("deck"); + var deckNames = []; + for (var i = 0; i < decks.length; i++) { + var deck = decks[i]; + var deckName = deck.childNodes[0].nodeValue; + deckNames[i] = deckName; + var formatName = deck.getAttribute("targetFormat"); + var openDeckBut = $("").button(); + var deckListBut = $("").button(); + + var deckElem = $("
"); + deckElem.append(openDeckBut); + deckElem.append(deckListBut); + var deckNameDiv = $("").html(formatDeckName(formatName, deckName)); + deckElem.append(deckNameDiv); + + that.deckListDialog.append(deckElem); + + openDeckBut.click( + (function (i) { + return function () { + that.comm.getLibraryDeck(deckNames[i], + function (xml) { + that.setupDeck(xml, deckNames[i]); + that.deckModified(true); + }); + }; + })(i)); + + + deckListBut.click( + (function (i) { + return function () { + window.open('/gemp-lotr-server/deck/libraryHtml?deckName=' + encodeURIComponent(deckNames[i]), "_blank"); + }; + })(i)); + } + } + + that.deckListDialog.dialog("open"); + }); + }, + + clickCardFunction:function (event) { + var that = this; + + var tar = $(event.target); + if (tar.length == 1 && tar[0].tagName == "A") + return true; + + if (!this.successfulDrag && this.infoDialog.dialog("isOpen")) { + this.infoDialog.dialog("close"); + event.stopPropagation(); + return false; + } + + if (tar.hasClass("actionArea")) { + var selectedCardElem = tar.closest(".card"); + if (event.which >= 1) { + if (!this.successfulDrag) { + if (event.shiftKey || event.which > 1) { + this.displayCardInfo(selectedCardElem.data("card")); + return false; + } else if (selectedCardElem.hasClass("cardInCollection")) { + var cardData = selectedCardElem.data("card"); + this.selectionFunc(cardData.blueprintId, cardData.zone); + cardData.tokens = {count:(parseInt(cardData.tokens["count"]) - 1)}; + layoutTokens(selectedCardElem); + } else if (selectedCardElem.hasClass("packInCollection")) { + // if (confirm("Would you like to open this pack?")) { + this.comm.openPack(this.getCollectionType(), selectedCardElem.data("card").blueprintId, function () { + that.cardFilter.getCollection(); + }, { + "404":function () { + alert("You have no pack of this type in your collection."); + } + }); + //} + } else if (selectedCardElem.hasClass("cardToSelect")) { + this.comm.openSelectionPack(this.getCollectionType(), this.packSelectionId, selectedCardElem.data("card").blueprintId, function () { + that.cardFilter.getCollection(); + }, { + "404":function () { + alert("You have no pack of this type in your collection or that selection is not available for this pack."); + } + }); + this.selectionDialog.dialog("close"); + } else if (selectedCardElem.hasClass("selectionInCollection")) { + var selectionDialogResize = function () { + var width = that.selectionDialog.width() + 10; + var height = that.selectionDialog.height() + 10; + that.selectionGroup.setBounds(2, 2, width - 2 * 2, height - 2 * 2); + }; + + if (this.selectionDialog == null) { + this.selectionDialog = $("
") + .dialog({ + title:"Choose one", + autoOpen:false, + closeOnEscape:true, + resizable:true, + width:400, + height:200, + modal:true + }); + + this.selectionGroup = new NormalCardGroup(this.selectionDialog, function (card) { + return true; + }, false); + + this.selectionDialog.bind("dialogresize", selectionDialogResize); + } + this.selectionDialog.html(""); + var cardData = selectedCardElem.data("card"); + this.packSelectionId = cardData.blueprintId; + var selection = selectedCardElem.data("selection"); + var blueprintIds = selection.split("|"); + for (var i = 0; i < blueprintIds.length; i++) { + var card = new Card(blueprintIds[i], "selection", "selection" + i, "player"); + var cardDiv = createCardDiv(card.imageUrl, null, card.isFoil(), false, card.isPack(), card.hasErrata()); + cardDiv.data("card", card); + cardDiv.addClass("cardToSelect"); + this.selectionDialog.append(cardDiv); + } + openSizeDialog(that.selectionDialog); + selectionDialogResize(); + } else if (selectedCardElem.hasClass("cardInDeck")) { + this.removeCardFromDeck(selectedCardElem); + } + event.stopPropagation(); + } + } + return false; + } + return true; + }, + + dragCardData:null, dragStartX:null, dragStartY:null, successfulDrag:null, @@ -116,12 +738,10 @@ var GempLotrDeckBuildingUI2 = Class.extend({ dragStartCardFunction:function (event) { this.successfulDrag = false; var tar = $(event.target); - if (tar.hasClass("clickArea")) { - var cardElem = tar.closest(".card"); - var cardProps = cardElem.data("props"); - + if (tar.hasClass("actionArea")) { + var selectedCardElem = tar.closest(".card"); if (event.which == 1) { - this.dragCardProps = cardProps; + this.dragCardData = selectedCardElem.data("card"); this.dragStartX = event.clientX; this.dragStartY = event.clientY; return false; @@ -131,12 +751,12 @@ var GempLotrDeckBuildingUI2 = Class.extend({ }, dragStopCardFunction:function (event) { - if (this.dragCardProps != null) { + if (this.dragCardData != null) { if (this.dragStartY - event.clientY >= 20) { - this.cardInformationDialog.showCardInfo(this.dragCardProps["blueprintId"]); + this.displayCardInfo(this.dragCardData); this.successfulDrag = true; } - this.dragCardProps = null; + this.dragCardData = null; this.dragStartX = null; this.dragStartY = null; return false; @@ -144,176 +764,401 @@ var GempLotrDeckBuildingUI2 = Class.extend({ return true; }, - clickCardFunction: function(event) { - var tar = $(event.target); - if (tar.length == 1 && tar[0].tagName == "A") - return true; + displayCardInfo:function (card) { + this.infoDialog.html(""); + this.infoDialog.html("
"); + this.infoDialog.append(createFullCardDiv(card.imageUrl, card.foil, card.horizontal, card.isPack())); + if (card.hasWikiInfo()) + this.infoDialog.append("
Wiki
"); + var windowWidth = $(window).width(); + var windowHeight = $(window).height(); - if (!this.successfulDrag && this.cardInformationDialog.isOpened()) { - this.cardInformationDialog.close(); - event.stopPropagation(); - return false; + var horSpace = 30; + var vertSpace = 45; + + if (card.horizontal) { + // 500x360 + this.infoDialog.dialog({width:Math.min(500 + horSpace, windowWidth), height:Math.min(380 + vertSpace, windowHeight)}); + } else { + // 360x500 + this.infoDialog.dialog({width:Math.min(360 + horSpace, windowWidth), height:Math.min(520 + vertSpace, windowHeight)}); } - - if (tar.hasClass("clickArea")) { - var cardElem = tar.closest(".card"); - var cardProps = cardElem.data("props"); - - if (event.which == 1) { - if (!this.successfulDrag) { - // If card in collection - if (event.shiftKey) { - this.cardInformationDialog.showCardInfo(cardProps["blueprintId"]); - } else if (cardProps["inCollection"] == "true") { - // add card to deck - this.addCardToDeck(cardProps["type"], cardProps["group"], - cardProps["blueprintId"], cardProps["image"]); - this.updateCardCount(cardElem, cardProps); - } else if (cardProps["inDeck"] == "true") { - // remove card from deck - this.deckPanel.removeCardAndUpdate(cardElem, cardElem.data("id"), cardProps); - this.updateCardCounts(); - } - } - } - } - return true; + this.infoDialog.dialog("open"); }, - loadExtraCollectionTypes:function () { + getDeckContents:function () { + var ringBearer = $(".card", this.ringBearerDiv); + var ring = $(".card", this.ringDiv); + + var result = ""; + if (ringBearer.length > 0) + result += ringBearer.data("card").blueprintId; + result += "|"; + if (ring.length > 0) + result += ring.data("card").blueprintId; + result += "|"; + + var sites = new Array(); + $(".card", this.siteDiv).each( + function () { + sites.push($(this).data("card").blueprintId); + }); + result += sites; + result += "|"; + + var cards = new Array(); + $(".card", this.drawDeckDiv).each( + function () { + cards.push($(this).data("card").blueprintId); + }); + result += cards; + + return result; + }, + + saveDeck:function (reloadList) { var that = this; - this.comm.getCollectionTypes( - function (xml) { - var root = xml.documentElement; - if (root.tagName == "collections") { - var collections = root.getElementsByTagName("collection"); - for (var i = 0; i < collections.length; i++) { - var collection = collections[i]; - that.collectionSelect.append(""); - } + + var deckContents = this.getDeckContents(); + if (deckContents == null) + alert("Deck must contain at least Ring-bearer, The One Ring and 9 sites"); + else + this.comm.saveDeck(this.deckName, that.formatSelect.val(), this.notes, deckContents, function (xml) { + that.deckModified(false); + alert("Deck was saved. Refresh the Game Hall to see it!"); + }, { + "400":function () { + alert("Invalid deck format."); } }); }, - layoutCollectionContainer : function(cardGroups, left, top, width, height) { - var padding = 3; - cardGroups["main"].setLayout(left + padding, top + padding, width - 2 * padding, height - 2 * padding); + addCardToContainer:function (blueprintId, zone, container, tokens) { + var card = new Card(blueprintId, zone, "deck", "player"); + var cardDiv = createCardDiv(card.imageUrl, null, card.isFoil(), tokens, card.isPack(), card.hasErrata()); + cardDiv.data("card", card); + container.append(cardDiv); + return cardDiv; }, - clearCollection: function() { - $(".card", this.collectionContentsDiv).remove(); - this.cardInCollectionId = 0; + showPredefinedFilter:function (filter, container) { + this.cardFilter.enableDetailFilters(false); + this.specialSelection = true; + this.cardFilter.setFilter(filter); + + var that = this; + this.selectionFunc = function (blueprintId) { + var cardDiv = this.addCardToContainer(blueprintId, "special", container, false); + cardDiv.addClass("cardInDeck"); + that.showNormalFilter(); + that.layoutSpecialGroups(); + that.deckModified(true); + }; }, - addCardToDeck: function(type, group, blueprintId, image, horizontal) { - var cardProps = {}; - cardProps["type"] = type; - cardProps["group"] = group; - cardProps["blueprintId"] = blueprintId; - cardProps["image"] = image; - cardProps["hor"] = horizontal; - cardProps["inDeck"] = "true"; - this.deckPanel.addCardAndUpdate(this.createDeckCardElem(cardProps), "" + (this.cardInDeckId++), cardProps); + showNormalFilter:function () { + this.cardFilter.enableDetailFilters(true); + this.specialSelection = false; + this.cardFilter.setFilter(""); + + this.selectionFunc = this.addCardToDeckAndLayout; }, - addCardToCollection: function(type, blueprintId, count, group, contents) { - var props = {}; - props["blueprintId"] = blueprintId; - props["count"] = count; - props["type"] = type; + addCardToDeckDontLayout:function (blueprintId, side) { + var that = this; + if (side == "FREE_PEOPLE") { + this.addCardToDeck(blueprintId, side); + } else if (side == "SHADOW") { + this.addCardToDeck(blueprintId, side); + } else if (side == null) { + var div = this.addCardToContainer(blueprintId, side, this.siteDiv, false) + div.addClass("cardInDeck"); + } + }, - var card = new Card(blueprintId, "collection", "1", "player", null); + addCardToDeckAndLayout:function (blueprintId, side) { + var that = this; + if (side == "FREE_PEOPLE") { + this.addCardToDeck(blueprintId, side); + that.fpDeckGroup.layoutCards(); + } else if (side == "SHADOW") { + this.addCardToDeck(blueprintId, side); + that.shadowDeckGroup.layoutCards(); + } else if (side == null) { + var div = this.addCardToContainer(blueprintId, side, this.siteDiv, false) + div.addClass("cardInDeck"); + that.siteGroup.layoutCards(); + } + that.deckModified(true); + }, + deckModified:function (value) { + + var name = (this.deckName == null) ? "New deck" : this.deckName; + if (value) + { + this.deckValidationDirty = true; + this.deckContentsDirty = true; + $("#editingDeck").html("*" + name + " - modified"); + } + else + { + this.deckContentsDirty = false; + $("#editingDeck").text(name); + } + }, + + addCardToDeck:function (blueprintId, side) { + var that = this; + var added = false; + $(".card.cardInDeck", this.drawDeckDiv).each( + function () { + var cardData = $(this).data("card"); + if (cardData.blueprintId == blueprintId) { + var attDiv = that.addCardToContainer(blueprintId, "attached", that.drawDeckDiv, false); + cardData.attachedCards.push(attDiv); + added = true; + } + }); + if (!added) { + var div = this.addCardToContainer(blueprintId, side, this.drawDeckDiv, false) + div.addClass("cardInDeck"); + } + + this.deckModified(true); + }, + + updateDeckStats:function () { + var that = this; + var deckContents = this.getDeckContents(); + if (deckContents != null && deckContents != "") + { + this.comm.getDeckStats(deckContents, + $("#formatSelect").val(), + function (html) + { + $("#deckStats").html(html); + }, + { + "400":function () + { + alert("Invalid deck for getting stats."); + } + }); + } else { + $("#deckStats").html("Deck has no Ring, Ring-bearer or all 9 sites"); + } + }, + + updateFormatOptions:function() { + var that = this; + var currentFormat = $("#formatSelect").val(); + + this.comm.getFormats(false, + function (json) + { + that.formatSelect.empty(); + //var formats = JSON.parse(json); + $(json).each(function (index, o) { + var $option = $("