function solitaireGame(oUniqueName,oWorkspace,oDeck,oWastePile,oFoundation,oTableau,oCardWord,oCardNames,oSuits,youWin,oDeal,oOptions,
prefDone,prefCanc,prefName,imgPref,dealPref,cardPref,backPref,deal1,deal3) {
if( !window.playingCard ) { return; }
if( !this.throwError ) {
solitaireGame.prototype.throwError('SolitaireIncorrectCall','You must use the \'new\' keyword when creating a game of solitaire.');
}
if( !document.getElementById || !document.childNodes || !document.createElement || !document.createElement('div') ) {
this.throwError('SolitaireBrowserNotGoodEnough','The browser you are using does not have high enough DOM support to play solitaire.',true);
}
if( !oUniqueName || ( typeof(oUniqueName) != typeof('') ) || solitaireGame.prototype.gameList[oUniqueName] ) {
this.throwError('SolitaireNoUniqueName',(solitaireGame.prototype.gameList[oUniqueName]?('Attempted to reuse the name: '+oUniqueName+'\n'):'')+
'You must specify a unique name when creating a solitaire game.');
}
if( !oWorkspace || ( oWorkspace.nodeType != 1 ) ) {
this.throwError('SolitaireNoWorkspaceParent','You must specify a parent element when creating a solitaire game.\nThe element must exist before you create the solitaireGame object.\nIf needed, use an onload listener, and use that to create the game.');
}
if( arguments.length > 2 ) {
for( var i = 2, oStr = typeof(''); ( i < arguments.length ) && ( i < 21 ); i++ ) {
if( ( i != 7 ) && ( i != 8 ) && arguments[i] && typeof(arguments[i]) != oStr ) {
this.throwError('SolitaireInvalidString','Expected a string as parameter '+(i+1)+' when creating a solitaire game.');
} else if( ( ( i == 7 ) || ( i == 8 ) ) && arguments[i] ) {
if( ( typeof( arguments[i] ) != typeof([]) ) || ( arguments[i].length < ((i==7)?13:4) ) ) {
this.throwError('SolitaireInvalidString','Expected an array containing '+((i==7)?'thirteen':'four')+' strings as parameter '+(i+1)+' when creating a solitaire game.');
}
for( var n = 0; n < ((i==7)?13:4); n++ ) {
if( !arguments[i][n] || ( typeof(arguments[i][n]) != oStr ) ) {
this.throwError('SolitaireInvalidString','Expected a string as entry '+(n+1)+' of the array passed as parameter '+(i+1)+' when creating a solitaire game.');
}
}
}
}
}
solitaireGame.prototype.gameList[oUniqueName] = this;
this.name = oUniqueName;
this.cheatsAllowed = true;
this.cards = new cardSet();
this.cards.setCardNames(oCardWord,oCardNames);
this.cards.create52Cards(oSuits)
this.cardStacks = [];
this.cardStacks[0] = new cardStack(0,0,true,oDeck?oDeck:'Deck');
this.cardStacks[1] = new cardStack(1,1,true,oWastePile?oWastePile:'Waste pile');
for( var i = 2; i < 6; i++ ) {
this.cardStacks[i] = new cardStack(2,i,true,oFoundation?oFoundation:'Foundation');
}
for( var i = 6; i < 13; i++ ) {
this.cardStacks[i] = new cardStack(3,i,true,oTableau?oTableau:'Tableau');
}
this.dealNum = ( this.solitairepref[this.name+'deal'] == '3' ) ? 3 : 1;
this.strings = {};
this.strings.youWin = youWin ? youWin : 'Congratulations, you won! Deal again?';
this.strings.prefDone = prefDone ? prefDone : 'Done';
this.strings.prefCanc = prefCanc ? prefCanc : 'Cancel';
this.strings.prefName = prefName ? prefName : 'Options';
this.strings.imgPref = imgPref ? imgPref : 'Images for size ';
this.strings.dealPref = dealPref ? dealPref : 'Dealing';
this.strings.cardPref = cardPref ? cardPref : 'Card set:';
this.strings.backPref = backPref ? backPref : 'Image back:';
this.strings.deal1 = deal1 ? deal1 : 'Deal 1';
this.strings.deal3 = deal3 ? deal3 : 'Deal 3';
for( var i = 0; i < this.cards.playingCards.length; i++ ) {
this.cards.playingCards[i].game = this;
this.cards.playingCards[i].representation.onmousedown = this.handleMousedownOnCards;
this.cards.playingCards[i].representation.onclick = this.handleClicksOnCards;
this.cards.playingCards[i].representation.ondblclick = this.handleDoubleClicksOnCards;
this.cards.playingCards[i].representation.ondragstart = function () { return false; };
if( window.opera ) {
this.cards.playingCards[i].representation.onfocus = function () {
if( this.relatedObject == this.relatedObject.cardStack.cardsInStack[this.relatedObject.cardStack.cardsInStack.length-1] ||
( this.relatedObject.cardStack.type == 3 && this.wayup ) ) {
this.style.border = '1px solid #ff0';
this.style.margin = '-1px 0px 0px -1px';
}
};
this.cards.playingCards[i].representation.onblur = function () { this.style.border = ''; this.style.margin = ''; };
}
}
for( var i = 0; i < this.cardStacks.length; i++ ) {
this.cardStacks[i].game = this;
this.cardStacks[i].hotspot.onclick = this.handleClicksOnHotspots;
}
this.workspace = document.createElement('div');
this.workspace.style.position = 'relative';
this.workspace.className = 'workspace';
this.workspace.appendChild(document.createTextNode(' '));
if( navigator.product == 'Gecko' && navigator.taintEnabled && !this.cardStacks.filter ) {
this.workspace.appendChild(document.createElement('br'));
this.workspace.appendChild(document.createTextNode(' '));
}
oWorkspace.appendChild(this.workspace);
var relatedGame = this;
this.prefsButs = document.createElement('div');
this.prefsButs.style.position = 'absolute';
this.prefsButs.style.zIndex = '2';
this.prefsButs.className = 'extrabuttons';
var dealDiv = document.createElement('div'),
optDiv = document.createElement('div');
this.dealimg = document.createElement('img'),
this.optimg = document.createElement('img');
this.dealimg.setAttribute('alt',this.dealimg.title = (oDeal?oDeal:'Deal'));
this.optimg.setAttribute('alt',this.optimg.title = (oOptions?oOptions:'Options'));
dealDiv.appendChild(this.dealimg);
optDiv.appendChild(this.optimg);
this.prefsButs.appendChild(dealDiv);
if( !( window.ActiveXObject && navigator.platform.indexOf( 'Mac' ) + 1 && window.ScriptEngine && ScriptEngine() == 'JScript' ) && !( window.opera && !window.XMLHttpRequest ) ) {
this.prefsButs.appendChild(optDiv);
}
this.dealimg.style.display = 'block';
this.optimg.style.display = 'block';
dealDiv.onclick = function () {
if( !relatedGame.ondeal || relatedGame.ondeal({type:'deal',target:relatedGame,currentTarget:relatedGame}) ) {
relatedGame.startGame();
}
};
optDiv.onclick = function () {
if( !relatedGame.onshowprefs || relatedGame.onshowprefs({type:'showprefs',target:relatedGame,currentTarget:relatedGame,cardSet:relatedGame.usingCards,cardBack:relatedGame.cardBack,dealNum:relatedGame.dealNum}) ) {
relatedGame.showPrefs();
}
};
this.cantDoOutline = !window.ActiveXObject && !navigator.taintEnabled && document.childNodes && !window.XMLHttpRequest;
}
solitaireGame.prototype.gameList = {};
solitaireGame.prototype.throwError = function (oName,oMessage,oSurpress) {
if( !window.hideCardGameErrors && !oSurpress ) { alert('Fatal error: '+oName+'\n\n'+oMessage); }
throw({name:oName,message:oMessage});
};
solitaireGame.prototype.setCheatMode = function (oMode) { this.cheatsAllowed = oMode; };
solitaireGame.prototype.toString = function () { return '[object solitaireGame: '+this.name+']'; };
solitaireGame.prototype.addImagePack = function (oImageSet,oBackImages,oExtension,oWidth,oHeight,oName) {
if( !window.playingCard ) { return; }
var oStr = typeof(''), oNum = typeof(0), oArr = typeof([]);
if( typeof( oImageSet ) != oStr ) {
this.throwError('SolitaireInvalidImagePack','Expected a string as first parameter to addImagePack method.');
}
if( typeof( oBackImages ) != oArr || !oArr.length ) {
this.throwError('SolitaireInvalidImagePack','Expected an array of back images as second parameter to addImagePack method.');
}
for( var i = 0; i < oBackImages.length; i++ ) {
if( typeof( oBackImages[i] ) != oArr || oBackImages[i].length > 2 || typeof( oBackImages[i][0] ) != oStr || typeof( oBackImages[i][1] ) != oStr ) {
this.throwError('SolitaireInvalidImagePack','Back image number '+(i+1)+' passed to addImagePack method is not in the correct format.\nExpected an array containing two strings.');
}
}
if( typeof( oExtension ) != oStr ) {
this.throwError('SolitaireInvalidImagePack','Expected a string as third parameter to addImagePack method.');
}
if( typeof( oWidth ) != oNum || oWidth < 1 || oWidth != Math.floor( oWidth ) ) {
this.throwError('SolitaireInvalidImagePack','Expected a positive integer as fourth parameter to addImagePack method.');
}
if( typeof( oHeight ) != oNum || oHeight < 1 || oHeight != Math.floor( oHeight ) ) {
this.throwError('SolitaireInvalidImagePack','Expected a positive integer as fifth parameter to addImagePack method.');
}
if( typeof( oName ) != oStr ) {
this.throwError('SolitaireInvalidImagePack','Expected a string as sixth parameter to addImagePack method.');
}
this.cards.imagePacks.addImagePack(oImageSet,oBackImages,oExtension,oWidth,oHeight,oName);
};
solitaireGame.prototype.checkForWinner = function () {
for( var i = 2; i < 6; i++ ) {
if( this.cardStacks[i].cardsInStack.length != 13 ) { return; }
}
this.gameInPlay = false;
var theGame = this;
setTimeout(function () {
if( theGame.ongamewon ) {
if( theGame.ongamewon({type:'gamewon',target:theGame,currentTarget:theGame}) ) {
theGame.startGame();
}
} else if( confirm(theGame.strings.youWin) ) { theGame.startGame(); }
},10);
};
solitaireGame.prototype.startGame = function (oInstantWin) {
if( !window.playingCard ) { return; }
if( !this.cards.imagePacks.availWidths.length ) {
this.throwError('SolitaireNoImagePackSpecified','You must specify at least one image pack before starting a game of solitaire.');
}
if( this.showingPrefs ) { return; }
if( this.downOnCard || this.moveOnCard ) {
this.clearMouseEvents();
}
this.doingSpatNav = null;
for( var i = 0; i < this.cardStacks.length; i++ ) {
this.cardStacks[i].cardsInStack.length = 0;
}
for( var i = 0; i < this.cards.playingCards.length; i++ ) {
this.cards.playingCards[i].cardStack = null;
}
if( oInstantWin ) {
for( var i = 2, curcard = 0; i < 6; i++ ) {
for( var j = 0; j < 13; j++ ) {
this.cards.playingCards[curcard].showFace(true);
this.cards.playingCards[curcard++].moveToStack(this.cardStacks[i]);
}
}
this.cards.shuffleCards();
} else {
this.cards.shuffleCards();
for( var i = 0, curcard = 0; i < 7; i++ ) {
for( var j = 0; j < i; j++ ) {
this.cards.playingCards[curcard].showFace(false);
this.cards.playingCards[curcard++].moveToStack(this.cardStacks[i + 6]);
}
this.cards.playingCards[curcard].showFace(true);
this.cards.playingCards[curcard++].moveToStack(this.cardStacks[i + 6]);
}
for( var i = curcard; i < this.cards.playingCards.length; i++ ) {
this.cards.playingCards[i].showFace(false);
this.cards.playingCards[i].moveToStack(this.cardStacks[0]);
}
}
this.usingCards = null;
this.setAppropriateSize();
if( !this.resizeFix && this.cards.imagePacks.availWidths.length > 1 ) {
var obRef = this, resizeTimeout;
this.resizeFix = function () {
if( resizeTimeout ) { clearTimeout(resizeTimeout); }
resizeTimeout = setTimeout(function () {
obRef.setAppropriateSize();
},200);
};
if( window.addEventListener ) {
window.addEventListener('resize',this.resizeFix,false)
} else if( window.attachEvent ) {
window.attachEvent('onresize',this.resizeFix)
}
}
this.gameInPlay = true;
if( oInstantWin ) { this.checkForWinner(); }
};
solitaireGame.prototype.setAppropriateSize = function (oNotAgain) {
if( this.downOnCard || this.moveOnCard ) {
this.clearMouseEvents();
}
var availW = this.workspace.offsetWidth;
var maxWidth = availW / 8;
var cardSize = this.cards.imagePacks.getFittingImageSize(true,maxWidth);
var cardPref = this.solitairepref[this.name+'x'+cardSize], usingCards;
if( cardPref && ( usingCards = this.cards.imagePacks.availCombo[cardPref] ) ) {
cardPref = cardPref.split('|')[2];
} else {
usingCards = this.cards.imagePacks.widths[cardSize][0];
cardPref = usingCards.backimages[0][0];
}
this.workspace.style.height = ( usingCards.height * 4.1 ) + 'px';
if( !oNotAgain && ( this.workspace.offsetWidth < availW ) ) {
this.setAppropriateSize(true);
return;
}
if( this.usingCards == usingCards ) { return; }
this.usingCards = usingCards;
this.cardBack = cardPref;
var fonts = Math.round(usingCards.height/10) + 'px';
this.cardStacks[0].setStyles(Math.round(usingCards.width / 8 ),Math.round(usingCards.height / 10 ),1,usingCards.width+'px',usingCards.height+'px',fonts);
if( this.cardStacks[0].hotspot.parentNode != this.workspace ) {
this.workspace.appendChild(this.cardStacks[0].hotspot);
}
this.cardStacks[1].setStyles(Math.round(usingCards.width / 4 ) + usingCards.width,Math.round(usingCards.height / 10 ),1,usingCards.width+'px',usingCards.height+'px',fonts);
if( this.cardStacks[1].hotspot.parentNode != this.workspace ) {
this.workspace.appendChild(this.cardStacks[1].hotspot);
}
for( var i = 2; i < 6; i++ ) {
this.cardStacks[i].setStyles(( Math.round(usingCards.width / 8 ) * ( i + 2 ) ) + ( usingCards.width * ( i + 1 ) ),Math.round(usingCards.height / 10 ),1,usingCards.width+'px',usingCards.height+'px',fonts);
if( this.cardStacks[i].hotspot.parentNode != this.workspace ) {
this.workspace.appendChild(this.cardStacks[i].hotspot);
}
}
for( var i = 6; i < 13; i++ ) {
this.cardStacks[i].setStyles(( Math.round(usingCards.width / 8 ) * ( i - 5 ) ) + ( usingCards.width * ( i - 6 ) ),Math.round(usingCards.height / 5 ) + usingCards.height,1,usingCards.width+'px',usingCards.height+'px',fonts);
if( this.cardStacks[i].hotspot.parentNode != this.workspace ) {
this.workspace.appendChild(this.cardStacks[i].hotspot);
}
}
this.prefsButs.style.left = Math.floor( ( 23 / 8 ) * usingCards.width ) + 'px';
this.prefsButs.style.top = Math.round( usingCards.height / 10 ) + 'px';
this.dealimg.style.width = this.optimg.style.width = Math.ceil( usingCards.width / 2 ) + 'px';
var buttonHeight = Math.ceil( ( 9 / 20 ) * usingCards.height );
this.dealimg.style.height = this.optimg.style.height = buttonHeight + 'px';
this.dealimg.src = this.usingCards.imageset + 'deal' + this.usingCards.extension;
this.optimg.src = this.usingCards.imageset + 'options' + this.usingCards.extension;
this.optimg.parentNode.style.marginTop = ( usingCards.height - ( 2 * buttonHeight ) ) + 'px';
this.prefsButs.style.fontSize = fonts;
if( this.prefsButs.parentNode != this.workspace ) {
this.workspace.appendChild(this.prefsButs);
}
this.cards.setCardSize(usingCards.width+'px',usingCards.height+'px');
this.cards.setImagePack(usingCards.imageset,cardPref,usingCards.extension);
for( var i = 0; i < this.cards.playingCards.length; i++ ) {
this.cards.playingCards[i].wasDragged = false;
this.cards.playingCards[i].representation.style.fontSize = fonts;
this.cards.playingCards[i].autoPositionSolitaire();
if( this.cards.playingCards[i].representation.parentNode != this.workspace ) {
this.workspace.appendChild(this.cards.playingCards[i].representation);
}
}
};
if( !window.playingCard ) {
solitaireGame.prototype.throwError('SolitaireCardGameCoreNotAvailable','Could not find the CardGameCore objects.\nThe cardgamecore.js file must be included BEFORE solitaire.js.');
}
playingCard.prototype.autoPositionSolitaire = function () {
this.representation.style.zIndex = this.positionOnStack + 2;
if( this.representation.style.opacity && this.representation.style.opacity != '1' ) {
if( !this.game.cantDoOutline ) {
this.representation.style.outline = 'none';
}
this.representation.style.opacity = '1';
this.representation.style.MozOpacity = '1';
this.representation.style.filter = 'alpha(opacity=100)';
if( this.representation.style.setProperty ) {
try { tmpCard.representation.style.setProperty('-khtml-opacity','1'); } catch(e) {}
}
}
this.representation.style.left = this.cardStack.leftPos +
( ( this.cardStack.type == 1 ) ? Math.round( this.dealNum * ( this.game.usingCards.width / 4 ) ) : 0 ) + 'px';
this.representation.style.top = this.cardStack.topPos +
( ( this.cardStack.type == 3 ) ? Math.round( this.positionOnStack * ( this.game.usingCards.height / 10 ) ) : 0 ) + 'px';
};
playingCard.prototype.dragIsStartingSolitaire = function () {
this.representation.style.zIndex = 21 + this.positionOnStack;
if( this.nextOnStack() ) { this.nextOnStack().dragIsStarting(); }
};
playingCard.prototype.dragHasStoppedSolitaire = function () {
this.autoPositionSolitaire();
if( this.nextOnStack() ) { this.nextOnStack().dragHasStopped(); }
};
playingCard.prototype.moveToStackIfPossible = function (oStack,oCheat) {
var currentStack = this.cardStack, canMove = false;
oCheat = oCheat && this.game.cheatsAllowed;
if( oStack.type == 2 ) {
if( this.nextOnStack() ) {}
else if( ( this.number == 1 ) && ( oStack.cardsInStack.length == 0 ) ) { canMove = true; }
else if( ( this.number != 1 ) && oStack.cardsInStack.length && ( oStack.cardsInStack[oStack.cardsInStack.length-1].number == this.number - 1 ) && ( oStack.cardsInStack[oStack.cardsInStack.length-1].suit == this.suit ) ) { canMove = true; }
} else if( oStack.type == 3 ) {
if( oCheat && ( oStack.cardsInStack[oStack.cardsInStack.length-1] != this ) ) { canMove = true; }
if( oStack.cardsInStack.length == 0 ) {
if( this.number == 13 ) { canMove = true; }
oCheat = false;
} else {
if( oStack.cardsInStack[oStack.cardsInStack.length-1].wayup && ( oStack.cardsInStack[oStack.cardsInStack.length-1].number == this.number + 1 ) && ( oStack.cardsInStack[oStack.cardsInStack.length-1].color != this.color ) ) { canMove = true; }
oCheat = false;
}
}
if( canMove && this.game.onmovecard && !this.game.onmovecard({type:'movecard',target:this,currentTarget:this,relatedTarget:oStack,cheat:(oCheat&&(oStack.type==3))?true:false}) ) {
canMove = false;
}
if( canMove ) {
var eachCard = this, nextCard;
while(eachCard) {
nextCard = eachCard.nextOnStack();
eachCard.moveToStack(oStack);
eachCard.autoPositionSolitaire();
eachCard = nextCard;
}
currentStack.truncate();
if( this.game.doingSpatNav && window.opera ) { this.game.workspace.className += ''; }
this.game.checkForWinner();
return true;
}
return false;
};
playingCard.prototype.cleanUpSpatNav = function () {
var tmpEl = this;
while( tmpEl ) {
tmpEl.autoPositionSolitaire();
tmpEl = tmpEl.nextOnStack();
}
this.game.doingSpatNav = null;
if( window.opera ) { this.game.workspace.className += ''; }
};
solitaireGame.prototype.handleClicksOnHotspots = function(e) {
if( !this.relatedObject.game.gameInPlay ) { return; }
if( this.downOnCard || this.moveOnCard ) {
this.clearMouseEvents();
}
if( this.relatedObject.game.doingSpatNav ) {
if( !e ) { e = window.event; }
if( !this.relatedObject.game.doingSpatNav.moveToStackIfPossible(this.relatedObject,e.altKey) ) {
this.relatedObject.game.doingSpatNav.cleanUpSpatNav();
}
this.relatedObject.game.doingSpatNav = null;
} else if( ( this.relatedObject.type == 0 ) && ( this.relatedObject.cardsInStack.length == 0 ) ) {
if( this.relatedObject.game.onresetdeck && !this.relatedObject.game.onresetdeck({type:'resetdeck',target:this.relatedObject,currentTarget:this.relatedObject,relatedTarget:this.relatedObject.game.cardStacks[1]}) ) { return; }
for( var i = this.relatedObject.game.cardStacks[1].cardsInStack.length - 1, thisCard; i >= 0; i-- ) {
thisCard = this.relatedObject.game.cardStacks[1].cardsInStack[i];
thisCard.showFace(false);
thisCard.moveToStack(this.relatedObject);
thisCard.autoPositionSolitaire();
}
this.relatedObject.game.cardStacks[1].truncate();
}
};
solitaireGame.prototype.handleDoubleClicksOnCards = function() {
if( !this.relatedObject || !this.relatedObject.game.gameInPlay ) { return; }
if( this.downOnCard || this.moveOnCard ) {
this.clearMouseEvents();
}
if( this.relatedObject.game.doingSpatNav ) {
this.relatedObject.game.doingSpatNav.cleanUpSpatNav();
}
if( !this.relatedObject.wayup ) { return; }
if( this.relatedObject != this.relatedObject.cardStack.cardsInStack[this.relatedObject.cardStack.cardsInStack.length-1] ) { return; }
this.relatedObject.wasDragged = true;
var relObj = this.relatedObject;
setTimeout(function () { relObj.wasDragged = false; },20);
if( this.relatedObject.cardStack.type == 2 ) { return; }
var currentStack = this.relatedObject.cardStack;
for( var i = 2; i < 6; i++ ) {
if( this.relatedObject.moveToStackIfPossible(this.relatedObject.game.cardStacks[i]) ) { return; }
}
};
solitaireGame.prototype.handleClicksOnCards = function (e) {
if( !this.relatedObject.game.gameInPlay ) { return; }
if( this.relatedObject.game.downOnCard ) {
this.relatedObject.game.clearMouseEvents();
} else if( this.relatedObject.game.moveOnCard ) {
return;
}
var ontop = ( this.relatedObject == this.relatedObject.cardStack.cardsInStack[this.relatedObject.cardStack.cardsInStack.length-1] );
if( !ontop && ( ( this.relatedObject.cardStack.type != 3 ) || !this.relatedObject.wayup ) ) { return; }
if( this.relatedObject.game.doingSpatNav ) {
if( !e ) { e = window.event; }
if( !this.relatedObject.game.doingSpatNav.moveToStackIfPossible(this.relatedObject.cardStack,e.altKey) ) {
this.relatedObject.game.doingSpatNav.cleanUpSpatNav();
}
this.relatedObject.game.doingSpatNav = null;
} else if( ontop && ( this.relatedObject.cardStack.type == 0 ) ) {
var eachCard = [
this.relatedObject,
( this.relatedObject.cardStack.cardsInStack.length > 1 ) ? this.relatedObject.previousOnStack() : null,
( this.relatedObject.cardStack.cardsInStack.length > 2 ) ? this.relatedObject.previousOnStack().previousOnStack() : null
];
if( this.relatedObject.game.onwastepile && !this.relatedObject.game.onwastepile({type:'wastepile',target:this.relatedObject,currentTarget:this.relatedObject,relatedTarget:this.relatedObject.game.cardStacks[1],threeCards:eachCard,dealNum:this.relatedObject.game.dealNum}) ) { return; }
for( var i = 0; i < this.relatedObject.game.dealNum; i++ ) {
if( eachCard[i] ) {
eachCard[i].dealNum = i;
eachCard[i].moveToStack(this.relatedObject.game.cardStacks[1]);
eachCard[i].showFace(true);
eachCard[i].autoPositionSolitaire();
}
}
this.relatedObject.game.cardStacks[0].truncate();
} else if( ontop && ( this.relatedObject.wayup == false ) && ( this.relatedObject.cardStack.type == 3 ) ) {
if( this.relatedObject.game.onflipcard && !this.relatedObject.game.onflipcard({type:'flipcard',target:this.relatedObject,currentTarget:this.relatedObject}) ) { return; }
this.relatedObject.showFace(true);
} else {
if( this.relatedObject.wasDragged ) {
this.relatedObject.wasDragged = false;
return;
}
this.relatedObject.game.doingSpatNav = this.relatedObject;
var tmpCard = this.relatedObject;
while( tmpCard ) {
if( !this.relatedObject.game.cantDoOutline ) {
tmpCard.representation.style.outline = '2px solid';
}
tmpCard.representation.style.opacity = '0.4';
tmpCard.representation.style.MozOpacity = '0.4';
tmpCard.representation.style.filter = 'alpha(opacity=40)';
if( tmpCard.representation.style.setProperty ) {
try { tmpCard.representation.style.setProperty('-khtml-opacity','0.4'); } catch(e) {}
}
tmpCard = tmpCard.nextOnStack();
}
if( window.opera ) { this.relatedObject.game.workspace.className += ''; }
}
};
solitaireGame.prototype.checkBrowserScrollBug = function (oScroll) {
if( window.navigator.userAgent.indexOf( 'Opera' ) + 1 ) { return 0; }
if( window.ScriptEngine && ScriptEngine().indexOf( 'InScript' ) + 1 ) { return 0; }
if( window.navigator.vendor == 'KDE' ) { return 0; }
return oScroll;
}
solitaireGame.prototype.handleMousedownOnCards = function (e) {
this.relatedObject.wasDragged = false;
if( !this.relatedObject.game.gameInPlay ) { return; }
if( solitaireGame.prototype.downOnSolitaireCard ) { return; }
if( this.relatedObject.game.doingSpatNav ) { return; }
if( !e ) { e = window.event; }
if( !e.which ) { e.which = e.button; }
if( e.which > 1 ) { return; }
if( this.relatedObject.game.downOnCard || this.relatedObject.game.moveOnCard ) {
this.relatedObject.game.clearMouseEvents();
}
var ontop = ( this.relatedObject == this.relatedObject.cardStack.cardsInStack[this.relatedObject.cardStack.cardsInStack.length-1] );
if( !( ontop && this.relatedObject.cardStack.type && ( this.relatedObject.cardStack.type < 3 ) ) && !( this.relatedObject.wayup && ( this.relatedObject.cardStack.type == 3 ) ) ) { return; }
solitaireGame.prototype.downOnSolitaireCard = this.relatedObject.game.downOnCard = this.relatedObject;
var oNum = typeof(0);
this.relatedObject.eventInformation = [
( typeof( e.pageX ) == oNum ) ? e.pageX : ( e.clientX + this.relatedObject.game.checkBrowserScrollBug( document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ),
( typeof( e.pageY ) == oNum ) ? e.pageY : ( e.clientY + this.relatedObject.game.checkBrowserScrollBug( document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ),
parseInt(this.style.left),
parseInt(this.style.top)
];
if( document.addEventListener ) {
document.addEventListener('mouseup',this.relatedObject.game.handleMouseupOnCards,false);
document.addEventListener('mousemove',this.relatedObject.game.handleMousemoveOnCards,false);
} else if( document.attachEvent ) {
document.attachEvent('onmouseup',this.relatedObject.game.handleMouseupOnCards);
document.attachEvent('onmousemove',this.relatedObject.game.handleMousemoveOnCards);
} else {
this.relatedObject.game.oldmouseup = document.onmouseup;
this.relatedObject.game.oldmousemove = document.onmousemove;
document.onmouseup = this.relatedObject.game.handleMouseupOnCards;
document.onmousemove = this.relatedObject.game.handleMousemoveOncards;
}
if( e.preventDefault ) { e.preventDefault(); }
e.returnValue = false;
return false;
};
solitaireGame.prototype.clearMouseEvents = function (noRepositioning) {
if( !this.downOnCard && !this.moveOnCard ) { return; }
var oCard = this.moveOnCard;
solitaireGame.prototype.downOnSolitaireCard = this.downOnCard = this.moveOnCard = null;
if( document.removeEventListener ) {
document.removeEventListener('mouseup',this.handleMouseupOnCards,false);
document.removeEventListener('mousemove',this.handleMousemoveOnCards,false);
} else if( document.detachEvent ) {
document.detachEvent('onmouseup',this.handleMouseupOnCards);
document.detachEvent('onmousemove',this.handleMousemoveOnCards);
} else {
document.onmouseup = this.oldmouseup;
document.onmousemove = this.oldmousemove;
this.oldmouseup = null;
this.oldmousemove = null;
}
while( !noRepositioning && oCard ) {
oCard.autoPositionSolitaire();
oCard = oCard.nextOnStack();
}
};
solitaireGame.prototype.handleMousemoveOnCards = function (e) {
var thisCard = solitaireGame.prototype.downOnSolitaireCard;
if( !thisCard ) { return; }
if( !thisCard.game.gameInPlay ) { return; }
if( thisCard.game.doingSpatNav ) { return; }
if( !thisCard.game.downOnCard && !thisCard.game.moveOnCard ) { return; }
if( thisCard.game.downOnCard ) {
thisCard.game.moveOnCard = thisCard.game.downOnCard;
thisCard.game.downOnCard = null;
var tmpCard = thisCard;
while( tmpCard ) {
tmpCard.representation.style.zIndex = 30 + tmpCard.positionOnStack;
tmpCard.representation.style.opacity = '0.4';
tmpCard.representation.style.MozOpacity = '0.4';
tmpCard.representation.style.filter = 'alpha(opacity=40)';
if( tmpCard.representation.style.setProperty ) {
try { tmpCard.representation.style.setProperty('-khtml-opacity','0.4'); } catch(e) {}
}
tmpCard = tmpCard.nextOnStack();
}
}
var oNum = typeof(0);
var oNewInfo = [
( typeof( e.pageX ) == oNum ) ? e.pageX : ( e.clientX + thisCard.game.checkBrowserScrollBug( document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ),
( typeof( e.pageY ) == oNum ) ? e.pageY : ( e.clientY + thisCard.game.checkBrowserScrollBug( document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) )
];
oNewInfo[0] = thisCard.eventInformation[2] + ( oNewInfo[0] - thisCard.eventInformation[0] );
oNewInfo[1] = thisCard.eventInformation[3] + ( oNewInfo[1] - thisCard.eventInformation[1] );
var oOffset = 0;
while( thisCard ) {
thisCard.representation.style.left = oNewInfo[0] + 'px';
thisCard.representation.style.top = ( oNewInfo[1] + Math.round( oOffset ) ) + 'px';
oOffset += thisCard.game.usingCards.height / 10;
thisCard = thisCard.nextOnStack();
}
};
solitaireGame.prototype.checkSolitaireIntersect = function(oWidth,oHeight,x1,y1,x2,y2) {
return ( x2 < x1 + oWidth ) && ( x1 < x2 + oWidth ) && ( y2 < y1 + oHeight ) && ( y1 < y2 + oHeight );
}
solitaireGame.prototype.handleMouseupOnCards = function (e) {
var thisCard = solitaireGame.prototype.downOnSolitaireCard;
if( !thisCard ) { return; }
if( !thisCard.game.gameInPlay ) { return; }
if( thisCard.game.doingSpatNav ) { return; }
if( !e ) { e = window.event; }
if( !e.which ) { e.which = e.button; }
if( e.which > 1 ) { return; }
solitaireGame.prototype.downOnSolitaireCard = null;
if( !thisCard.game.moveOnCard ) { return; }
var intersectingStack = false, allStacks = thisCard.game.cardStacks;
thisCard.wasDragged = true;
var oNum = typeof(0);
var oNewInfo = [
( typeof( e.pageX ) == oNum ) ? e.pageX : ( e.clientX + thisCard.game.checkBrowserScrollBug( document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ),
( typeof( e.pageY ) == oNum ) ? e.pageY : ( e.clientY + thisCard.game.checkBrowserScrollBug( document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) )
];
oNewInfo[0] = thisCard.eventInformation[2] + ( oNewInfo[0] - thisCard.eventInformation[0] );
oNewInfo[1] = thisCard.eventInformation[3] + ( oNewInfo[1] - thisCard.eventInformation[1] );
var currentStack = thisCard.cardStack;
for( var i = 2; i < 13; i++ ) {
if( thisCard.game.checkSolitaireIntersect( thisCard.game.usingCards.width,thisCard.game.usingCards.height,oNewInfo[0],oNewInfo[1],thisCard.game.cardStacks[i].leftPos, thisCard.game.cardStacks[i].topPos + ( ( thisCard.game.cardStacks[i].type == 3 ) ? ( ( thisCard.game.cardStacks[i].cardsInStack.length - 1 ) * ( thisCard.game.usingCards.height / 10 ) ) : 0 ) ) ) {
if( thisCard.moveToStackIfPossible(thisCard.game.cardStacks[i],e.altKey) ) {
thisCard.game.clearMouseEvents(true);
return;
}
}
}
thisCard.game.clearMouseEvents();
};
solitaireGame.prototype.getPrefCookies = function () {
solitaireGame.prototype.solitairepref = [];
var solicooks = document.cookie.split('; ');
for( var n = 0, crumb; n < solicooks.length; n++ ) {
crumb = solicooks[n].split('=');
this.solitairepref[unescape(crumb[0])] = unescape(crumb[1]);
}
}
solitaireGame.prototype.getPrefCookies();
solitaireGame.prototype.makeNewPrefCookie = function (oName,oValue) {
document.cookie = escape(oName)+'='+escape(oValue)+';expires='+
( new Date( ( new Date() ).getTime() + ( 189216000000000 ) ) ).toGMTString()+';path=/;domain='+location.hostname;
}
solitaireGame.prototype.showPrefs = function (e) {
if( this.downOnCard || this.moveOnCard ) {
this.clearMouseEvents();
}
var inPlay = this.gameInPlay;
this.gameInPlay = false;
var prefsEl = this.showingPrefs = document.createElement('div');
this.showingPrefs.className = 'solitaireprefs';
this.showingPrefs.style.position = 'absolute';
this.showingPrefs.style.left = '0px';
this.showingPrefs.style.top = '0px';
this.showingPrefs.style.width = '100%';
if( window.attachEvent && window.ActiveXObject && navigator.platform == 'Win32' ) {
this.showingPrefs.style.height = this.workspace.offsetHeight + 'px';
} else {
this.showingPrefs.style.height = '100%';
}
this.showingPrefs.style.zIndex = 100;
var oForm = document.createElement('form');
oForm.relatedGame = this;
oForm.method = 'get';
oForm.action = '';
oForm.onsubmit = function () { return false; }
var firstSelect = document.createElement('select');
var secndSelect = document.createElement('select');
var thirdSelect = document.createElement('select');
var submitBut = document.createElement('input');
var cancelBut = document.createElement('input');
var imageDiv = document.createElement('div');
imageDiv.style.styleFloat = 'right';
imageDiv.style.cssFloat = 'right';
submitBut.setAttribute('type','button');
submitBut.value = this.strings.prefDone;
cancelBut.setAttribute('type','button');
cancelBut.value = this.strings.prefCanc;
cancelBut.onclick = function () {
if( oForm.relatedGame.oncancelprefs && !oForm.relatedGame.oncancelprefs({type:'cancelprefs',target:oForm.relatedGame,currentTarget:oForm.relatedGame}) ) { return; }
oForm.relatedGame.gameInPlay = inPlay;
prefsEl.parentNode.removeChild(prefsEl);
oForm.relatedGame.showingPrefs = null;
};
submitBut.onclick = function () {
var pref1name = oForm.relatedGame.name+'x'+secndSelect.cardSet.width;
var pref2name = oForm.relatedGame.name+'deal';
if( oForm.relatedGame.onsaveprefs && !oForm.relatedGame.onsaveprefs({type:'saveprefs',target:oForm.relatedGame,currentTarget:oForm.relatedGame,cardSet:secndSelect.cardSet,cardBack:secndSelect.backs[secndSelect.selectedIndex][0],dealNum:thirdSelect.selectedIndex?3:1}) ) { return; }
oForm.relatedGame.solitairepref[pref1name] = secndSelect.cardSet.width+'x'+secndSelect.cardSet.height+'|'+secndSelect.cardSet.imageset+'|'+secndSelect.backs[secndSelect.selectedIndex][0];
oForm.relatedGame.solitairepref[pref2name] = thirdSelect.selectedIndex ? '3' : '1';
oForm.relatedGame.makeNewPrefCookie(pref1name,oForm.relatedGame.solitairepref[pref1name]);
oForm.relatedGame.makeNewPrefCookie(pref2name,oForm.relatedGame.solitairepref[pref2name]);
oForm.relatedGame.dealNum = parseInt(oForm.relatedGame.solitairepref[oForm.relatedGame.name+'deal']);
oForm.relatedGame.usingCards = null;
oForm.relatedGame.setAppropriateSize();
oForm.relatedGame.gameInPlay = inPlay;
prefsEl.parentNode.removeChild(prefsEl);
oForm.relatedGame.showingPrefs = null;
};
var prfHead = document.createElement('h3');
prfHead.appendChild(document.createTextNode(this.strings.prefName));
var imgHead = document.createElement('h4');
imgHead.appendChild(document.createTextNode(this.strings.imgPref+this.usingCards.width));
var dealHead = document.createElement('h4');
dealHead.appendChild(document.createTextNode(this.strings.dealPref));
var firstP = document.createElement('p');
var secndP = document.createElement('p');
var thirdP = document.createElement('p');
var forthP = document.createElement('p');
if( window.attachEvent && window.ActiveXObject && navigator.platform == 'Win32' ) {
prfHead.style.zoom = '1';
imgHead.style.zoom = '1';
dealHead.style.zoom = '1';
firstP.style.zoom = '1';
secndP.style.zoom = '1';
thirdP.style.zoom = '1';
forthP.style.zoom = '1';
}
var firstLabel = document.createElement('label');
var secndLabel = document.createElement('label');
firstP.appendChild(firstLabel);
secndP.appendChild(secndLabel);
thirdP.appendChild(thirdSelect);
forthP.appendChild(submitBut);
forthP.appendChild(cancelBut);
firstLabel.appendChild(document.createTextNode(this.strings.cardPref));
firstLabel.appendChild(document.createElement('br'));
firstLabel.appendChild(firstSelect);
secndLabel.appendChild(document.createTextNode(this.strings.backPref));
secndLabel.appendChild(document.createElement('br'));
secndLabel.appendChild(secndSelect);
thirdSelect.options[0] = new Option(this.strings.deal1,'');
thirdSelect.options[1] = new Option(this.strings.deal3,'');
thirdSelect.options[(this.dealNum==1)?0:1].selected = true;
thirdSelect.selectedIndex = [(this.dealNum==1)?0:1];
oForm.appendChild(imageDiv);
oForm.appendChild(prfHead);
oForm.appendChild(imgHead);
oForm.appendChild(firstP);
oForm.appendChild(secndP);
oForm.appendChild(dealHead);
oForm.appendChild(thirdP);
oForm.appendChild(forthP);
prefsEl.appendChild(oForm);
var oCardSet = this.usingCards, oCardBack = this.cardBack;
var oCardsAll = this.cards.imagePacks.widths[this.usingCards.width];
prefsEl.firstSelI = 0;
for( var i = 0, newOption; i < oCardsAll.length; i++ ) {
newOption = new Option(oCardsAll[i].name,'');
if( oCardSet == oCardsAll[i] ) {
newOption.selected = true;
prefsEl.firstSelI = i;
}
firstSelect.options[firstSelect.options.length] = newOption;
}
firstSelect.onchange = function () {
secndSelect.options.length = 0;
secndSelect.cardSet = oCardsAll[this.selectedIndex];
secndSelect.backs = secndSelect.cardSet.backimages;
prefsEl.secndSelI = 0;
for( var i = 0, newOption; i < secndSelect.backs.length; i++ ) {
newOption = new Option(secndSelect.backs[i][1],'');
if( ( oCardSet == secndSelect.cardSet ) && ( secndSelect.backs[i][0] == oCardBack ) ) {
newOption.selected = true;
prefsEl.secndSelI = i;
}
secndSelect.options[secndSelect.options.length] = newOption;
}
secndSelect.selectedIndex = prefsEl.secndSelI;
secndSelect.onchange();
};
secndSelect.onchange = function () {
if( navigator.product == 'Gecko' ) {
oForm.insertBefore(imageDiv,prfHead);
}
while( imageDiv.firstChild ) {
imageDiv.removeChild(imageDiv.firstChild);
}
var imgs = [], cardNum4 = [1,7,12,0], cardSuit4 = [0,2,1,0];
var selectedSet = secndSelect.cardSet.imageset, selectedExt = secndSelect.cardSet.extension;
for( var i = 0, innrD; i < 4; i++ ) {
if( !( i % 2 ) ) {
innrD = document.createElement('div');
imageDiv.appendChild(innrD);
try { imageDiv.style.display = 'table'; } catch(e) {}
imageDiv.style.verticalAlign = 'bottom';
}
imgs[i] = document.createElement('img');
if( cardNum4[i] ) {
imgs[i].src = selectedSet + oForm.relatedGame.cards.cardSuitNames[cardSuit4[i]] + cardNum4[i] + selectedExt;
imgs[i].setAttribute('alt',oForm.relatedGame.cards.cardNames[cardNum4[i]-1]+' '+oForm.relatedGame.cards.cardSuitNames[cardSuit4[i]]);
} else {
imgs[i].src = selectedSet + 'back' + this.backs[this.selectedIndex][0] + selectedExt;
imgs[i].setAttribute('alt',oForm.relatedGame.cards.cardWord);
}
imgs[i].setAttribute('align','bottom');
imgs[i].style.verticalAlign = 'bottom';
imgs[i].style.width = secndSelect.cardSet.width + 'px';
imgs[i].style.height = secndSelect.cardSet.height + 'px';
innrD.appendChild(imgs[i]);
}
};
firstSelect.selectedIndex = prefsEl.firstSelI;
firstSelect.onchange();
this.workspace.appendChild(prefsEl);
};