/*
JavaScript version of the hit television gameshow, "Deal or No Deal"

Copyright (c) 2007, 2008, James Auldridge
All rights reserved.
Code licensed under the BSD License:
  http://www.jaaulde.com/license.php
*/
var jaaulde = window.jaaulde || {};
jaaulde.games = jaaulde.games || {};
jaaulde.games.DoND = {
  data : {
    gameVersion : '0.10&beta;',
    caseAmounts : [.01,1,5,10,25,50,75,100,200,300,400,500,750,1000,5000,10000,25000,50000,75000,100000,200000,300000,400000,500000,750000,1000000],
    cases : [],
    remainingValues : null,
    bmc : null,
    bmcOpened : false,
    lastCaseClicked : null,
    playersCase : null,
    currentState : 0,
    currentRound : 1,
    maxRounds : 10,
    openNumCasesThisRound : 6,
    casesOpenedThisRound : 0,
    casesLeft : 0,
    bankOfferDiminisher : .25,
    latestBankOffer : 0,
    highestBankOffer : 0,
    highWinnings : 0,
    winnings : 0,
    cookieJar : false,
    setHighScore : function(){},
    init : function()
    {
      jaaulde.games.DoND.data.remainingValues = jaaulde.games.DoND.data.caseAmounts.copy();
      if(typeof jaaulde.utils !== 'undefined' && typeof jaaulde.utils.cookies !== 'undefined' && jaaulde.utils.cookies.test())
      {
        jaaulde.games.DoND.data.cookieJar = jaaulde.utils.cookies;
        var highWinnings = jaaulde.games.DoND.data.cookieJar.get('DoND_highWinnings');
        if(highWinnings !== null)
        {
          jaaulde.games.DoND.data.highWinnings = parseInt(highWinnings); 
        }
        jaaulde.games.DoND.data.setHighScore = function(value){jaaulde.games.DoND.data.cookieJar.set('DoND_highWinnings',value,8760);};
      }
    }
  },
  display : {
    action : null,
    yourCase : null,
    bankoffer : null,
    popInfo : null,
    infoText : null,
    popInfoIsOpen : false,
    resetFlashTimer : null,
    init : function()
    {
      jaaulde.games.DoND.display.showHighScore(jaaulde.games.DoND.data.highWinnings);
      $('#versionNumber').html(jaaulde.games.DoND.data.gameVersion);
      $('#reset').click(function(){jaaulde.games.DoND.controller.reset()});
      $('#deal').click(function(){jaaulde.games.DoND.controller.deal()});
      $('#noDeal').click(function(){jaaulde.games.DoND.controller.noDeal()});
      $('#closePopInfoButton').click(function(){if(jaaulde.games.DoND.display.popInfoIsOpen===true){jaaulde.games.DoND.display.closePopInfo();}});
      $('#bankofferHistory').html('');
      $(document).keydown(function(e){e = !e ? window.event : e;if(jaaulde.games.DoND.display.popInfoIsOpen===true && e.keyCode == 13 || e.which == 13){jaaulde.games.DoND.display.closePopInfo();}});
      for(var i=1;i<jaaulde.games.DoND.data.cases.length;i++)
      {
        $('<span class="notClicked" id="case'+jaaulde.games.DoND.data.cases[i].id+'">'+jaaulde.games.DoND.data.cases[i].id+'</span>').click(jaaulde.games.DoND.controller.selectCase).appendTo('#caseDiv');
      }
      $('#strikeAmts tbody').html('');
      var breakNum=Math.floor(jaaulde.games.DoND.data.caseAmounts.length/2);
      for(i=0;i<breakNum;i++)
      {
        col1ID = i;
        col2ID = i + breakNum;
        $('<tr><td id="sa'+col1ID+'">'+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.caseAmounts[col1ID])+'</td><td id="sa'+col2ID+'">'+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.caseAmounts[col2ID])+'</td>').appendTo('#strikeAmts tbody');
      }
    },
    formatUSD : function(num,hideZeroCents)
    {
      var sign,cents,dollars,numCommas,i,cPos;
      hideZeroCents = typeof hideZeroCents !== 'boolean'?true:false;
      num = num.toString().replace(/[^0-9.-]/g,'');
      num = isNaN(num)?'0':num;
      sign = num==(num=Math.abs(num))?'':'-';
      num = num.toFixed(2);
      cents = Math.round((num*100)%100);
      cents = cents<10?'0'+cents:cents;
      cents = (hideZeroCents===true && cents=='00')?'':'.'+cents
      dollars = Math.floor(num).toString();
      numCommas = Math.floor(dollars.length/3);
      numCommas = dollars.length%3==0?numCommas-1:numCommas;
      for(i=0;i<numCommas;i++)
      {
        cPos = dollars.indexOf(',');
        if(cPos===-1){cPos=dollars.length;}
        dollars = dollars.substring(0,cPos-3)+','+dollars.substring(cPos-3,dollars.length);
      }
      return sign+'$'+dollars+cents;
    },
    showHighScore : function(value)
    {
      $('#highscore').html(jaaulde.games.DoND.display.formatUSD(value))
    },
    markPlayersCase : function(el)
    {
      $(el).removeClass('notClicked').addClass('playersCase').html('');
      $('#yourCase').addClass('caseSelected').html(jaaulde.games.DoND.data.playersCase.id);
      jaaulde.games.DoND.display.setAction('Choose '+jaaulde.games.DoND.data.openNumCasesThisRound+' cases to eliminate.');
    },
    markOutOfPlayCase : function(el)
    {
      $(el).removeClass('notClicked').addClass('outOfPlay');
    },
    strikeAmount : function(id)
    {
      $('#sa'+id).addClass('struck');
    },
    openPopInfo : function(text)
    {
      $('#infoText').html(text);
      $('#popInfo').removeClass('hidden').addClass('revealed');
      jaaulde.games.DoND.display.popInfoIsOpen=true;
    },
    closePopInfo : function()
    {
      $('#popInfo').removeClass('revealed').addClass('hidden');
      $('#infoText').html('');
      jaaulde.games.DoND.display.popInfoIsOpen=false;
      jaaulde.games.DoND.controller.popInfoClosed();
    },
    showBankOffer : function()
    {
      jaaulde.games.DoND.display.setAction('The bank has made an offer.<br /><em>Deal or No Deal?</em>');
      $('#bankoffer').html(jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.latestBankOffer));
      $('#offerbuttons input').removeAttr('disabled');
    },
    removeBankOffer : function()
    {
      $('#bankoffer').html('');
      $('#offerbuttons input').attr('disabled','disabled');
      $('<li>'+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.latestBankOffer)+'</li>').appendTo('#bankofferHistory');
    },
    setAction : function(text)
    {
      $('#action').html(text);
    },
    flashReset : function()
    {
      $('#reset').mouseover(function(){clearTimeout(jaaulde.games.DoND.display.resetFlashTimer)}).css({fontWeight: 'bold', color: '#f00'});
      jaaulde.games.DoND.display.resetFlashCycler()
    },
    resetFlashCycler : function()
    {
      $('#reset').toggle();
      jaaulde.games.DoND.display.resetFlashTimer = setTimeout('jaaulde.games.DoND.display.resetFlashCycler()',400);
    }
  },
  controller : {
    popInfoClosed : function(){if(jaaulde.games.DoND.data.currentState == 3){jaaulde.games.DoND.controller.gameFlow();}},
    buildCases : function()
    {
      var values = jaaulde.games.DoND.data.caseAmounts.copy();
      var numCases = values.length;
      var ranNumber,ranValue;
      for(var i=numCases;i>=1;i--)
      {
        ranNumber=Math.floor(Math.random()*i);
        ranValue = values[ranNumber];
        if(ranValue==1000000){jaaulde.games.DoND.data.bmc=i;}
        valueIndex = jaaulde.games.DoND.data.caseAmounts.indexOf(ranValue);
        values.splice(ranNumber,1);
        jaaulde.games.DoND.data.cases[i] = new jaaulde.games.DoND.controller.briefcase(i,ranValue,valueIndex);
        jaaulde.games.DoND.data.casesLeft++;
      }
    },
    briefcase : function(id,value,valueIndex)
    {
      this.id = id;
      this.value = value;
      this.valueIndex = valueIndex;
      this.inPlay = true;
      this.caseDisplayElement = false;
      jaaulde.games.DoND.controller.briefcase.prototype.choose = function(el)
      {
        if(jaaulde.games.DoND.display.popInfoIsOpen === false && jaaulde.games.DoND.data.currentState!==10)
        {
          if(this.inPlay)
          {
            this.inPlay = false;
            this.caseDisplayElement = el;
            jaaulde.games.DoND.data.lastCaseClicked = this;
            jaaulde.games.DoND.data.casesLeft--;
            if(this.value==1000000)
            {
              jaaulde.games.DoND.data.bmcOpened=true;
            }
            jaaulde.games.DoND.controller.gameFlow();
          }
        }
      }
    },
    gameFlow : function()
    {
      switch (jaaulde.games.DoND.data.currentState)
      {
        case 0:
          jaaulde.games.DoND.data.currentState=1;
          jaaulde.games.DoND.data.playersCase = jaaulde.games.DoND.data.lastCaseClicked;
          jaaulde.games.DoND.display.markPlayersCase(jaaulde.games.DoND.data.lastCaseClicked.caseDisplayElement);
          break;

        case 1:
          jaaulde.games.DoND.data.casesOpenedThisRound++;
          jaaulde.games.DoND.data.remainingValues.splice(jaaulde.games.DoND.data.remainingValues.indexOf(jaaulde.games.DoND.data.lastCaseClicked.value),1);
          jaaulde.games.DoND.display.strikeAmount(jaaulde.games.DoND.data.lastCaseClicked.valueIndex);
          jaaulde.games.DoND.display.markOutOfPlayCase(jaaulde.games.DoND.data.lastCaseClicked.caseDisplayElement);
          jaaulde.games.DoND.display.setAction('Choose '+(jaaulde.games.DoND.data.openNumCasesThisRound-jaaulde.games.DoND.data.casesOpenedThisRound)+' more case(s) to eliminate.');
          jaaulde.games.DoND.display.openPopInfo('Case '+jaaulde.games.DoND.data.lastCaseClicked.id+' contained<br />'+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.lastCaseClicked.value));
          if(jaaulde.games.DoND.data.casesOpenedThisRound==jaaulde.games.DoND.data.openNumCasesThisRound)
          {
            jaaulde.games.DoND.data.currentRound++;
            jaaulde.games.DoND.data.casesOpenedThisRound = 0;
            jaaulde.games.DoND.data.openNumCasesThisRound = jaaulde.games.DoND.data.openNumCasesThisRound>1?jaaulde.games.DoND.data.openNumCasesThisRound-1:jaaulde.games.DoND.data.openNumCasesThisRound;
            if(jaaulde.games.DoND.data.currentRound<=jaaulde.games.DoND.data.maxRounds)
            {
              jaaulde.games.DoND.data.currentState = 10;
              jaaulde.games.DoND.controller.makeBankOffer();
            }
            else
            {
              jaaulde.games.DoND.data.currentState = 3;
              jaaulde.games.DoND.data.winnings = jaaulde.games.DoND.data.playersCase.value;
              var compString = jaaulde.games.DoND.data.playersCase.value > jaaulde.games.DoND.data.highestBankOffer
                        ? 'You came out ahead of all bank offers!'
                        : "At least one bank offer was higher than your case's value--you should have quit while you were ahead!";
              jaaulde.games.DoND.display.openPopInfo("Your case held<br /><strong>"+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.playersCase.value)+"</strong><br /><br />"+compString);
            }
          }
          break;

        case 3:
          jaaulde.games.DoND.data.currentState = 10;
          jaaulde.games.DoND.display.setAction('Game over.  Reset to play again.');
          jaaulde.games.DoND.display.flashReset();
          var summaryString = 'Your winnings this game:<br /><strong>'+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.winnings)+'</strong><br /><br />';
          if(jaaulde.games.DoND.data.winnings > jaaulde.games.DoND.data.highWinnings)
          {
            summaryString += '<strong>This is a new high score for you!</strong>';
            jaaulde.games.DoND.display.showHighScore(jaaulde.games.DoND.data.winnings);
            jaaulde.games.DoND.data.setHighScore(jaaulde.games.DoND.data.winnings);
          }
          else
          {
            if(jaaulde.games.DoND.data.highWinnings>0)
            {
              summaryString += 'Your high score:<br /><strong>'+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.highWinnings)+'</strong>';
            }
          }
          jaaulde.games.DoND.display.openPopInfo(summaryString);
          break;

        case 10:
          break;
      }
    },
    selectCase : function()
    {
      elId = parseInt($(this).attr('id').match(/[0-9]+$/));
      jaaulde.games.DoND.data.cases[elId].choose($(this));
    },
    caseMeanCalc : function()
    {
      var sum,qty=jaaulde.games.DoND.data.remainingValues.length;
      if(qty>0)
      {
        sum = jaaulde.games.DoND.data.remainingValues.sum();
        var mean = (sum/qty).toFixed(2);
        return mean;
      }
      else
      {
        throw 'DoND controller object called method caseMeanCalc with no values left--proceding would cause divide by zero.';
      }
    },
    makeBankOffer : function()
    {
      var multiplier,rounder;
      jaaulde.games.DoND.data.latestBankOffer = jaaulde.games.DoND.controller.caseMeanCalc();
      multiplier = (jaaulde.games.DoND.data.bankOfferDiminisher*jaaulde.games.DoND.data.currentRound).toFixed(2);
      multiplier = multiplier>1 ? 1 : multiplier;
      jaaulde.games.DoND.data.latestBankOffer = multiplier<1 ? Math.round(jaaulde.games.DoND.data.latestBankOffer*multiplier) : jaaulde.games.DoND.data.latestBankOffer;
      if(jaaulde.games.DoND.data.latestBankOffer >= 0 && jaaulde.games.DoND.data.latestBankOffer <=99)
      {
        rounder = 10;
      }
      else if(jaaulde.games.DoND.data.latestBankOffer >= 100 && jaaulde.games.DoND.data.latestBankOffer <=9999)
      {
        rounder = 100;
      }
      else
      {
        rounder = 1000;
      }
      jaaulde.games.DoND.data.latestBankOffer = (Math.round(jaaulde.games.DoND.data.latestBankOffer/rounder))*rounder;
      jaaulde.games.DoND.data.latestBankOffer = jaaulde.games.DoND.data.latestBankOffer<.5 ? .5 : jaaulde.games.DoND.data.latestBankOffer;
      jaaulde.games.DoND.data.highestBankOffer = jaaulde.games.DoND.data.latestBankOffer>jaaulde.games.DoND.data.highestBankOffer ? jaaulde.games.DoND.data.latestBankOffer : jaaulde.games.DoND.data.highestBankOffer;
      jaaulde.games.DoND.display.showBankOffer();
    },
    deal : function()
    {
      var goodDealInfo,compString,millionDollarCaseReveal;
      jaaulde.games.DoND.display.removeBankOffer();
      jaaulde.games.DoND.data.currentState = 3;
      jaaulde.games.DoND.data.winnings = jaaulde.games.DoND.data.latestBankOffer;
      goodDealInfo = jaaulde.games.DoND.data.latestBankOffer > jaaulde.games.DoND.data.playersCase.value ? 'You made a good deal!' : 'You could have done better...';
      compString = jaaulde.games.DoND.data.winnings < jaaulde.games.DoND.data.highestBankOffer ? '<br /><br />There were earlier bank offers for more...you should have quit while you were ahead.' : '';
      millionDollarCaseReveal = jaaulde.games.DoND.data.bmcOpened ? '' : '<br /><br />By the way, the $1,000,000 was in case '+jaaulde.games.DoND.data.bmc;
      jaaulde.games.DoND.display.openPopInfo("You've taken the deal for<br /><strong>"+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.latestBankOffer)+"</strong><br /><br />Your case held<br /><strong>"+jaaulde.games.DoND.display.formatUSD(jaaulde.games.DoND.data.playersCase.value)+"</strong><br /><br />"+goodDealInfo+compString+millionDollarCaseReveal);
    },
    noDeal : function()
    {
      jaaulde.games.DoND.display.removeBankOffer();
      jaaulde.games.DoND.display.setAction('Choose '+jaaulde.games.DoND.data.openNumCasesThisRound+' more case(s) to eliminate.');
      jaaulde.games.DoND.data.currentState = 1;
    },
    reset : function()
    {
      window.location = window.location.href;
    },
    init : function()
    {
      jaaulde.games.DoND.controller.buildCases();
    }
  },
  setup : function()
  {
    jaaulde.games.DoND.data.init();
    jaaulde.games.DoND.controller.init();
    jaaulde.games.DoND.display.init();
  },
  init : function()
  {
    if(!Array.prototype.copy){Array.prototype.copy = function(){return this.concat();}}
    if(!Array.prototype.indexOf){Array.prototype.indexOf = function(value,start){var sPos,i,returnVal=-1;sPos = start || 0;for(i=sPos;i<this.length;i++){if(this[i]===value){returnVal = i;break;}}return returnVal;};}
    if(!Array.prototype.sum){Array.prototype.sum = function(){var i,points,prec=0,sum=0;for(i=0;i<this.length;i++){if(!isNaN(this[i])){points = this[i].toString().split('.');points = points[1]?points.length:0;prec = points>prec?points:prec;sum += parseFloat(this[i]);}}return sum.toFixed(prec);};}
    $(window).load(function(){jaaulde.games.DoND.setup();});
    $(window).unload(function(){$('#DoND-display-root').html('');DoND = null;});
  }()
}