﻿

function ContestInterface(contestWagers, gridSize, minimumSelectionsRequired, maximumSectionsRequired)
{
    if(gridSize == undefined)
    {
        gridSize = 5; //This was the first contest the Customer asked for (A Pick 5 out of 25 contest) 
    }
    
    this.GridSize = gridSize; //Example: 5. That means it is a 5 by 5 grid. The total picks would be 5squared (25).
    
    if(minimumSelectionsRequired == undefined)
    {
        minimumSelectionsRequired = gridSize;
    }

    this.MinimumSelectionsRequired = minimumSelectionsRequired; //By default it would be the gridsize but in some cases a contest might allow you to only have to pick 1 or 2 out of all the choices.
    
    if(maximumSectionsRequired == undefined)
    {
        maximumSectionsRequired = minimumSelectionsRequired;
    }
    this.MaximumSectionsRequired = maximumSectionsRequired; //By default this is going to be the same as the MinimumSelectionsRequired. However the customer miught want to change it up some day.
    
    
    
    //Do not add to this array outside of the AddContestWagerBlock function!!
    this.ContestWagerBlocks = new Array(); //Of ContestWagerBlock's.
    if(contestWagers != null)
    {
        this.ContestWagerBlocks = contestWagers;
    }
    
    //Do not add to this array outside of the AddContestWagerBlock function!!
    this.SelectedContestWagerBlocks = new Array(); //Of ContestWagerBlock's.
    
}

ContestInterface.prototype.AddContestWagerBlock = function(wagerBlock)
{
    var totalBocks = (this.ContestWagerBlocks.length);
    if(totalBocks >= (this.GridSize*this.GridSize))
    {
        throw "Cannot add another ContestWagerBlock. The maximum number has already been met. The Total allowed blocks are: " + (this.GridSize*this.GridSize);
    }
    this.ContestWagerBlocks.push(wagerBlock);
    
    totalBocks++;
    return totalBocks;
}


/// <summary>
/// Adds a selected WagerBlock to the selected picks.
/// </summary>
/// <param name="wagerBlock">The selected block from the grid</param>
ContestInterface.prototype.SelectContestWagerBlock = function(wagerBlock)
{
    var totalSelectedBocks = (this.SelectedContestWagerBlocks.length);
    if(totalSelectedBocks >= (this.GridSize))
    {
        alert('You cannot select more than ' + this.GridSize + ' picks.');
        return -1;
    }
    this.SelectedContestWagerBlocks.push(wagerBlock);
    
    totalSelectedBocks++;
    return totalSelectedBocks;
}




/// <summary>
/// Checks if a block has already been selected. Returns it's index from the SelectedContestWagerBlocks array if found. If not then returns -1;
/// </summary>
/// <param name="index">The block's row index from the grid.</param>
/// <param name="rowIndex">The block's column index from the grid.</param>
ContestInterface.prototype.IsBlockAlreadySelected = function(rowIndex, columnIndex)
{
    var existingIndex = -1;

    for(var x = 0; x < this.SelectedContestWagerBlocks.length; x++)
    {
        if(this.SelectedContestWagerBlocks[x].RowIndex == rowIndex && this.SelectedContestWagerBlocks[x].ColumnIndex == columnIndex)
        {
            existingIndex = x;
        }
    } 
    
    return existingIndex;   
}


/// <summary>
/// Checks if a block has already been selected. Returns it's index from the SelectedContestWagerBlocks array if found. If not then returns -1;
/// </summary>
/// <param name="rowIndex">The selected block's row index in the grid.</param>
/// <param name="columnIndex">The selected block's column index in the grid.</param>
/// <param name="forceAdd">Will ignore if it is already selected</param>
/// <param name="forceRemove">Will ignore if it isn't already selected</param>
ContestInterface.prototype.SelectBlock = function(rowIndex, columnIndex, forceAdd, forceRemove)
{
    this.SetSelectedBlock(rowIndex, columnIndex, forceAdd, forceRemove);
    for(var i=0; i < this.ContestWagerBlocks.length; i++)
    {
        if(this.ContestWagerBlocks[i].ColumnIndex == columnIndex && this.ContestWagerBlocks[i].RowIndex == rowIndex)
        {
            this.UpdateAllDownAndAcrossLink(this.ContestWagerBlocks[i]);
            break;
        }
    }
}

