//
// Misc functionality at top.
//
function moveToTop() {
    document.body.scrollTop = document.documentElement.scrollTop = 0;
}

// This routine is going to render the NFTs just like what the wallet code does.
// Image on top, film if there is a video_id and token number. Clicking the image
// launches the explorer, clicking the film launches the video. The token number
// is not clickable.
async function renderNFTEx(_index, _tokenId) {
    //console.log('index: ' + _index + ' tokenId: ' + _tokenId);

    if (arrGlobals['mobile']) {
        arrGlobals['nftWidth'] = arrGlobals['nftWidthMobile'];
        //console.log('new nftWidth: ' + arrGlobals['nftWidth']);
    }

    let leftRightTop = 5; //px
    let width = arrGlobals['nftWidth'];
    let height = ((width * 5) / 4); //px
    let imgMaxWidth = width - (leftRightTop * 2); //px
    let imgMaxHeight = width;
    //console.log('width: '+ width + ", height: " + height);

    let theObj = document.getElementById('holdingNFTRowId' + _index);
    if (null != theObj) {

        // Image spacing for both images
        let imgSpace = 'left: ' + leftRightTop + 'px;max-width:' + imgMaxWidth + 'px;max-height:' + imgMaxHeight + 'px;';
        let filmImage = arrGlobals['siteURL'] + 'dsn/images/film.png';
        let reelImage = arrGlobals['siteURL'] + 'dsn/images/reel.png';

        //let filmImage = arrGlobals['siteURL'] + 'dsn/images/film.png';
        let bkclr = g_bkg['active'];

        let theId = _index + '_' + _tokenId; // like: 1_3
        let theText = 'Token Id: ' + _tokenId;

        let imageId = 'nftImageId' + _tokenId;
        let imageLocId = 'nftImageLocId' + _tokenId;
        let tokenId = 'nftTokenId' + _tokenId;
        let imageLinkId = 'nftImageLinkId' + _tokenId;
        let imageLinkFilmId = 'nftImageLinkFilmId' + _tokenId;
        let videoId = 'nftTokenVideoId' + _tokenId;
        let videoReelId = 'nftTokenVideoReelId' + _tokenId;

        // All images link to the explorer on the main image.
        //console.log(arrProjects[_index]["contractAddr"]);
        let mainLink = 'https://explorer.thetatoken.org/account/' + arrProjects[_index]["contractAddr"];

        //console.log('nft id ' + id);
        let theSection = '<div class="tokenrel" id="' + theId + '" style="background-color:' + bkclr + ';width:' + width + 'px;height:' + height + 'px">';

        // Main image
        theSection += '<div>';
        theSection += '<a id="' + imageLinkId + '" href="' + mainLink + '" target=_self>';
        theSection += '<img class="tokenrel" style="top: ' + leftRightTop + 'px;' + imgSpace + '" id="' + imageId + '" src="">';
        theSection += '</a>';
        theSection += '</div>';

        // secondary image
        theSection += '<div>';
        theSection += '<a id="' + imageLinkFilmId + '" href="" target=_self>';
        theSection += '<img class="tokenrel" style="bottom: 1.25em;' + imgSpace + '" id="' + videoId + '" src="' + filmImage + '" hidden>';
        theSection += '<img class="tokenrel" style="bottom: 1.65em;' + imgSpace + '" id="' + videoReelId + '" src="' + reelImage + '" hidden>';
        theSection += '</a>';
        theSection += '</div>';

        // build in the token id
        theSection += '<div class="nfttitle" style="bottom: 0;width:' + width + 'px" id="' + _tokenId + '">';
        theSection += 'Token ' + _tokenId;
        theSection += '</div>';

        theSection += '</div>';
        //console.log(theSection);

        let secHTML = theObj.innerHTML + theSection;
        theObj.innerHTML = secHTML;

        // This gets the URI that needs to be fetched to get the image URI
        //console.log('calling: tokenURI()');
        arrProjects[_index]['I']['IERC721Metadata']['Obj'].methods.tokenURI(_tokenId).call().then(uriObj => {
            //arrProjects[_index]["contractObj"].methods.tokenURI(_tokenId).call().then(uriObj => {
            //console.log('handling: tokenURI()');
            if (null != uriObj) {
                //console.log('the uriObj:');
                //console.log(uriObj);

                $url = arrGlobals['siteURL'] + 'dsn/?data=' + uriObj;
                //console.log($url);
                fetch($url).then(response => {
                    response.json().then(projectObj => {
                        if (null != projectObj) {
                            //console.log(projectObj['image']);

                            // imageId needs a src for the image.
                            let theImageObj = document.getElementById(imageId);
                            if (null != theImageObj) {
                                theImageObj.src = projectObj['image'];
                            }

                            // In the token metadata file, the video_reel is a fully qualified URL
                            if (typeof projectObj['video_reel'] !== 'undefined') {
                                //console.log(projectObj['video_reel']);

                                // Need to build the hyperlink so user can launch the video(s)
                                let theLinkObj = document.getElementById(imageLinkFilmId);
                                if (null != theLinkObj) {
                                    // TODO: Build the reel URL

                                    //let theReelURL = projectObj['hashTable']['root'] + '/' + projectObj['video_reel'] + '_reel.json';
                                    let thehyperlink = arrGlobals['siteURL'] + 'dsn/reel/?reel=' + projectObj['video_reel'];
                                    //console.log(thehyperlink);
                                    theLinkObj.href = thehyperlink;
                                }

                                let theVideoObj = document.getElementById(videoReelId);
                                if (null != theVideoObj) {
                                    theVideoObj.style.display = 'block';
                                }
                            } else if (typeof projectObj['video_id'] !== 'undefined') {
                                //console.log('video_id: ' + projectObj['video_id']);

                                // Need to build the hyperlink so user can launch the video
                                let theLinkObj = document.getElementById(imageLinkFilmId);
                                if (null != theLinkObj) {
                                    let videoLink = arrGlobals['root'] + 'video/?id=' + projectObj['video_id'];
                                    //console.log(videoLink);
                                    theLinkObj.href = videoLink;
                                }

                                let theVideoObj = document.getElementById(videoId);
                                if (null != theVideoObj) {
                                    theVideoObj.style.display = 'block';
                                }
                            } else {
                                // show nothing.
                            }
                        }
                    });
                });
            }
        });
    }
}

