﻿function moneyToNumber(money)
{
    if(money == 'n/a') {
        money = '';
    }
    return money.replace('$', '').replace(',', '');
}


//// GridDialogGoogleExport Class -------------------------------------------

//Properties
GridDialogGoogleExport.prototype.keywordArray;
GridDialogGoogleExport.prototype.keywordListDelimiter = '\t';
GridDialogGoogleExport.prototype.priceCol = '1';
GridDialogGoogleExport.prototype.isBidEnabled = true;
GridDialogGoogleExport.prototype.isDestUrlAdded = false; //needed because DestUrl can be enabled but not added if it is blank
GridDialogGoogleExport.prototype.keywordWrapStartingChar = '';
GridDialogGoogleExport.prototype.keywordWrapEndingChar = '';
GridDialogGoogleExport.prototype.wasBidAmountEnabled = true;
GridDialogGoogleExport.prototype.wasDestUrlEndabled = true;
GridDialogGoogleExport.prototype.saveToFileForm;
GridDialogGoogleExport.prototype.saveToFilePostData;
GridDialogGoogleExport.prototype.clip;

GridDialogGoogleExport.prototype.divDialog;
GridDialogGoogleExport.prototype.ddlBidAmount;
GridDialogGoogleExport.prototype.txtBidMultiplier;
GridDialogGoogleExport.prototype.chkBidAmountEnabled;
GridDialogGoogleExport.prototype.ddlMatchType;
GridDialogGoogleExport.prototype.txtDestUrl;
GridDialogGoogleExport.prototype.chkDestUrlEnabled;
GridDialogGoogleExport.prototype.txtareaKeywordList;
GridDialogGoogleExport.prototype.btnCopyClipboard;
GridDialogGoogleExport.prototype.btnSaveToFile;
GridDialogGoogleExport.prototype.btnClose;
GridDialogGoogleExport.prototype.imgClose;

GridDialogGoogleExport.prototype.originalMarginTop;

//event handlers
GridDialogGoogleExport.prototype.bidAmountChanged = function (e)
{
    var target = getTarget(e);
    var newBidAmountName = target.value;
    
    //right now there is just one bid amount,
    //but in the future here you would want to update the priceCol
    //based on what the newBidAmountName is
    
    //then just uncomment this as well to recalculate all the bids
    //this.modifyAllKeywordListRows(this.updateBid);
}

GridDialogGoogleExport.prototype.bidMultiplierChanged = function (e)
{
    this.modifyAllKeywordListRows(this.updateBid);
}

GridDialogGoogleExport.prototype.toggleBidAmountEnabled = function (e)
{
    var target = getTarget(e);
    if(target.checked) {
        this.isBidEnabled = true;
        this.modifyAllKeywordListRows(this.addBid);
    }
    else {
        this.isBidEnabled = false;
        this.modifyAllKeywordListRows(this.removeBid);
    }
}

GridDialogGoogleExport.prototype.matchTypeChanged = function (e)
{
    //remove old wrapped characters
    this.modifyAllKeywordListRows(this.unWrapKeyword);

    //find the new match type and its wrapping chars    
    this.setStartingAndEndingWrapChars();

    //wrap appropriate characters based on new match type
    this.modifyAllKeywordListRows(this.wrapKeyword);
}

GridDialogGoogleExport.prototype.destUrlChanged = function (e)
{
    if(this.chkDestUrlEnabled.checked == false)
    {
        return; //destUrl isn't enabled, so we don't have to do anything
    }
    
    var destUrl = this.txtDestUrl.value;
    if(this.isDestUrlAdded)
    {
        if(destUrl == '')
        {
            //the destUrl was added, but it has been changed
            //to nothing, so remove it
            this.modifyAllKeywordListRows(this.removeDestUrl);
            this.isDestUrlAdded = false;
        }
        else
        {
            //the destUrl has been changed from something
            //to something else, update
            this.modifyAllKeywordListRows(this.updateDestUrl);
        }
    }
    else if(destUrl != '') 
    {
        //There was no destUrl added, but it was
        //just changed to something, so add it
        this.modifyAllKeywordListRows(this.addDestUrl);
        this.isDestUrlAdded = true;
    }
}