ContestInterface.prototype.SetSelectedBlock = function(rowIndex, columnIndex, forceAdd, forceRemove)
{
    if(forceAdd == null)
        forceAdd = false;
    if(forceRemove == null)
        forceRemove = false;

    for(var i = 0; i < this.ContestWagerBlocks.length; i++)
    {    
        var existingIndex = this.IsBlockAlreadySelected(rowIndex, columnIndex);

        if(existingIndex > -1)
        {
            if(forceAdd != true)
            {
                this.ClearContestItemBackground(this.SelectedContestWagerBlocks[existingIndex].ContainerElementId);
                this.SelectedContestWagerBlocks.splice(existingIndex,1);
                
                break;
            }
        }
        else if(this.ContestWagerBlocks[i].RowIndex == rowIndex && this.ContestWagerBlocks[i].ColumnIndex == columnIndex && forceRemove != true)
        {
            if(this.SelectContestWagerBlock(this.ContestWagerBlocks[i]) > -1)
            {
                this.SetContestItemBackground(this.ContestWagerBlocks[i].ContainerElementId)
            }
            
            break;
        }
    }
}


ContestInterface.prototype.ClearContestItemBackground = function(elementId)
{
    var elem = document.getElementById(elementId);
    if(elem != null)
    {
        elem.className = elem.className.replace(' ContestItemSelected','');
    }
}

ContestInterface.prototype.SetContestItemBackground = function(elementId)
{
    var elem = document.getElementById(elementId);
    if(elem != null)
    {
        var existingCss = elem.className;
        elem.className = ('class', (existingCss == null ? '' : existingCss) + ' ContestItemSelected');
        
    }
}

ContestInterface.prototype.SelectAllDown = function(columnIndex, callingElement)
{  
    if(callingElement == undefined)
    {
        callingElement = null;
    }
    var remove = false; //default
    var add = true; //default
    var block = null;
    
    if(callingElement != null && !this.IsAllButtonOn(callingElement))
    {
        this.ClearSelection();
    }
    else
    {
        add = false;
        remove - true;
    }
    
    for(var i = 0; i < this.ContestWagerBlocks.length; i++)
    {
        if(this.ContestWagerBlocks[i].ColumnIndex == columnIndex)
        {
            var block = this.ContestWagerBlocks[i];             
            this.SetSelectedBlock(block.RowIndex, block.ColumnIndex, add, remove)
        }
    }
    
    this.UpdateAllDownAndAcrossLink(block);
}



ContestInterface.prototype.SelectAllAcross = function(rowIndex, callingElement)
{  
    if(callingElement == undefined)
    {
        callingElement = null;
    }
    
    var remove = false; //default
    var add = true; //default
    var block = null;
    
    if(callingElement != null && !this.IsAllButtonOn(callingElement))
    {
        this.ClearSelection();
    }
    else
    {
        add = false;
        remove - true;
    }
    
    
    for(var i = 0; i < this.ContestWagerBlocks.length; i++)
    {
        if(this.ContestWagerBlocks[i].RowIndex == rowIndex)
        {
            var block = this.ContestWagerBlocks[i];   
            this.SetSelectedBlock(block.RowIndex, block.ColumnIndex, add, remove)
        }
    }
    
    this.UpdateAllDownAndAcrossLink(block);
}



ContestInterface.prototype.AllBlocksSelectedInRow = function(rowIndex)
{
    var selectedTotal = 0;
    for(var i = 0; i < this.SelectedContestWagerBlocks.length && this.SelectedContestWagerBlocks.length >= this.GridSize; i++)
    {
        if(this.SelectedContestWagerBlocks[i].RowIndex == rowIndex)
        {
            selectedTotal++;
        }
    }
    
    return (selectedTotal == this.GridSize);
}