// This is called after a successful mint
async function delayRefresh(_timeMS) {

    // Wait _timeMS and then reload
    await delay(_timeMS);
    window.location.reload();
}

async function delayHide(_timeMS, _secId) {
    // Wait _timeMS and then hide the section
    await delay(_timeMS);
    document.getElementById(_secId).style.display = "none";
}

// slowly read the nfts data.
async function readNFTs(_index, theObj) {

    for (let num = 0; num < theObj.length; num++) {
        //console.log('tokenId: ' + theObj[num].token);
        renderNFTEx(_index, theObj[num].token);
        await delay(200);
    }
    let theElObj = document.getElementById('holdingRowId' + _index);
    if (null != theElObj) {
        theElObj.style.display = "block";
    }
}

//
// This routine checks to see if the visitor holds any NFTs on this
// contract. 
//
async function holdsNFTs(_index) {
    //console.log('holdingRowId'+_index);
    //console.log('visitor: '+ arrGlobals['visitor']);
    //console.log('contract: ' + arrProjects[_index]["contractAddr"]);

    if (arrGlobals['showHolderSection'] != false) {
        //console.log('do it here');

        // fetch token holdsings from ThetaScan
        theURL = 'https://www.thetascan.io/api/721/?address=' + arrGlobals['visitor'] + '&contract=' + arrProjects[_index]["contractAddr"];
        //console.log('url: ' + theURL);

        fetch(theURL).then(response => {
            response.json().then(theObj => {
                //console.log("The Results: ");
                if (null != theObj) {
                    // we got back a non-zero array.
                    readNFTs(_index, theObj);
                }
            })
        });
    }
}