GridDialogGoogleExport.prototype.toggleDestUrlEnabled = function (e)
{
    var target = getTarget(e);
    if(target.checked)
    {
        var destUrl = this.txtDestUrl.value;
        if(destUrl != '') //make sure there is some ad url in the text box
        {
            this.modifyAllKeywordListRows(this.addDestUrl);
            this.isDestUrlAdded = true;
        }
    }
    else
    {
        if(this.isDestUrlAdded == true) //make sure not to take off a column if it is not the destUrl
        {
            this.modifyAllKeywordListRows(this.removeDestUrl);
            this.isDestUrlAdded = false;
        }
    }
}

GridDialogGoogleExport.prototype.txtareaChanged = function (e)
{
    this.updateClipboard();
}

//event captured by hovering flash movie instead (Zero Clipboard)
//GridDialogGoogleExport.prototype.copyClick = function (e)
//{
//}

GridDialogGoogleExport.prototype.saveClick = function (e)
{
    this.saveToFilePostData.value = this.txtareaKeywordList.value;
    //alert(this.saveToFilePostData);
    this.saveToFileForm.submit();
}

GridDialogGoogleExport.prototype.closeClick = function (e)
{
    this.divDialog.style.visibility='hidden';
    this.clip.hide();
}

//row handling methods
    //these use "dialog" instead of "this" because these functions
    //are passed as paramters before they are called
    //apparently that messes up "this"
    
GridDialogGoogleExport.prototype.wrapKeyword = function(row, rowIndex, dialog)
{
    var colArray = row.split(dialog.keywordListDelimiter);
    if(colArray.length > 0)
    {
        colArray[0] = dialog.keywordWrapStartingChar + trim(colArray[0]) + dialog.keywordWrapEndingChar;
        return dialog.reassembleColumns(colArray);
    }
    else
    {
        return row; //row was empty ... doesn't make sense
    }
}

GridDialogGoogleExport.prototype.unWrapKeyword = function(row, rowIndex, dialog)
{
    var colArray = row.split(dialog.keywordListDelimiter);
    if(colArray.length > 0 && colArray.length > 0)
    {
        colArray[0] = trim(colArray[0]);
        if(dialog.keywordWrapStartingChar != '')
        {
            colArray[0] = colArray[0].substring(1);
        }
        if(dialog.keywordWrapEndingChar != '')
        {
            colArray[0] = colArray[0].substring(0, colArray[0].length-1);
        }
        return dialog.reassembleColumns(colArray);
    }
    else
    {
        return row; //row was empty ... doesn't make sense
    }
}

GridDialogGoogleExport.prototype.updateBid = function (row, rowIndex, dialog) 
{
    if(dialog.isBidEnabled === true) {
        var colArray = row.split(dialog.keywordListDelimiter);
        if(colArray.length > 1) {
            colArray[1] = dialog.getBidAmount(rowIndex, dialog.priceCol);
            return dialog.reassembleColumns(colArray);
        }
    }
    return row; //no second column to update
}

GridDialogGoogleExport.prototype.addBid = function (row, rowIndex, dialog) 
{
    if(dialog.isBidEnabled === true) {
        var bidAmount = dialog.getBidAmount(rowIndex, dialog.priceCol);

        var colArray = row.split(dialog.keywordListDelimiter);

        if(colArray.length === 1 && bidAmount !== undefined && bidAmount !== '') {
            return row + dialog.keywordListDelimiter + bidAmount;
        }
        else if(colArray.length === 3) {
            colArray[1] = bidAmount; //(index, numberToRemove, newValue)
            return dialog.reassembleColumns(colArray);
        }
    }
    return row; //no columns, but we need to add the bid after the first column
}

GridDialogGoogleExport.prototype.removeBid = function (row, rowIndex, dialog) 
{
    var colArray = row.split(dialog.keywordListDelimiter);
    if(colArray.length > 1)
    {
        var oldVal = colArray[1];
        if(parseFloat(oldVal,10)==(oldVal*1)) { //check that we don't accidentally remove the destUrl (make sure this is a number)
            colArray[1] = '';
            return dialog.reassembleColumns(colArray);
        } else {
            return row;
        }
    }
    else
    {
        return row; //no second column to remove
    }
}

GridDialogGoogleExport.prototype.updateDestUrl = function (row, rowIndex, dialog) 
{
    var colArray = row.split(dialog.keywordListDelimiter);
    if(colArray.length > 0)
    {
        var destUrl = dialog.txtDestUrl.value;
        colArray[2] = destUrl;
        return dialog.reassembleColumns(colArray);
    }
    else
    {
        return row; //wanted to update the last col, but none are there
    }
}