ContestInterface.prototype.AllBlocksSelectedInColumn = function(columnIndex)
{
    var selectedTotal = 0;
    for(var i = 0; i < this.SelectedContestWagerBlocks.length && this.SelectedContestWagerBlocks.length >= this.GridSize; i++)
    {
        if(this.SelectedContestWagerBlocks[i].ColumnIndex == columnIndex)
        {
            selectedTotal++;
        }
    }
    
    return (selectedTotal == this.GridSize);
}

ContestInterface.prototype.UpdateAllDownAndAcrossLink = function(block)
{
    
    var selectAllAcrossElement = document.getElementById(block.RowSelectAllControlId);
    var selectAllDownElement = document.getElementById(block.ColumnSelectAllControlId);
    
    var AllRowBlocksSelected = this.AllBlocksSelectedInRow(block.RowIndex);
    var AllColumnBlocksSelected = this.AllBlocksSelectedInColumn(block.ColumnIndex);
    
    if(AllColumnBlocksSelected)
    {
        this.SetSelectAllButton(selectAllDownElement, 'AllDown', true);
        //selectAllDownElement.innerHTML = 'Undo All Down';
        
    }
    else
    {
        this.SetSelectAllButton(selectAllDownElement, 'AllDown', false, true);
        //selectAllDownElement.innerHTML = 'All Down';
    }
    
    if(AllRowBlocksSelected)
    {
        this.SetSelectAllButton(selectAllAcrossElement, 'AllAcross', true);
        //selectAllAcrossElement.innerHTML = 'Undo All Across';
    }
    else
    {
        this.SetSelectAllButton(selectAllAcrossElement, 'AllAcross', false, true);
    }
}

ContestInterface.prototype.ClearSelection = function() {
    var rowIndex = -1;
    var columnIndex = -1;

    for(var i=0; i < this.ContestWagerBlocks.length; i++) {
        this.SetSelectedBlock(this.ContestWagerBlocks[i].RowIndex, this.ContestWagerBlocks[i].ColumnIndex, false, true);
        this.UpdateAllDownAndAcrossLink(this.ContestWagerBlocks[i]);
    }
    
}

ContestInterface.prototype.RendomizeSelecton = function(objectContextName) {
    for (var x = 0; x < 8; x++) {
        setTimeout(objectContextName + '.SelectRandomPicks();', Math.floor(x) + '00');
    }
}

ContestInterface.prototype.SelectRandomPicks = function() {

    this.ClearSelection();
    var randomSelections = new Array();
    for (var i = 0; i < this.MinimumSelectionsRequired; i++) {
        var rnd = Math.ceil((this.ContestWagerBlocks.length - 1) * Math.random());

        for (var xAttemps = 0; xAttemps < 999; xAttemps++) {
            rnd = (xAttemps > 0 ? rnd - xAttemps : rnd)

            if (this.CheckIfRandomAlreadySelected(rnd, randomSelections) <= -1 && rnd > 0) {
                randomSelections.push(rnd);
                break;
            }
        }
    }

    if (randomSelections.length < this.GridSize) {//Some times the random function won't be able to create enough unique numbers. If this happens then start picking from the first in the list and work it's way up.
        var tmpCount = 0;
        
        for (var i = 0; i < (this.MinimumSelectionsRequired - randomSelections.length);  i++) {    
            while (tmpCount < this.ContestWagerBlocks.length) {
                
                if (this.CheckIfRandomAlreadySelected(tmpCount, randomSelections) <= -1) {
                    randomSelections.push(tmpCount);
                    break;
                }
                tmpCount++;
            }
        }

    }

    for (var i = 0; i < randomSelections.length; i++) {
        this.SelectBlock(this.ContestWagerBlocks[randomSelections[i]].RowIndex, this.ContestWagerBlocks[randomSelections[i]].ColumnIndex, true, false);
    }
}