// This is used for Participant and Website Projects.
function calculateMintCost(_index) {
    //console.log('calculateMintCost');

    arrProjects[_index]['D']['prices']['mintPriceTfuelWei'] = arrProjects[_index]['D']['priceObj']['mintWei'];
    let theMintTfuel = Number(BigInt(arrProjects[_index]['D']['prices']['mintPriceTfuelWei']) / BigInt(10000000000000000)) / 100;
    //console.log("mintPriceTfuel: " + theMintTfuel);
    //arrProjects[_index]['D']['mintPriceTfuel'] = theMintTfuel;
    arrProjects[_index]['D']['prices']['mintPriceTfuel'] = theMintTfuel.toString();
    //arrProjects[_index]["mintWei"] = arrProjects[_index]['D']['prices']['mintPriceTfuelWei'];
}
function calculateBurnCost(_index) {
    //console.log('calculateBurnCost');

    arrProjects[_index]['D']['prices']['burnPriceTfuelWei'] = arrProjects[_index]['D']['priceObj']['burnWei'];
    let theBurnTfuel = Number(BigInt(arrProjects[_index]['D']['prices']['burnPriceTfuelWei']) / BigInt(10000000000000000)) / 100;
    //console.log("burnPriceTfuel: " + theBurnTfuel);
    //arrProjects[_index]['D']['burnPriceTfuel'] = theBurnTfuel;
    arrProjects[_index]['D']['prices']['burnPriceTfuel'] = theBurnTfuel.toString();
}

function writePartMint(_index) {

    // Need the price of tfuel in order to make this calculation
    let dollarAmountpertfuel = arrProjects[_index]['D']['pennyPriceObj']['priceOfTfuel'];
    //console.log('dollarAmountpertfuel: ' + dollarAmountpertfuel);
    let dollarAmountForMint = dollarAmountpertfuel * arrProjects[_index]['D']['prices']['mintPriceTfuel'];
    dollarAmountForMint = Number(parseInt(dollarAmountForMint * 100)) / 100;

    const elem = document.getElementById("mintCostId" + _index);
    if (elem != null) {
        elem.innerHTML = "Minting Price: ~$" + dollarAmountForMint + ".";
        document.getElementById("mintTfuelId" + _index).innerHTML = "Required Coin:  " + arrProjects[_index]['D']['prices']['mintPriceTfuel'] + " tfuel";

        // Now perform a balance test to see if the person can aford to buy the token
        if (arrGlobals['BalanceTfuel'] > Number(arrProjects[_index]['D']['prices']['mintPriceTfuel'])) {
            document.getElementById("mintButtonId" + _index).addEventListener('click', function () { mintPart(_index) }, false);
        } else {
            writeDisableTfuel(_index)
        }

    }
}
// Converts mint section into burn section
function writePartBurn(_index) {
    // Need the price of tfuel in order to make this calculation
    let dollarAmountpertfuel = arrProjects[_index]['D']['pennyPriceObj']['priceOfTfuel'];
    //console.log('dollarAmountpertfuel: ' + dollarAmountpertfuel);
    let dollarAmountForBurn = dollarAmountpertfuel * arrProjects[_index]['D']['prices']['burnPriceTfuel'];
    dollarAmountForBurn = Number(parseInt(dollarAmountForBurn * 100)) / 100;

    const elem = document.getElementById("burnCostId" + _index);
    if (elem != null) {
        elem.innerHTML = "Burning Price: ~$" + dollarAmountForBurn + ".";
        document.getElementById("burnTfuelId" + _index).innerHTML = "Required Coin:  " + arrProjects[_index]['D']['prices']['burnPriceTfuel'] + " tfuel";

        if (arrGlobals['BalanceTfuel'] > Number(arrProjects[_index]['D']['prices']['burnPriceTfuel'])) {
            document.getElementById("burnButtonId" + _index).addEventListener('click', function () { burnPart(_index) }, false);
        } else {
            writeDisableBurn(_index)
        }
    }
}

//
// Interface handlers
//

async function IPartV1(_index) {
    arrProjects[_index]['D']['priceObj'] = null;
    arrProjects[_index]['I']['IPartV1']['Obj'].methods.pricesRead().call().then(pricesObj => {
        arrProjects[_index]['D']['priceObj'] = pricesObj;
    });
}

async function IWebV1(_index) {
    arrProjects[_index]['D']['priceObj'] = null;
    arrProjects[_index]['I']['IWebV1']['Obj'].methods.pricesRead().call().then(pricesObj => {
        arrProjects[_index]['D']['priceObj'] = pricesObj;
    });
}


// ---------------------------------------------------------------------------------------