GridDialogGoogleExport.prototype.addDestUrl = function (row, rowIndex, dialog) 
{
    var destUrl = dialog.txtDestUrl.value;
    var colArray = row.split(dialog.keywordListDelimiter);
    
    if(colArray.length == 1) {
        row = row + dialog.keywordListDelimiter + dialog.keywordListDelimiter + destUrl;        
    }
    else if(colArray.length == 2) {
        row = row + dialog.keywordListDelimiter + destUrl;
    }

    return row;
}

GridDialogGoogleExport.prototype.removeDestUrl = function (row, rowIndex, dialog) 
{
    var colArray = row.split(dialog.keywordListDelimiter);
    var newRow = '';
    colArray.splice(2, 1);
    
    for(var i=0; i < colArray.length; i++) //just leave off the last col
    {
        if(i != 0)
        {
            newRow += dialog.keywordListDelimiter;
        }
        newRow += trim(colArray[i]);
    }
    
    return newRow;
}

//other methods
GridDialogGoogleExport.prototype.setStartingAndEndingWrapChars = function () 
{
    var matchType = this.ddlMatchType.value;
    if(matchType == 'broad')
    {
        this.keywordWrapStartingChar = '';
        this.keywordWrapEndingChar = '';
        this.reenableCheckBoxesIfNeeded();
    } 
    else if(matchType == 'exactPhrase') //""
    {
        this.keywordWrapStartingChar = '"';
        this.keywordWrapEndingChar = '"';
        this.reenableCheckBoxesIfNeeded();
    }
    else if(matchType == 'exactTerms') //[]
    {
        this.keywordWrapStartingChar = '[';
        this.keywordWrapEndingChar = ']';
        this.reenableCheckBoxesIfNeeded();
    }
    else if(matchType == 'noMatch') //-
    {
        this.keywordWrapStartingChar = '-';
        this.keywordWrapEndingChar = '';
        this.wasBidAmountEnabled = this.chkBidAmountEnabled.checked;
        this.wasDestUrlEnabled = this.chkDestUrlEnabled.checked;
        this.chkBidAmountEnabled.checked = false;
        this.chkDestUrlEnabled.checked = false;
        var eventBid = new Object();
        eventBid.target = this.chkBidAmountEnabled;
        this.toggleBidAmountEnabled(eventBid);
        var eventUrl = new Object();
        eventUrl.target = this.chkDestUrlEnabled;
        this.toggleDestUrlEnabled(eventUrl);        
    }
}

GridDialogGoogleExport.prototype.reenableCheckBoxesIfNeeded = function () 
{
    if(!this.chkBidAmountEnabled.checked && this.wasBidAmountEnabled)
    {
        this.chkBidAmountEnabled.checked = true;
        var event = new Object();
        event.target = this.chkBidAmountEnabled;
        this.toggleBidAmountEnabled(event);
    }
    if(!this.chkDestUrlEnabled.checked && this.wasDestUrlEnabled)
    {
        this.chkDestUrlEnabled.checked = true;
        var event = new Object();
        event.target = this.chkDestUrlEnabled;
        this.toggleDestUrlEnabled(event);        
    }
}

GridDialogGoogleExport.prototype.reassembleColumns = function (colArray) 
{
    var row = '';
    for(var i=0; i < colArray.length; i++)
    {
        if(i != 0)
        {
            row += this.keywordListDelimiter;
        }
        if(colArray[i] !== undefined) {
            
            if(typeof(colArray[i]) == 'string')
            {
                colArray[i] = trim(colArray[i]);
            }
            row += colArray[i];
        }
    }
    return row;
}


//f - must modify a row and return the result
//when f is called, it forgets that "this" should be the Dialog object.  
//so I have to pass "this" into f for reference ... LAME
GridDialogGoogleExport.prototype.modifyAllKeywordListRows = function (f) 
{                                                                        
    var text = this.txtareaKeywordList.value;           
    var keywordArray = text.split('\n');
    var newText = '';
    
    for (var i=0; i < keywordArray.length; i++) 
    {
        keywordArray[i] = trim(keywordArray[i].replace('\r', ''));
        
        if(keywordArray[i] != '')
        {
            //run the function passed in
            keywordArray[i] = f(keywordArray[i], i, this);
        }
        
        //add the modified row back into the new textarea value
        if(i != 0)
        {
            newText += '\n';
        }
        newText += keywordArray[i];
    }
    
    this.txtareaKeywordList.value = newText;
    this.updateClipboard();
}

