﻿TabGridContainer = function(dropElement, scale)
{
    this.HiddenDataItemSeparator = ':';
    this.HiddenDataTripletSeparator = '|';
    this.HiddenDataChordListSeparator = '|';
    this.HiddenDataChordListItemSeparator = '-';
    
    this.Browser = this.GetBrowser();
    
    this.OwnerPrefix = dropElement.getAttribute('OwnerPrefix');
    this.DropElement = dropElement;

    // dropped item properties
    this.CenterTop = ParseNumber(dropElement.style.top) + (ParseNumber(GetElementHeight(dropElement)) / 2);
    this.CenterLeft = ParseNumber(dropElement.style.left) + (ParseNumber(GetElementWidth(dropElement)) / 2);
    this.Width = ParseNumber(GetElementWidth(dropElement));
    this.Height = ParseNumber(GetElementHeight(dropElement));
    
    this.Number = ParseNumber(dropElement.getAttribute('ImgNumber'));

    // sort out scaling
    if (isNaN(scale)) 
    {
        scale = GetGridScale(this.OwnerPrefix);        
    }
    this.StaffLength = 660;    
    //20;
    this.FretHeight = this.StaffLength / (parseInt(scale) + 1); 
    
    this.StringSeparation = 10;
    

    // tool bar item constants
    this.ToolBarItemVerticalPosition = -2;

    this.IsWholeChord = dropElement.id.indexOf('divGeneratedDropChord') != -1
    this.IsDivider = this.Number == 30;
    
    
    this.HighestAllowedVerticalPosition = this.Number > 24 ? -2 : -1;
    
    this.DividerToolBoxTop = "0px";
    this.DividerToolBoxLeft = "670px";
    
    
    this.HiddenField = document.getElementById(this.OwnerPrefix + 'hiddenData');
}