//
// Handlers here
//
// The withdrawTitled() routine is used for the Participant and Website projects. It will
// only be shown to the project owner.
async function withdrawAllHdr(_index) {
    //console.log("withdrawTitled Index is: " + _index);
    console.log('HANDLER: withdrawAllHdr()');

    if (await IsCorrectNetwork()) {
        //let contract = arrProjects[_index]['I']['ICore']['Obj'];
        // two parameters are agentId and websiteId
        console.log("calling withdrawAll(): " + arrGlobals['visitor']);

        let dataObj = document.getElementById("ownerTrxnId" + _index);

        let currentGasPrice = await web3.eth.getGasPrice();

        document.body.style.cursor = 'wait';
        try {
            //console.log('TODO: Bring wallet call back');

            await arrProjects[_index]['I']['ICore']['Obj'].methods.withdrawAll().send({
                from: arrGlobals['visitor'],
                gasPrice: currentGasPrice
            }).then(tx => {
                console.log(tx);
                var transactionRef = '<a href="http://www.thetascan.io/hash/?hash=' + tx.transactionHash + '" target="_blank">Trxn Link & Hash</a>';
                //console.log(transactionRef);
                dataObj.innerHTML = transactionRef;
            });

        } catch (error) {
            //console.log(error.message);
            dataObj.innerHTML = error.message;
        }
        dataObj.style.display = "block";
        document.body.style.cursor = 'default';
    }
}

async function mintPart(_index) {
    //console.log('perform mint, index: ' + _index);
    console.log('HANDLER: mintPart()');

    if (await IsCorrectNetwork()) {
        //let contract = arrProjects[_index]['contractObj'];
        let mintWei = arrProjects[_index]['D']['prices']['mintPriceTfuelWei'];

        let dataObj = document.getElementById("mintTrxnId" + _index);

        // we're going to check the balance before attempting to call MetaMask
        if (BigInt(arrGlobals['BalanceTfuelWei']) > BigInt(mintWei)) {
            console.log("calling soulboundMint(): " + mintWei);

            let currentGasPrice = await web3.eth.getGasPrice();

            document.body.style.cursor = 'wait';
            try {
                //console.log('TODO: Bring wallet call back');

                await arrProjects[_index]['I']['ICore']['Obj'].methods.soulboundMint().send({
                    from: arrGlobals['visitor'],
                    value: mintWei,
                    gasPrice: currentGasPrice
                }).on('error', (error) => {
                    console.log(error);
                }).then(tx => {
                    //console.log(tx);
                    var transactionRef = '<a href="http://www.thetascan.io/hash/?hash=' + tx.transactionHash + '" target="_blank">Trxn Link & Hash</a>';
                    console.log(transactionRef);
                    dataObj.innerHTML = transactionRef;
                    // wait three seconds after minting something before the refresh.
                    delayRefresh(3000);
                });

            } catch (error) {
                console.log('try&catch error');
                console.log(error.message);
                dataObj.innerHTML = error.message;
            }
            document.body.style.cursor = 'default';

        } else {
            dataObj.innerHTML = 'Insufficient Funds';
        }

        dataObj.style.display = "block";
    }

}

//
// This routine is associated with the ENTER button. The code has already looked 
// into the visitor's account and seen that there is no Participant NFT. When they
// click ENTER, this code will fetch the price of a Participant and launch 
// metamask to purchase that NFT. But only if they hold enough balance in the account
// to buy the NFT.
//
async function mintPartNew() {
    console.log('HANDLER: mintPartNew()');

    console.log('partAddr: ' + arrGlobals['participantAddr']);

    if (await IsCorrectNetwork()) {

        let PartABI = [];
        PartABI = arrGlobals['I']['ICore']['ABI'].concat(arrGlobals['I']['IPartV1']['ABI']);
        //console.log(PartABI);

        contractPartObj = new window.web3.eth.Contract(PartABI, arrGlobals['participantAddr']);
        //console.log(contractPartObj);

        // pricesRead
        let pricesObj = await contractPartObj.methods.pricesRead().call();
        let mintWei = pricesObj.mintWei;
        console.log('mintWei: ' + mintWei);

        let dataObj = document.getElementById("landingMsgId");

        // we're going to check the balance before attempting to call MetaMask
        if (BigInt(arrGlobals['BalanceTfuelWei']) > BigInt(mintWei)) {
            console.log("calling soulboundMint(): " + mintWei);

            let currentGasPrice = await web3.eth.getGasPrice();

            document.body.style.cursor = 'wait';
            try {
                //console.log('TODO: Bring wallet call back');

                await contractPartObj.methods.soulboundMint().send({
                    from: arrGlobals['visitor'],
                    value: mintWei,
                    gasPrice: currentGasPrice
                }).on('error', (error) => {
                    console.log(error);
                }).then(tx => {
                    //console.log(tx);
                    var transactionRef = '<a href="http://www.thetascan.io/hash/?hash=' + tx.transactionHash + '" target="_blank">Trxn Link & Hash</a>';
                    console.log(transactionRef);
                    dataObj.innerHTML = transactionRef;
                });

            } catch (error) {
                //console.log('try&catch error');
                console.log(error.message);
                dataObj.innerHTML = error.message;
            }
            document.body.style.cursor = 'default';

        } else {
            dataObj.innerHTML = 'Insufficient Funds';
            // show a linik to simpleswap.
            let swapObj = document.getElementById("landingSwapId");
            if (null != swapObj) {
                swapObj.style.display = 'block';
            }

        }
    }
}