GridDialogGoogleExport.prototype.populateRows = function (keywordArry) 
{
    this.keywordArray = keywordArry;
    this.txtareaKeywordList.value = '';
    var newText = '';
    var newRow = '';
    this.setStartingAndEndingWrapChars();
    for(var i=0; i < this.keywordArray.length; i++)                           
    {
        //add keyword
        newRow += this.keywordArray[i][0];

        this.keywordArray[i][this.priceCol] = moneyToNumber(this.keywordArray[i][this.priceCol]);
        //add price if enabled
        if(this.chkBidAmountEnabled)
        {
            newRow = this.addBid(newRow, i, this);
        }
        
        //add destUrl if enabled
        if(this.chkDestUrlEnabled.checked)
        {
            var destUrl = this.txtDestUrl.value;
            if(destUrl != '') //make sure there is some ad url in the text box
            {
                newRow = this.addDestUrl(newRow, i, this);
                this.isDestUrlAdded = true;
            }
        }
        newRow = this.wrapKeyword(newRow, i, this);
        
        newRow += '\n';
        newText += newRow;
        newRow = '';
    }
    //BUG, for some reason if < 5 rows are entered, only the first one appears
    //in the textarea.  If I do an alert before hand it works, the text should be
    //correct.
    this.txtareaKeywordList.value = newText;    
    this.updateClipboard()
}

GridDialogGoogleExport.prototype.show = function (keywordArry) 
{
    if(!keywordArry || keywordArry.length == 0)
    {
        customAlert('You must check at least one row to use the Google Adwords Export dialog');
    }
    else
    {
        this.populateRows(keywordArry);
        
        if(document.addEventListener) {
            scroll(0,0);
        } else if(document.attachEvent) {
            this.divDialog.style.marginTop = getNewMarginTop(this.originalMarginTop); //account for scrolling that may have happened
        }
        this.divDialog.style.visibility='visible';
        //this.clip.reposition(); //all show does is call repositon.  So this line isn't needed
        this.clip.show();
    }
}

GridDialogGoogleExport.prototype.getBidAmount = function (rowNum, priceCol) 
{
    var rawBidAmount = this.keywordArray[rowNum][priceCol];
    if(rawBidAmount == '') {
        return '';
    } else {    
        var multiplier = this.txtBidMultiplier.value;
        var newBidAmount = rawBidAmount * multiplier;
        return newBidAmount.toFixed(2);
    }
}

GridDialogGoogleExport.prototype.updateClipboard = function ()
{
    this.clip.setText(this.txtareaKeywordList.value);
}