TabGridContainer.prototype =
{
    GetBrowser : function()
    {
        if (navigator.userAgent.indexOf('MSIE') != -1)
            return 'IE';
        if (navigator.userAgent.indexOf('Chrome') != -1)
            return 'CHROME';
        if (navigator.userAgent.indexOf('Firefox') != -1)
            return 'FIREFOX';
        if (navigator.userAgent.indexOf('Netscape') != -1)
            return 'FIREFOX';
    },
    
    
    
    IsOver : function()
    {        
        Log('IsOver->');
        
        var availableTop = this.HighestAllowedVerticalPosition;
        var string6Top = this.StringSeparation * 5;
        var lastFretLeft = this.StaffLength;
        
        var withinVerticalBounds = (this.CenterTop > availableTop) && (this.CenterTop < (string6Top + this.StringSeparation));
        var withinHorizontalBounds = (this.CenterLeft > (0 - this.FretHeight / 2)) && (this.CenterLeft < lastFretLeft + (this.FretHeight / 2));
        
        Log('IsOver->WithinVerticalBounds->' + withinVerticalBounds);
        Log('IsOver->WithinHorizontalBounds->' + withinHorizontalBounds);
        
        if (withinVerticalBounds && withinHorizontalBounds)
        {
            Log('IsOver->TRUE');
            return true;
        }
        
        Log('IsOver->FALSE');
        return false;
    },
    
    
    
    IsNotOver : function()
    {
        // we must see if the item being thrown away is in the hidden data - if it is it must be removed
        // remove the item from the hidden string if it is present
        this.RemoveData(this.DropElement.getAttribute('ImgNumber'), this.DropElement.getAttribute('HorizontalPosition'), this.DropElement.getAttribute('VerticalPosition'));
        return false;
    },
    
    
    
    
    
    MoveItem : function ()
    {
        Log('MoveItem->');
        
        var verticalPosition = this.FindVerticalPosition()   
        var horizontalPosition = this.FindHorizontalPosition();
        
        Log('MoveItem->VerticalPosition->' + verticalPosition);  
        Log('MoveItem->HorizontalPosition->' + horizontalPosition);

        if (this.IsWholeChord)
            this.MoveWholeChord(horizontalPosition);
        else
            this.MoveNumber(this.Number, horizontalPosition, verticalPosition);
    },
    
    
    
    
    MoveNumber : function(fretNumber, horizontalPosition, verticalPosition)
    {
        Log('MoveNumber->');
        

        if (this.DropElement.id != '')
        {
            // IMPORTANT
            // i am using dropElement.HorizontalPosition etc as a way of getting data from the OLD positioned item
            // rather than the new HorizontalCoOrdinate value passed in for the case of RE-POSITIONING elements already dropped
            this.RemoveData(this.Number, this.DropElement.getAttribute('HorizontalPosition'), this.DropElement.getAttribute('VerticalPosition'));
        }
       
        // we may have dropped an item over another item already on the grid
        // we may have an item visible which now has no data for it in the hidden string so needs to be made invisible
        this.HideItemByPosition(horizontalPosition, verticalPosition);        
        
        // we need to do the above first or we will hide the image we are dropping:
        this.RemoveDataByPosition(horizontalPosition, verticalPosition);

        var newItem = this.GetNewItem(fretNumber, horizontalPosition, verticalPosition);
        
        this.SetPosition(newItem);
        this.SetData(fretNumber, horizontalPosition, verticalPosition);
    },
    
    
    
    MoveWholeChord : function(horizontalPosition)
    {
        Log('MoveWholeChord->');
        
        // we need to get the horizontal co-ordinate 
        // then get the chord data (which is the value of the list

        var list = document.getElementById(this.DropElement.getAttribute('ListOwnerId'));
        var chordData = list.options[list.selectedIndex].value;

        Log('MoveWholeChord->ChordData: ' + chordData);

        var arrayChordElements = chordData.split(this.HiddenDataChordListSeparator);

        // we need to apply the horizontal value passed in to each of the chord elements as they dont have this yet
        var chordElementCounter;
        for(chordElementCounter=0; chordElementCounter<arrayChordElements.length; chordElementCounter++)
        {
            // data elements are in the form stringNumber-fretNumber
            // or, VerticalCoOrdinate-ImageNumber
            var arrayVertAndFret = arrayChordElements[chordElementCounter].split(this.HiddenDataChordListItemSeparator);
            var verticalPosition = arrayVertAndFret[0];
            var fretNumber = arrayVertAndFret[1];
            
            // IMPORTANT: dropped items are zero based the whole chord items are based at 1
            verticalPosition = verticalPosition - 1;

            this.MoveNumber(fretNumber, horizontalPosition, verticalPosition);
        }
    },
    
    
    
    
    
    FindHorizontalPosition : function()
    {
        Log('FindHorizontalPosition->')
        
        var counter = 0;
        while (true)
        {
            if (counter > 500)
            {
                Log('FindHorizontalPosition->Unable to find position');
                alert('Unable to find horizontal position');
                return;
            }

            var rangeLeft = (counter * this.FretHeight) - (this.FretHeight / 2);
            var rangeRight = (counter * this.FretHeight) + (this.FretHeight / 2);
            
            Log('FindHorizontalPosition->RangeLeft->' + rangeLeft);
            Log('FindHorizontalPosition->RangeRight->' + rangeRight);

            if ((this.CenterLeft >= rangeLeft) && (this.CenterLeft <= rangeRight))
            {
                break;
            }
            counter++;
        }
        
        return counter;
    },
    
    
    
    FindVerticalPosition : function()
    {
        Log('FindVerticalPosition->');
        
        var verticalPosition = this.HighestAllowedVerticalPosition;
        
        while (true)
        {
            if (verticalPosition > 500)
            {
                // safety break to prevent infinite looping:
                Log('FindVerticalPosition->Unable to find position');
                alert('Unable to find vertical position');
                return;
            }

            var rangeTop = (verticalPosition * this.StringSeparation) - (this.StringSeparation / 2);
            var rangeBottom = (verticalPosition * this.StringSeparation) + (this.StringSeparation / 2);
            
            Log('FindVerticalPosition->RangeTop->' + rangeTop);
            Log('FindVerticalPosition->RangeBottom->' + rangeBottom);

            if ((this.CenterTop >= rangeTop) && (this.CenterTop <= rangeBottom))
            {
                break;
            }
            verticalPosition++;
        }
                
        return verticalPosition;
    },
       
    
    
    
    
    
    
    SetPosition : function(divElement)
    {
        Log('SetPosition->');
        
        var verticalPosition = divElement.getAttribute('VerticalPosition');  
        var horizontalPosition = divElement.getAttribute('HorizontalPosition');
        
        Log('SetPosition->VerticalPosition->' + verticalPosition);
        Log('SetPosition->HorizontalPosition->' + horizontalPosition);
        
        var height = GetElementHeight(divElement);
        var width = GetElementWidth(divElement);
        
        var top = (verticalPosition * this.StringSeparation) - (height / 2);
        var left = (horizontalPosition * this.FretHeight) - (width / 2);
        
        Log('SetPosition->ItemHeight->' + height);
        Log('SetPosition->ItemWidth->' + width);
        Log('SetPosition->Top->' + top);
        Log('SetPosition->Left->' + left);
        
        if (this.IsDivider)
        {
            // special positioning here
            // we want to position this element in the vertical center of the grid (its a divider)
            top = 0;
        }

        divElement.style.top = top + 'px';
        divElement.style.left = left + 'px';
        
        if (left > 670 && !this.IsDivider)
            // we may have scaled the image off the end of the grid!
            divElement.style.visibility = "hidden";
        else
            divElement.style.visibility = "visible";
    },
    
    
    
    SetData : function(imageNumber, horizontalPosition, verticalPosition)
    {
        Log('SetData->');

        var currentData = this.HiddenField.value;

        if (currentData.length > 0) // we need to put a separator bar in place
            currentData += this.HiddenDataTripletSeparator;

        currentData += imageNumber + this.HiddenDataItemSeparator + verticalPosition + this.HiddenDataItemSeparator + horizontalPosition;
        this.HiddenField.value = currentData;
    },
    
    
    
    RemoveData : function (imageNumber, horizontalPosition, verticalPosition)
    {
        Log('RemoveData->');
        
        var searchString = imageNumber + this.HiddenDataItemSeparator + verticalPosition + this.HiddenDataItemSeparator + horizontalPosition;        
        var hiddenDataValue = this.HiddenField.value;

        if (hiddenDataValue.indexOf(searchString) != -1)
        {
            hiddenDataValue = StringRemove(hiddenDataValue, searchString);
            hiddenDataValue = CleanUpData(hiddenDataValue);
            this.HiddenField.value = hiddenDataValue;
        }
    },
    
    
    RemoveDataByPosition: function (horizontalPosition, verticalPosition)
    {
        Log('RemoveDataByPosition->');
        
        var searchString = this.HiddenDataItemSeparator + verticalPosition + this.HiddenDataItemSeparator + horizontalPosition;
        var hiddenDataValue = this.HiddenField.value;

        if (hiddenDataValue.indexOf(searchString) != -1)
        {
            // build the full search string with the ImgNumber too then re-use RemoveItemFromHiddenString
            var imageNumber;
            
            // this could be 1-2-3|12 or just 12 etc
            var strStart = hiddenDataValue.substr(0, hiddenDataValue.indexOf(searchString)); 

            if (strStart.indexOf(this.HiddenDataTripletSeparator) != -1) 
                // we can just get the remainder of the string after the last '|'
                imageNumber = strStart.substr(strStart.lastIndexOf(this.HiddenDataTripletSeparator) + 1);
            else
                // if the above condition is not met then strStart already contains just the number
                imageNumber = strStart; 

            // re-use this function to remove the entire item from the hidden string
            this.RemoveData(imageNumber, horizontalPosition, verticalPosition);
        }
    },
    
    
    


    HideItemByPosition : function (horizontalPosition, verticalPosition)
    {
        Log('HideItemByPosition->');
        
        for(i=0;i<document.images.length;i++)
        {
            if (document.images[i].getAttribute('OwnerPrefix'))
            {
                if (document.images[i].getAttribute('OwnerPrefix') == this.OwnerPrefix && document.images[i].getAttribute('HorizontalPosition') == horizontalPosition && document.images[i].getAttribute('VerticalPosition') == verticalPosition)
                {
                    document.images[i].style.visibility = 'hidden';
                }
            }
        }
    },
    
    
    

    GetNewItem : function (imageNumber, horizontalPosition, verticalPosition)
    {      
        Log('GetNewItem->');
        
        // NewItemCounterTabGrid is a global variable
        var newImageId = 'newImg' + NewItemCounterTabGrid; 
        
        // newElementName is set onmouseup in the dropped element (ie, this div or in divTab)
        var newSpanElement = document.getElementById(newElementName);
        
        ////////////////////////////////////////////////////////////////////////////////////////
        // THESE PROPERTIES MUST MATCH THOSE GENERATED IN THE SERVER CONTROL FOR THE IMG ITEMS //
        
        if (this.Browser == 'FIREFOX')
        {        
//            var newImage = document.createElement('img');
//            newImage.setAttribute('id', newImageId);
//            newImage.setAttribute('name', newImageId);
//            newImage.setAttribute('alt', imageNumber);
//            newImage.setAttribute('src', strWebSiteRootPath + "/" + imageNumber + ".gif");
//            newImage.setAttribute('OwnerPrefix', this.OwnerPrefix);
//            newImage.setAttribute('ImgNumber', imageNumber);
//            newImage.setAttribute('HorizontalPosition', horizontalPosition);
//            newImage.setAttribute('VerticalPosition', verticalPosition);
//            newImage.setAttribute('ItemType', 'Tab');
//            newImage.setAttribute('drag', 'true');
//            newImage.setAttribute('style', 'position:absolute;top:0px;left:0px;visibility:visible;z-index:100;cursor:default');
//            
//            newSpanElement.insertBefore(newImage, null);

            var html = newSpanElement.parentNode.innerHTML;
            
            var newItemHTML = "<img id='" + newImageId + "'"
                                        + "  name='" + newImageId + "'"
                                        + "  alt='" + imageNumber + "'"
                                        + "  src='" + strImageThemeRootPath + "/" + imageNumber + ".gif'"
                                        + "  OwnerPrefix='" + this.OwnerPrefix + "'"
                                        + "  ImgNumber='" + imageNumber + "'"
                                        + "  HorizontalPosition='" + horizontalPosition + "'"
                                        + "  VerticalPosition='" + verticalPosition + "'"
                                        + "  ItemType='Tab'"
                                        + "  drag='true'"
                                        + "  style='position:absolute;top:0px;left:0px;visibility:hidden;z-index:100;cursor:default'/>";
            
            newSpanElement.parentNode.innerHTML = html + newItemHTML;
        }
        else
        {
            var newItemHTML = "<img id='" + newImageId + "'"
                                        + "  name='" + newImageId + "'"
                                        + "  alt='" + imageNumber + "'"
                                        + "  src='" + strImageThemeRootPath + "/" + imageNumber + ".gif'"
                                        + "  OwnerPrefix='" + this.OwnerPrefix + "'"
                                        + "  ImgNumber='" + imageNumber + "'"
                                        + "  HorizontalPosition='" + horizontalPosition + "'"
                                        + "  VerticalPosition='" + verticalPosition + "'"
                                        + "  ItemType='Tab'"
                                        + "  drag='true'"
                                        + "  style='position:absolute;top:0px;left:0px;visibility:hidden;z-index:100;cursor:default'/>";
            newSpanElement.outerHTML = "<span id='" + newElementName + "'></span>" + newItemHTML;
        }
        
        NewItemCounterTabGrid++;        

        return document.getElementById(newImageId);
    },
    
    
    
    ResetItem : function()
    {
        Log('ResetItem->');         
            
        if (this.Browser == 'FIREFOX')
        {            
            // firefox has forgotton what the drop element was...
            this.DropElement = document.getElementById(this.DropElement.id);
        }

        // the element might be a tool box image dropped or it might be one of the images re-positioned
        if (this.DropElement.id.indexOf('newImg') != -1)
        {
            Log('ResetItem->Reset new image');
            
            // nothing to do as we dont want to reset anything as this was a re-positioned item
            this.DropElement.style.visibility = 'hidden';
            return; 
        }
        else if (this.DropElement.id.indexOf('_tbi') != -1) 
        {        
            Log('ResetItem->Reset tool box item');
            
            this.DropElement.setAttribute('VerticalPosition', this.ToolBarItemVerticalPosition);
            //this.SetPosition(this.DropElement);
            new TabGridContainer(this.DropElement, DEFAULT_SCALE).SetPosition(this.DropElement);
        }
        else if (this.DropElement.id.indexOf('divGeneratedDropChord') != -1) 
        {
            // its a dropped whole chord
            Log('ResetItem->Reset whole chord');

            // we can position the dropElement back to where it was as it can be used again whole
            var dropChordPosition = new DropChordPosition();
            this.DropElement.style.top = dropChordPosition.Top + 'px';
            this.DropElement.style.left = dropChordPosition.Left + 'px';
        }
        else if (this.DropElement.id.indexOf('_img') != -1) 
        {
            // its a positioned image from hidden data being re-moved (ie, was there when the page loaded)
            this.DropElement.style.visibility = 'hidden';
        }
        
        Log('LogItem->Function End');
    }


}