//
// The participant and website contracts both use soulboundBurn() which does not take
// a token number, but they are payable.
// 
async function burnPart(_index) {
    //console.log('perform burn, index: ' + _index);
    //console.log('HANDLER: burnPart() TEST');

    if (await IsCorrectNetwork()) {
        //let contract = arrProjects[_index]['contractObj'];
        let burnWei = arrProjects[_index]['D']['prices']['burnPriceTfuelWei'];

        let dataObj = document.getElementById("burnTrxnId" + _index);

        // we're going to check the balance before attempting to call MetaMask
        if (BigInt(arrGlobals['BalanceTfuelWei']) > BigInt(burnWei)) {
            console.log("calling soulboundBurn(): " + burnWei);

            let currentGasPrice = await web3.eth.getGasPrice();

            document.body.style.cursor = 'wait';
            try {
                //console.log('TODO: Bring wallet call back');

                await arrProjects[_index]['I']['ICore']['Obj'].methods.soulboundBurn().send({
                    from: arrGlobals['visitor'],
                    value: burnWei,
                    gasPrice: currentGasPrice
                }).on('error', (error) => {
                    console.log(error);
                }).then(tx => {
                    //console.log(tx);
                    var transactionRef = '<a href="http://www.thetascan.io/hash/?hash=' + tx.transactionHash + '" target="_blank">Trxn Link & Hash</a>';
                    console.log(transactionRef);
                    dataObj.innerHTML = transactionRef;
                });

            } catch (error) {
                console.log(error.message);
                dataObj.innerHTML = error.message;
            }
            document.body.style.cursor = 'default';

        } else {
            dataObj.innerHTML = 'Insufficient Funds';
        }

        dataObj.style.display = "block";
    }
}

//
// This is the burn routine for the IBurnV1 interface. This 'burn()' function
// requires a token id and is not payable. 
//
// This is only used by soulBound tokens. The contract needs to support IBurnV1
// so that this call will succeed.
async function burnIt(_index) {
    console.log("burn index: " + _index);
    console.log('HANDLER: burnIt() TEST');

    if (await IsCorrectNetwork()) {

        console.log("calling burn: " + arrGlobals['visitor']);
        let TokenId = arrProjects[_index]['D']['theTokenId'];
        console.log("Token Id: " + TokenId);

        let currentGasPrice = await web3.eth.getGasPrice();

        document.body.style.cursor = 'wait';
        let dataObj = document.getElementById("mintTrxnId" + _index);
        try {
            console.log('TODO: Bring wallet call back');
/*
            await arrProjects[_index]['I']['IBurnV1']['Obj'].methods.burn(Number(TokenId)).send({
                from: arrGlobals['visitor'],
                gasPrice: currentGasPrice
            }).on('error', (error) => {
                console.log('on handler');
                console.log(error);
            }).then(tx => {
                //console.log(tx);
                var transactionRef = '<a href="http://www.thetascan.io/hash/?hash=' + tx.transactionHash + '" target="_blank">Trxn Link & Hash</a>';
                //console.log(transactionRef);
                dataObj.innerHTML = transactionRef;
            });
*/
        } catch (error) {
            //console.log(error.message);
            dataObj.innerHTML = error.message;
        }
        dataObj.style.display = "block";
        document.body.style.cursor = 'default';
    }
}