// GridDialogGoogleExport object constructor
function GridDialogGoogleExport(divDialogId
                                , ddlBidAmountId, txtBidMultiplierId, chkBidAmountEnabledId
                                , ddlMatchTypeId, txtDestUrlId, chkDestUrlEnabledId, txtareaKeywordListId
                                , btnCopyClipboardId, btnSaveToFileId, btnCloseId, imgCloseId
                                )
{
    this.divDialog = elm(divDialogId);
    this.ddlBidAmount = elm(ddlBidAmountId);
    this.txtBidMultiplier = elm(txtBidMultiplierId);
    this.chkBidAmountEnabled = elm(chkBidAmountEnabledId);
    this.ddlMatchType = elm(ddlMatchTypeId);    
    this.txtDestUrl = elm(txtDestUrlId);
    this.chkDestUrlEnabled = elm(chkDestUrlEnabledId);
    this.txtareaKeywordList = elm(txtareaKeywordListId);
    this.btnCopyClipboard = elm(btnCopyClipboardId);
    this.btnSaveToFile = elm(btnSaveToFileId);
    this.btnClose = elm(btnCloseId);
    this.imgClose = elm(imgCloseId);

    //setup separate form needed for Post back to save file
    this.saveToFileForm = document.createElement("FORM");
    document.body.appendChild(this.saveToFileForm);
    this.saveToFileForm.method = 'POST';
    this.saveToFileForm.action = '/api/EchoApi.aspx';
    this.saveToFilePostData = createNewFormElement(this.saveToFileForm, 'PostData', this.txtareaKeywordList.value);
    createNewFormElement(this.saveToFileForm, 'MimeType', 'application/octet-stream');
    createNewFormElement(this.saveToFileForm, 'FileName', 'GoogleExport.txt');
    
    //setup clipboard copier
    this.clip = new ZeroClipboard.Client();
    //this.clip.setHandCursor( false ); //seems to make more sense with the hand, still doesn't act like other buttons
    this.updateClipboard();
    this.clip.glue(btnCopyClipboardId);
    this.clip.hide();

    this.originalMarginTop = pixelsToNum(getStyle(this.divDialog).marginTop);
    
    function assignEventHandlers(currObj) // Creates a new closure so that inside each event handler "this" means the GridDialogGoogleExport object, not the event target
    {
        if(document.addEventListener)
        {
            currObj.ddlBidAmount.addEventListener('change', function(event) {currObj.bidAmountChanged(event); }, false);
            currObj.txtBidMultiplier.addEventListener('keyup', function(event) {currObj.bidMultiplierChanged(event); }, false);
            currObj.txtBidMultiplier.addEventListener('mouseout', function(event) {currObj.bidMultiplierChanged(event); }, false);
            currObj.chkBidAmountEnabled.addEventListener('click', function(event) {currObj.toggleBidAmountEnabled(event); }, false);
            currObj.ddlMatchType.addEventListener('change', function(event) {currObj.matchTypeChanged(event); }, false);
            currObj.txtDestUrl.addEventListener('keyup', function(event) {currObj.destUrlChanged(event); }, false);
            currObj.txtDestUrl.addEventListener('mouseout', function(event) {currObj.destUrlChanged(event); }, false);
            currObj.chkDestUrlEnabled.addEventListener('change', function(event) {currObj.toggleDestUrlEnabled(event); }, false);
            currObj.txtareaKeywordList.addEventListener('click', function(event) {currObj.txtareaChanged(event); }, false);
            //currObj.btnCopyClipboard.addEventListener('click', function(event) {currObj.copyClick(event); }, false);
            currObj.btnSaveToFile.addEventListener('click', function(event) {currObj.saveClick(event); }, false);
            currObj.btnClose.addEventListener('click', function(event) {currObj.closeClick(event); }, false);
            currObj.imgClose.addEventListener('click', function(event) {currObj.closeClick(event); }, false);
        }
        else if(document.attachEvent) // IE
        {
            currObj.ddlBidAmount.attachEvent('onchange', function(event) {currObj.bidAmountChanged(event); }, false);
            currObj.txtBidMultiplier.attachEvent('onkeyup', function(event) {currObj.bidMultiplierChanged(event); }, false);
            currObj.txtBidMultiplier.attachEvent('onmouseout', function(event) {currObj.bidMultiplierChanged(event); }, false);
            currObj.chkBidAmountEnabled.attachEvent('onclick', function(event) {currObj.toggleBidAmountEnabled(event); }, false);
            currObj.ddlMatchType.attachEvent('onchange', function(event) {currObj.matchTypeChanged(event); }, false);
            currObj.txtDestUrl.attachEvent('onkeyup', function(event) {currObj.destUrlChanged(event); }, false);
            currObj.txtDestUrl.attachEvent('onmouseout', function(event) {currObj.destUrlChanged(event); }, false);
            currObj.chkDestUrlEnabled.attachEvent('onclick', function(event) {currObj.toggleDestUrlEnabled(event); }, false);
            currObj.txtareaKeywordList.attachEvent('onchange', function(event) {currObj.txtareaChanged(event); }, false);
            //currObj.btnCopyClipboard.attachEvent('onclick', function(event) {currObj.copyClick(event); }, false);
            currObj.btnSaveToFile.attachEvent('onclick', function(event) {currObj.saveClick(event); }, false);
            currObj.btnClose.attachEvent('onclick', function(event) {currObj.closeClick(event); }, false);
            currObj.imgClose.attachEvent('onclick', function(event) {currObj.closeClick(event); }, false);
        }
    };
    assignEventHandlers(this);
//    this.show(new Array());

}

//// End of GridDialogGoogleExport Class -------------------------------------------
    