ContestInterface.prototype.CheckIfRandomAlreadySelected = function(rndNumber, existingSelections) {
    var results = -1;
    for (var i = 0; i < existingSelections.length; i++) {
        if (existingSelections[i] == rndNumber) {
            results = i;
            break;
        }
    }
    return results;
}


/// <summary>
/// Handles changing the state of the "All Across" and "All Down" buttons.
/// </summary>
/// <param name="targetElement">The element to be handled.</param>
/// <param name="actionType">The button type. Choices: "AllDown" or "AllAcross"</param>
ContestInterface.prototype.SetSelectAllButton = function(targetElement, actionType, forceOn, forceOff)
{
    
    if((this.IsAllButtonOn(targetElement) && forceOn != true) || forceOff == true)
    {
        if(actionType == 'AllAcross')
        {
            targetElement.innerHTML = '<img src="images/allAcrossButn.jpg" border="0" alt="All Across" />';
        }
        else
        {
            targetElement.innerHTML = '<img src="images/allDownButn.jpg" border="0" alt="All Down" />';
        }
        
        targetElement.setAttribute('Selected', 'false');
    }
    else
    {
        if(actionType == 'AllAcross')
        {
            targetElement.innerHTML = '<img src="images/undoAllAcrossButn.jpg" border="0" alt="Undo All Across" />';
        }
        else
        {
            targetElement.innerHTML = '<img src="images/undoAllDownButn.jpg" border="0" alt="Undo All Down" />';
        }
        targetElement.setAttribute('Selected', 'true');
    }
}

ContestInterface.prototype.IsAllButtonOn = function(targetElement)
{
    return (targetElement.getAttribute('Selected') == 'true' ? true : false);
}

/// <summary>
/// Checks the min and max selections to make sure they are correct. Currently returns true or false but it could be modified to throw alerts or exceptions for additional details.
/// </summary>
ContestInterface.prototype.IsValid = function() {

    var results = (this.SelectedContestWagerBlocks.length >= this.MinimumSelectionsRequired && this.SelectedContestWagerBlocks.length <= this.MaximumSectionsRequired);
    if (!results) {
        alert('You must pick ' + this.MinimumSelectionsRequired + ' wagers to complete your selection.');
    }
    return results;
}

ContestInterface.prototype.ParseSelections = function(storeElementId, showConfirm) {

    var res = this.IsValid();
    if (res) {
        var storeElement = document.getElementById(storeElementId);
        var selectionsDelimited = '';
        for (var i = 0; i < this.SelectedContestWagerBlocks.length; i++) {
            selectionsDelimited += this.SelectedContestWagerBlocks[i].Index;
            if (i < (this.SelectedContestWagerBlocks.length - 1)) {
                selectionsDelimited += ',';
            }
        }
        storeElement.value = selectionsDelimited;
    }

    if (res && showConfirm)
        res = confirm('You are about to confirm these as your selections for todays contest. Proceed?');
    
    return res;
}

/// <summary>
/// Represents 1 of the many blocks in the UI grid.
/// </summary>
/// <param name="index">The coresponding index to the datasource.</param>
/// <param name="rowIndex">The row of the grid that this block is dsiplayed in.</param>
/// <param name="columnIndex">The column of the grid that this block is dsiplayed in.</param>
/// <param name="containerElementId">The elements's client Id that houses the child elements for this block in the grid.</param>
/// <param name="rowSelectAllControlId">The client id for the button that will include this block when selecting all blocks in this current row.</param>
/// <param name="columnSelectAllControlId">The client id for the button that will include this block when selecting all blocks in this current column.</param>
function ContestWagerBlock(index,rowIndex,columnIndex,containerElementId, rowSelectAllControlId, columnSelectAllControlId) 
{
    this.Index = index;
    this.RowIndex = rowIndex;
    this.RowSelectAllControlId = rowSelectAllControlId;
    this.ColumnSelectAllControlId = columnSelectAllControlId;
    this.ColumnIndex = columnIndex;
    this.ContainerElementId = containerElementId;
}
