<?php

if( !isset($globalsSet)) {
// Enforcing strict complience with file inclusion
exit('User should not call this file directly.');
}
// This file should not be called directly. Call index.php!
if( !isset($globalMobile)) {
exit('need layout set.');
}


class Theta_nft {

	private $cCustomNFT; // custom class
	private $customData; // data array for custom settings from client.

	private $gData; // data array of all global variables


	function __construct() {
	}

	public function Init($_cCustomNFT) {
		$this->cCustomNFT = $_cCustomNFT;
	}

	// This function builds a hidden section that contains global variables.
	//
	// When a project is developed, it should point out the sepcific pennyOracle and gallery contracts
	// that should be used. 
	//
	private function globalVars($_dsncommon,$_arrParams) {

		$rowId = "globalVars";

		$this->gData = $_dsncommon->globalVars($_arrParams);

		// we want to have a custom title for the Project and gallery
		if( isset($this->customData['theCustomId']) ) {
			$theCustomId = $this->customData['theCustomId'];
		} else {
			$theCustomId = "Custom NFT Project";
		}
		if( isset($this->customData['theGalleryId']) ) {
			$theGalleryId = $this->customData['theGalleryId'];
		} else {
			$theGalleryId = "Custom NFT Gallery";
		}

		$theMintCallbackRoutine = '';
		if( isset($this->customData['mintCallback']) ) {
			$theMintCallbackRoutine = $this->customData['mintCallback'];
		}
		$theButtonCallbackRoutine = '';
		if( isset($this->customData['buttonCallback']) ) {
			$theButtonCallbackRoutine = $this->customData['buttonCallback'];
		}

		// Here is where we get the custom overrides from the custom code
		if( $this->cCustomNFT != null ) {
			if( method_exists($this->cCustomNFT,'theData') ) {
				$this->customData = $this->cCustomNFT->theData();

				//echo "Adding custom stuff to globals.<br>";
				// now add this custom data to the globals
				foreach($this->customData as $key => $item) {

					// If the custom code has coin requests, let's get them here.
					if( $key == 'enableCoins') {
						$this->gData['enableCoins']=$item;
					}
					// Also, do we show the NFTs?
					if( $key == 'showHolderSection') {
						$this->gData['showHolderSection'] = $item;
					}
				}
			}
		}

		// For debugging
		if( $this->gData['debug'] == 2 ) {
			foreach($this->gData as $key => $item) {
				echo $key.': '.$item."<br>";
			}
			foreach($this->customData as $key => $item) {
				echo $key.': '.$item."<br>";
			}
		}
		// The hidden html
		$theStr = "<div id=".$rowId.">";
		$theStr.= "<div class='row' id='globalVarsCoreId' hidden>";

		// when we walk the global entries, we're going to see if its
		// being overwritten by a custom setting. If so, we'll wait for
		// the custom write.
		//$theStr.= $_dsncommon->globalHTML();
		foreach($this->gData as $key => $item) {
			if( !isset($this->customData[$key]) ) {
				$theStr .= '<div id="'.$key.'Id">'.$item.'</div>';
				//echo "MAIN-- ".$key.': '.$item."<br>";
			}
		}
		foreach($this->customData as $key => $item) {

			$theStr.= "<div id='".$key."Id'>".$item."</div>";
			//echo "CUSTOM ".$key.': '.$item."<br>";
		}

		// Specific to this page
		$theStr.= "<div id='theCustomId'>".$theCustomId."</div>";
		$theStr.= "<div id='theGalleryId'>".$theGalleryId."</div>";
		$theStr.= "<div id='mintCallbackId'>".$theMintCallbackRoutine."</div>";
		$theStr.= "<div id='buttonCallbackId'>".$theButtonCallbackRoutine."</div>";
		$theStr.= "</div>";
		$theStr.= "</div>";
		//echo $theStr;
		return $theStr;
	}

	// This section shows the total number of NFTs, the soulbound flag and the single flag
	// Total NFTs: 1 (soulbound or transferable) (single or multiple)
	// All these items are displayed on the same line. 
	private function theTotalsLine($_rowIdNum) {
		$projTotalNFTsId = "projTotalNFTsId".strval($_rowIdNum);
		$projTrxnStateId = "projTrxnStateId".strval($_rowIdNum);
		$projCollStateId = "projCollStateId".strval($_rowIdNum);

		$theStr = '';
		$theStr .= '<div class="standard" style="margin-top: 5px">';
		$theStr .= '<span class="natural" >Total NFTs: <span class="natural" id="'.$projTotalNFTsId.'"></span></span>';
		$theStr .= '<span class="natural" style="margin-left: 10px" id="'.$projTrxnStateId.'"></span>'; //(soulbound or transferable)
		$theStr .= '<span class="natural" style="margin-left: 10px" id="'.$projCollStateId.'"></span>'; //(single or multiple)

		$theStr .= '</div>';
		return $theStr;
	}

	// Start with index zero
	private function theMainProjectSec($_rowIdNum) {

		// build the variable names
		$projImageId = "projectImageLink".strval($_rowIdNum);

		$projTitleId = "projectName".strval($_rowIdNum);
		$projWPLinkId = "projectWhitepaper".strval($_rowIdNum);
		$projDescriptionId = "projectDescription".strval($_rowIdNum);
		$projMoreInfoId = "projectMoreInfo".strval($_rowIdNum);
		$projCreatorId = "projectCreator".strval($_rowIdNum);

		// new lines for video id and reel functionality
		$projVideoId = "projectVideoId".strval($_rowIdNum);
		$projReelId = "projectReel".strval($_rowIdNum);

		$projArtistId = "projectArtist".strval($_rowIdNum);
		$projContractId = "projectContract".strval($_rowIdNum);
		//$projTotalId = "projectTotal".strval($_rowIdNum);

		$projShareId = "projectShare".strval($_rowIdNum);
		$projABIId = "projectABI".strval($_rowIdNum);
		$projABIimgId = "projABIimg".strval($_rowIdNum);

		$verifyId = "verify".strval($_rowIdNum);
		$verifySize = 24;
		$verifyImg = "<img id='".$verifyId."' height='".$verifySize."' src='".$GLOBALS['theRootURL'] ."/dsn/images/unverified_small.png' >";

		$theStr = '';
		if( $this->gData['mobile'] != 0) 
		{
			$theStr .= "<div class='row'>";
			$theStr .= "<div class='title' id='".$projTitleId."' style='text-align:center'></div>"; // required

			//$theStr .= "<div class='column leftEighty' style='text-align:center'>";
			$theStr .= "<div id='".$projImageId."' style='text-align:center'></div>"; // 
			//$theStr .= "</div>";
			//$theStr .= "<div class='column rightTwenty'>";
			//$theStr .= "<img height='42' src='".$GLOBALS['theRootURL'] ."/dsn/images/copy_small.png' onclick='copyURI(".$_rowIdNum.")' >";
			//$theStr .= "<div id='".$projShareId."' ></div>";

			//$theStr .= "</div>";
			//$theStr .= "<div style='clear: both'></div>";

			$theStr .= "<div class='link' id='".$projWPLinkId."' hidden></div>"; // Optional
			$theStr .= "<div class='standard' id='".$projDescriptionId."' hidden></div>"; // Optional
			$theStr .= "<div class='link' id='".$projMoreInfoId."' hidden></div>"; // Optional
			$theStr .= "<div class='standard' id='".$projCreatorId."' hidden></div>"; // Optional

			// for video id and reel functionality
			$theStr .= "<div class='link' id='".$projVideoId."' hidden></div>"; // Optional
			$theStr .= "<div class='link' id='".$projReelId."' hidden></div>"; // Optional

			$theStr .= "<div class='standard' id='".$projArtistId."' hidden></div>"; // Optional
			$theStr .= "<div class='link' id='".$projContractId."'></div>";
			$theStr .= self::theTotalsLine($_rowIdNum);
			//$theStr .= "<div class='standard' id='".$projTotalId."'>Total NFTs: Unknown</div>";

			$theStr .= "</div>";		

		}
		else
		{
			$theStr .= "<div class='row'>";
			$theStr .= "<div class='column left'>";
			$theStr .= "<div id='".$projImageId."'></div>";
			$theStr .= "</div>";
			$theStr .= "<div class='column right'>";
			$theStr .= "<div>";
			$theStr .= "<span>".$verifyImg."</span>";
			$theStr .= "<span class='title' id='".$projTitleId."'>Name</span>"; // required
			$theStr .= "</div>";
			$theStr .= "<div class='link' id='".$projWPLinkId."' hidden><a></a></div>"; // Optional
			$theStr .= "<div class='standard' id='".$projDescriptionId."' hidden></div>"; // Optional
			$theStr .= "<div class='link' id='".$projMoreInfoId."' hidden><a></a></div>"; // Optional
			$theStr .= "<div class='standard' id='".$projCreatorId."' hidden></div>"; // Optional

			// for video id and reel functionality
			$theStr .= "<div class='link' id='".$projVideoId."' hidden></div>"; // Optional
			$theStr .= "<div class='link' id='".$projReelId."' hidden></div>"; // Optional

			$theStr .= "<div class='standard' id='".$projArtistId."' hidden></div>";  // Optional
			// going to place a copy ABI image on the page before the link
			$theStr .= "<span >";
			$theStr .= "<span id='".$projABIId."' hidden></span>";
			$theStr .= "<img height='25' id='".$projABIimgId."' src='".$GLOBALS['theRootURL'] ."/dsn/images/abi_small.png' onclick='copyABI(".$_rowIdNum.")'>";
			$theStr .= "<span class='link' id='".$projContractId."'></span>";
			$theStr .= "</span>";

			$theStr .= self::theTotalsLine($_rowIdNum);
			//$theStr .= "<div class='standard' id='".$projTotalId."'>Count of NFTs Here</div>";
			$theStr .= "</div>";
			$theStr .= "</div>";
			$theStr .= "<div style='clear: both'></div>";
		}

		echo $theStr;
	}

	//
	// The mint row is being broken up into a mint row and burn row. The JavaScript is 
	// going to fill out both datasets and show the one that is appropriate to show.
	//
	private function theMintSec($_rowIdNum) {
		$mintRowId = "mintRowId".strval($_rowIdNum);
		$mintButtonId = "mintButtonId".strval($_rowIdNum);
		$mintTrxnId = "mintTrxnId".strval($_rowIdNum);
		$mintCostId = "mintCostId".strval($_rowIdNum);
		$mintTfuelId = "mintTfuelId".strval($_rowIdNum);
		$mintMsgId = "mintMsgId".strval($_rowIdNum);
		$mintCrossChainId = "mintCrossChainId".strval($_rowIdNum);

		$tfuelmintButtonTxt = "<img height='100' src='".$GLOBALS['theRootURL']."/dsn/images/mint_tfuel_3.png'>";

		$dShow = '';//'enable';
		$arrEnableCoins = null;
		if( isset($this->customData['enableCoins']) ) {
			$arrEnableCoins = $this->customData['enableCoins'];
			if( isset($arrEnableCoins['tfuel']) && false == $arrEnableCoins['tfuel'] ) {
				$dShow ='disabled';
			}
		}
		// output starts here.
		$theStr = "<div id='".$mintRowId."' hidden>";
		$theStr.= "<center><hr style='color:lightgray;width:75%'></center>";
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>Mint Section</div>';
		$theStr.= "<div class='row'>";
		$theStr.= "<div class='column left'>";
		$theStr.= "<div hidden>Mint Row</div>";

		// With the mint button, we give the option for it to be enabled or disabled. It's enabled by default.
		$theStr .=  "<button class='core centerIt' id='".$mintButtonId."' ".$dShow.">".$tfuelmintButtonTxt."</button>";
		$theStr .=  "<div id='".$mintTrxnId."' hidden></div>";

        $theStr .= "</div>";
		$theStr.= "<div class='column right'>";
		$theStr.= "<div class='standard' id='".$mintCostId."'></div>"; // Minting Price: ~$.
		$theStr.= "<div class='standard' id='".$mintTfuelId."'></div>"; // Required Coin:
		$theStr.= "<div class='standard' id='".$mintMsgId."'>Please validate the value and receiver in metamask.</div>";
		$theStr.= "<div class='standard' id='".$mintCrossChainId."'></div>";
		$theStr.= "</div>";
		$theStr.= "</div>";
		$theStr.= "<div style='clear: both'></div>";
		$theStr.= "</div>";
		echo $theStr;
	}
	private function theBurnSec($_rowIdNum) {
		$burnRowId = "burnRowId".strval($_rowIdNum);
		$burnButtonId = "burnButtonId".strval($_rowIdNum);
		$burnTrxnId = "burnTrxnId".strval($_rowIdNum);
		$burnCostId = "burnCostId".strval($_rowIdNum);
		$burnTfuelId = "burnTfuelId".strval($_rowIdNum);
		$burnMsgId = "burnMsgId".strval($_rowIdNum);
		$burnCrossChainId = "burnCrossChainId".strval($_rowIdNum);

		$tfuelburnButtonTxt = "<img height='100' src='".$GLOBALS['theRootURL']."/dsn/images/burn.png'>";

		$dShow = '';//'enable';
		$arrEnableCoins = null;
		if( isset($this->customData['enableCoins']) ) {
			$arrEnableCoins = $this->customData['enableCoins'];
			if( isset($arrEnableCoins['tfuel']) && false == $arrEnableCoins['tfuel'] ) {
				$dShow ='disabled';
			}
		}

		// output starts here.
		$theStr = "<div id='".$burnRowId."' hidden>";
		$theStr.= "<center><hr style='color:lightgray;width:75%'></center>";
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>Burn Section</div>';
		$theStr.= "<div class='row'>";
		$theStr.= "<div class='column left'>";
		$theStr.= "<div hidden>Burn Row</div>";

		// With the burn button, we give the option for it to be enabled or disabled. It's enabled by default.
		$theStr .=  "<button class='core centerIt' id='".$burnButtonId."' ".$dShow.">".$tfuelburnButtonTxt."</button>";
		$theStr .=  "<div id='".$burnTrxnId."' hidden></div>";

        $theStr .= "</div>";
		$theStr.= "<div class='column right'>";
		$theStr.= "<div class='standard' id='".$burnCostId."'></div>"; // Burning Price: ~$.
		$theStr.= "<div class='standard' id='".$burnTfuelId."'></div>"; // Required Coin:
		$theStr.= "<div class='standard' id='".$burnMsgId."'>Please validate the value and receiver in metamask.</div>";
		$theStr.= "<div class='standard' id='".$burnCrossChainId."'></div>";
		$theStr.= "</div>";
		$theStr.= "</div>";
		$theStr.= "<div style='clear: both'></div>";
		$theStr.= "</div>";
		echo $theStr;
	}

	// This shows status about a particular token number.
	private function memInfoLine($_rowIdNum) {
		$memTheInfoId = "memTheInfoId".strval($_rowIdNum);
		$memMintHoursId = "memMintHoursId".strval($_rowIdNum);
		$memRenewHoursId = "memRenewHoursId".strval($_rowIdNum);
		$memCostRenewId = "memCostRenewId".strval($_rowIdNum);
		$memChargeRateId = "memChargeRateId".strval($_rowIdNum);

		// HTML starts here
		$theStr = '<div id="'.$memTheInfoId.'" style="margin-top: 5px;margin-bottom: 5px">';
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>memInfoLine</div>';
		$theStr .= '<div class="column left">';
		$theStr .= '<div >Membership Info</div>';
        $theStr .= '</div>';

		$theStr .= '<div class="column right">';

		$theStr .= '<div>Granted during mint: <span id="'.$memMintHoursId.'" class="natural"></span>hrs</div>';
		$theStr .= '<div>Granted during renewal: <span id="'.$memRenewHoursId.'" class="natural"></span>hrs</div>';
		$theStr .= '<div>Cost to reactivate during renewal: <span id="'.$memCostRenewId.'" class="natural"></span></div>';
		$theStr .= '<div>Charge rate is <span id="'.$memChargeRateId.'" class="natural"></span> per day.</div>';
		$theStr .= '</div>';
		$theStr .= '<div style="clear: both"></div>';
		$theStr .= '</div>';

		return $theStr;
	}
	// This is the first line of the membership functionality. If the visitor is found
	// to be holding a token, that value will be placed in the evaluate control. If that
	// control holds a non-zero token id, status on that token will be shown.
	private function memEvaluateLine($_rowIdNum) {
		$memEvaluateId = "memEvaluateId".strval($_rowIdNum);
		$memKeyTokenId = "memKeyTokenId".strval($_rowIdNum);
		$memEvaluateBtnId =  "memEvaluateBtnId".strval($_rowIdNum);
	
		// HTML starts here
		$theStr = '<div id="'.$memEvaluateId.'" style="text-align: center;margin-bottom: 5px">';
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>memEvaluateLine</div>';

		// need to have a token id to base all the membership info off of.
		$theStr .= '<div>';
		$theStr .= '<input class="custom inlineIt" id="'.$memKeyTokenId.'" type="number" placeholder="Token Id"></input>';
		$theStr .= '<span class="natural" ><button class="natural inlineIt" id="'.$memEvaluateBtnId.'" onclick="memEvaluate('.$_rowIdNum.')" >EVALUATE</button></span>';
		$theStr .= '</div>';

		$theStr.= '</div>';
		return $theStr;
	}

	private function memRenewLine($_rowIdNum) {
		$memRenewId = "memRenewId".strval($_rowIdNum);

		$memRenewMinId = "memRenewMinId".strval($_rowIdNum);

		$memAdditionalId = "memAdditionalId".strval($_rowIdNum);
		$memRenewExtendBtnId = "memRenewExtendBtn".strval($_rowIdNum);

		$memInfoId = "memInfo".strval($_rowIdNum);
		$memInfoText = 'With memberships, any Metamask account can renew or extend any membership token. If the membership is active, any value provided will be added as intrinsic value balance, which buys time for the member token. If the account is inactive, the renew fee will be deducted from the value provided and then any remaining Tfuel will be added as intrinsic value balance.';
		$memInfoImg = "<img height='28' src='".$GLOBALS['theRootURL']."/dsn/images/info_small.png' onclick='memInfoToggle(".$_rowIdNum.")'>";

		// HTML starts here
		$theStr = '<div id="'.$memRenewId.'" style="text-align: center" hidden>';
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>memRenewLine</div>';

		$theStr .= '<div >';
		$theStr .= '<span class="natural" >';
		$theStr .= '<span class="natural" id="'.$memRenewMinId.'" hidden></span>';

		$theStr .= '<span class="natural" >Increase by more than renewal fee: </span>';
		$theStr .= '<input class="custom inlineIt" id="'.$memAdditionalId.'" type="number" placeholder="Additional dollars"></input>';
		$theStr .= '<span class="natural" ><button class="natural inlineIt" id="'.$memRenewExtendBtnId.'" onclick="memRenew('.$_rowIdNum.')" disabled></button></span>';
		$theStr .= '</span>';
		$theStr .= '<span class="natural" >'.$memInfoImg.'</span>';
		// Add the description of the control here.
		$theStr .= '<div id="'.$memInfoId.'" class="natural" style="margin-top: 10px;margin-bottom: 10px" hidden>'.$memInfoText.'</div>';
		$theStr .= '</div>';

		$theStr.= '</div>'; // end of main section
		return $theStr;
	}

	// This shows status about a particular token number. The visiting address
	// needs to be holding a token for this section to be shown.
	private function memStatusLine($_rowIdNum) {
		$memStatusId = "memStatusId".strval($_rowIdNum);

		$memWithdrawBtnId = "memWithdrawBtnId".strval($_rowIdNum);

		$memActiveId = "memActiveId".strval($_rowIdNum);
		$memDaysId = "memDaysId".strval($_rowIdNum);
		$memHoursId = "memHoursId".strval($_rowIdNum);
		$memBalanceId = "memBalanceId".strval($_rowIdNum);
		$memUnsettledId = "memUnsettledId".strval($_rowIdNum);

		// HTML starts here
		$theStr = '<div id="'.$memStatusId.'" style="margin-top: 5px" hidden>';
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>memStatusLine</div>';
		$theStr .= "<div class='column left'>";
		$theStr .= '<button class="natural inlineIt" id="'.$memWithdrawBtnId.'" onclick="memWithdraw('.$_rowIdNum.')" disabled>WITHDRAW BALANCE</button>';
        $theStr .= "</div>";

		$theStr .= "<div class='column right'>";

		$theStr .= 'Status: <span id="'.$memActiveId.'" class="natural"></span><br>';
		$theStr .= 'Timeleft: <span id="'.$memDaysId.'" class="natural"></span> days, <span id="'.$memHoursId.'" class="natural"></span> hours<br>';
		$theStr .= 'Balance: <span id="'.$memBalanceId.'" class="natural"></span> Tfuel, ';
		$theStr .= 'Unsettled: <span id="'.$memUnsettledId.'" class="natural"></span> Tfuel';
		$theStr .= "</div>";
		$theStr .= "<div style='clear: both'></div>";
		$theStr .= "</div>";

		return $theStr;
	}
	// This shows status about a particular token number.
	private function memOwnerLine($_rowIdNum) {
		$memOwnerId = "memOwnerId".strval($_rowIdNum);

		$memSettleBtnId = "memSettleBtnId".strval($_rowIdNum);
		$memSettleTokenId = "memSettleTokenId".strval($_rowIdNum);

		$memGrantBtnId = "memGrantBtnId".strval($_rowIdNum);
		$memGrantHrsId = "memGrantHrsId".strval($_rowIdNum);
		$memGrantTokenId = "memGrantTokenId".strval($_rowIdNum);

		$memTreasuryBalanceId = "memTreasuryBalanceId".strval($_rowIdNum);

		// HTML starts here
		$theStr = '<div class="owner" id="'.$memOwnerId.'" style="text-align: center" hidden>';
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>memOwnerLine</div>';

		$theStr .= '<div style="margin-top: 5px">';
		$theStr .= '<span  class="natural">';
		$theStr .= '<button class="natural inlineIt" id="'.$memSettleBtnId.'" style="margin-left: 10px" onclick="memSettleTitled('.$_rowIdNum.')" disabled>SETTLE</button>';
		$theStr .= '</span>';
		$theStr .= '<span class="natural">Token <span id="'.$memSettleTokenId.'" class="natural"></span></span>';
		$theStr .= '</div>';

		$theStr .= '<div style="margin-top: 5px">';
		$theStr .= '<span class="natural">';
		$theStr .= '<button class="natural inlineIt" id="'.$memGrantBtnId.'" style="margin-left: 10px" onclick="memGrantHours('.$_rowIdNum.')" disabled>GRANT</button>';
		$theStr .= '</span>';
		$theStr .= '<span class="natural"><input class="custom inlineIt" id="'.$memGrantHrsId.'" type="number" placeholder="Hours"></input></span>';
		$theStr .= '<span class="natural"> to Token <span id="'.$memGrantTokenId.'" class="natural"></span></span>';

		$theStr .= '<div>The Treasury Balance: <span id="'.$memTreasuryBalanceId.'" class="natural"></span></div>';
		$theStr .= '</div>';

		$theStr .= '</div>';
		return $theStr;
	}

	private function theMembershipSec($_rowIdNum) {
		$memRowId = "memRowId".strval($_rowIdNum); // used to show all the membership html
		$memTrxnId = "memTrxnId".strval($_rowIdNum);

		// output starts here.
		$theStr = "<div id='".$memRowId."' hidden>";
		$theStr.= "<center><hr style='color:lightgray;width:75%'></center>";
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>theMembershipSec</div>';
		$theStr.= "<div class='row'>";

		$theStr .= self::memInfoLine($_rowIdNum); // Always show
		// full screen line
		$theStr .= self::memEvaluateLine($_rowIdNum); // Always show
		$theStr .= self::memRenewLine($_rowIdNum); // Only show if there is a tokenId
		$theStr .= self::memStatusLine($_rowIdNum); // Only show if there is a tokenId
		// Next: Owner Section allows for memSettledTitled() and memGrantHours()
		$theStr .= self::memOwnerLine($_rowIdNum);
		$theStr .=  "<center><div id='".$memTrxnId."' hidden></div></center>";

		$theStr.= "</div>";
		$theStr.= "<div style='clear: both'></div>";
		$theStr.= "</div>";
		echo $theStr;

	}

	private function theHoldings($_rowIdNum) {
		$holdingRowId = "holdingRowId".strval($_rowIdNum);
		$holdingNFTRowId = "holdingNFTRowId".strval($_rowIdNum);

		$theStr = "<div id='".$holdingRowId."' hidden>";
		$theStr .= "<center><hr style='color:lightgray;width:75%'></center>";
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>theHoldings</div>';
		//$theStr .= "<center>NFTs held</center>";
		$theStr .= "<div id='".$holdingNFTRowId."' style='margin-top:5px'></div>";
		$theStr .= "<div style='clear: both'></div>";
		$theStr .= "</div>";
		echo $theStr;
	}

	private function theAgentSec($_rowIdNum) {
		$agentRowId = "agentRowId".strval($_rowIdNum);

		$agentTrxnId = "agentTrxnId".strval($_rowIdNum);
		$agentBalanceId = "agentBalance".strval($_rowIdNum);
		$agentTimeId = "agentTime".strval($_rowIdNum);
		$agentCutsId = "agentCuts".strval($_rowIdNum);

		$agentButtonId = "agentButtonId".strval($_rowIdNum);

		$theStr = '';
		if( $this->gData['mobile'] != 0) 
		{
			$theStr.= "<div id='".$agentRowId."' class='agent' hidden>";
			$theStr.= "<center><hr style='color:lightgray;width:75%'></center>";
			$theStr.= "<div class='row'>";
			//$theStr.= "<div class='column left'>";
			$theStr.= '<button class="natural centerIt" id="'.$agentButtonId.'" disabled>WITHDRAW</button><br>';
			$theStr.= "<div id='".$agentTrxnId."' hidden></div>";
			//$theStr.= "</div>";
			//$theStr.= "<div class='column right'>";
			$theStr.= "<div class='standard' id='".$agentBalanceId."'>balance and count info</div>";
			$theStr.= "<div class='standard' id='".$agentTimeId."'>Time left and min count</div>";
			$theStr.= "<i><div class='standard' id='".$agentCutsId."'>Cuts: agent, website</div></i>";
			//$theStr.= "</div>";
			$theStr.= "</div>";
			$theStr.= "<div style='clear: both'></div>";
			$theStr.= "</div>";
		}
		else
		{
			$theStr.= "<div id='".$agentRowId."' class='agent' hidden>";
			$theStr.= "<center><hr style='color:lightgray;width:75%'></center>";
			$theStr.= '<div class="token" '.$this->gData['showLables'].'>theAgentSec</div>';
			$theStr.= "<div class='row'>";
			$theStr.= "<div class='column left'>";
			$theStr.= '<button class="natural centerIt" id="'.$agentButtonId.'" disabled>WITHDRAW</button><br>';
			$theStr.= "<div id='".$agentTrxnId."' hidden></div>";
			$theStr.= "</div>";
			$theStr.= "<div class='column right'>";
			$theStr.= "<div class='standard' id='".$agentBalanceId."'>balance and count info</div>";
			$theStr.= "<div class='standard' id='".$agentTimeId."'>Time left and min count</div>";
			$theStr.= "<i><div class='standard' id='".$agentCutsId."'>Cuts: agent, website</div></i>";
			$theStr.= "</div>";
			$theStr.= "</div>";
			$theStr.= "<div style='clear: both'></div>";
			$theStr.= "</div>";
		}

		echo $theStr;
	}

	//
	// This section has two elements: a button (with trxn handler) and a description.
	// The JavaScript will need to set both the button handler and the description.
	// 
	// The main use of this section is to expose the balance held on the contract that
	// the owner (or titled) can withdraw. Thus, this is the agentPayObj of the titled
	// address.
	//
	private function theOwnerLine($_rowIdNum) {
		$ownerLineId = "ownerLineId".strval($_rowIdNum);
		//$ownerButtonId = "ownerButtonId".strval($_rowIdNum);
		$ownerButtonLegacyId = "ownerButtonLegacyId".strval($_rowIdNum); // legacy
		$ownerButtonIPayV1Id = "ownerButtonIPayV1Id".strval($_rowIdNum); // IPayV1
		$ownerTrxnId = "ownerTrxnId".strval($_rowIdNum);
		$ownerBalanceId = "ownerBalanceId".strval($_rowIdNum); // old

		$theStr = '';
		if( $this->gData['mobile'] != 0) 
		{
			$theStr.="<div id='".$ownerLineId."' hidden>";
			//$theStr.="<center><hr style='color:lightgray;width:75%'></center>";
			$theStr.="<div class='row'>";
			//$theStr.="<div class='column left'>";
			$theStr.="<div hidden>Owner Row</div>";
			$theStr.="<button class='natural centerIt' id='".$ownerButtonLegacyId."' disabled hidden>WITHDRAW</button>";
			$theStr.="<button class='natural centerIt' id='".$ownerButtonIPayV1Id."' disabled hidden>WITHDRAW</button>";
			$theStr.="<div id='".$ownerTrxnId."' hidden></div>";
			//$theStr.="</div>";
			//$theStr.="<div class='column right'>";
			$theStr.="<div class='standard' id='".$ownerBalanceId."'></div>";
			//$theStr.="</div>";
			$theStr.="</div>";
			$theStr.="<div style='clear: both'></div>";
			$theStr.="</div>";
		}
		else
		{
			$theStr.="<div id='".$ownerLineId."' hidden>";
			//$theStr.="<center><hr style='color:lightgray;width:75%'></center>";
			$theStr.= '<div class="token" '.$this->gData['showLables'].'>theOwnerLine</div>';
			$theStr.="<div class='row'>";
			$theStr.="<div class='column left'>";
			$theStr.="<div hidden>Owner Row</div>";
			$theStr.="<button class='natural' id='".$ownerButtonLegacyId."' disabled hidden>WITHDRAW</button>";
			$theStr.="<button class='natural' id='".$ownerButtonIPayV1Id."' disabled hidden>WITHDRAW</button>";
			$theStr.="<div id='".$ownerTrxnId."' hidden></div>";
			$theStr.="</div>";
			$theStr.="<div class='column right'>";
			$theStr.="<div class='standard' id='".$ownerBalanceId."'></div>";
			$theStr.="</div>";
			$theStr.="</div>";
			$theStr.="<div style='clear: both'></div>";
			$theStr.="</div>";
		}

		return $theStr;
	}

	//
	// This function displays information that is useful to the admin. If the visitor 
	// is ether the titled or owner this section will be displayed. Right now, it 
	// supports the toggling of the mint funcitonality.
	//
	// Note that the NFT must provide the toggle functionality via IMintV1.
	//
	private function theAdminSec($_rowIdNum) {
		$AdminRowId = "AdminRowId".strval($_rowIdNum);
		$AdminLinkId = "AdminLinkId".strval($_rowIdNum); // for 'enable minting' or 'disable minting'
		$AdminTrxnId =  "AdminTrxnId".strval($_rowIdNum);
		$raskelId = "raskelId".strval($_rowIdNum); // id of image
	
		$theStr = '';
		$theStr.='<div id="'.$AdminRowId.'" class="admin" hidden>';
		$theStr.="<center><hr style='color:lightgray;width:75%'></center>";
		$theStr.="<div class='row' style='text-align: center'>";
		$theStr.= '<div class="token" '.$this->gData['showLables'].'>theAdminSec</div>';

		$theStr.= self::theOwnerLine($_rowIdNum);

		// here is where our one line of data does. Format it here and the 
		// javascript code will fill in the innerHTML
		$imgSrc = $GLOBALS['theRootURL'] ."/dsn/images/disable_large.png";
		$theImage = "<img height='36' id='".$raskelId."' src='".$imgSrc."' onclick='mintToggle(".$_rowIdNum.")'>";

		$theStr .= "<span id='".$AdminLinkId."' class='natural' hidden>";
		$theStr .=  "<button class='core centerIt' >".$theImage."</button>";
		$theStr .=  "<center><div id='".$AdminTrxnId."' hidden></div></center>";
		//$theStr .= $theImage;
		$theStr .= "</span>";

		$theStr.="</div>";
		$theStr.="</div>";
		echo $theStr;
	}

	//
	// If the person visiting the site is not the projet owner, we're going to show
	// a link to the project owner's and titled's wallets.
	//
	private function theOwnersLinksSec($_rowIdNum) {
		$titledLinkRowId = "titledLinkRowId".strval($_rowIdNum);
		$titledLinkLinkId = "titledLinkLinkId".strval($_rowIdNum);
		$ownerLinkLinkId = "ownerLinkLinkId".strval($_rowIdNum);

		$theStr = '';
		$theStr.="<div id='".$titledLinkRowId."' hidden>";
		$theStr.="<center><hr style='color:lightgray;width:75%'></center>";
		$theStr.="<div class='row'>";
		// here is where our one line of data does. Format it here and the 
		// javascript code will fill in the innerHTML
		$theStr .= "<div id='".$ownerLinkLinkId."' style='text-align: center'>Project Owner: <a>Link</a></div>";
		$theStr .= "<div id='".$titledLinkLinkId."' style='text-align: center'>Project Titled: <a>Link</a></div>";
		$theStr.="</div>";
		$theStr.="</div>";
		echo $theStr;
	}

	private function theEnd() {
		$theStr = '<div style="width: 100%; overflow: hidden;">';
		$theStr.= '<div style="width: 90%; float: left;">';
		$theStr .= "<center><hr class='bar' ></center>";
		$theStr.= '</div>';
		$theStr.= '<div style="margin-left: 90%;">';
		$theStr .= "<img height='25' id='topId' src='".$GLOBALS['theRootURL'] ."/dsn/images/top.png' onclick='moveToTop()'>";
		$theStr.= '</div>';
		$theStr.= '</div>';
		echo $theStr;
	}


	public function theProject($index, $_IsSingle) {

		$proj = "projectRowId".strval($index);
		echo "<div id='".$proj."' hidden>";

		// For debugging
		$this->gData['showLables'] = 'hidden'; // string of '' or 'hidden'

		// Now the inner html

		//
		// The main section will shown to everyone that visits the project.
		//
		self::theMainProjectSec(intval($index));

		//
		// The mint section is shown to everyone but is adjusted based on conditions.
		// If the contract allows for multiple mint, the mint section will be shown.
		// If the contract is single (membership), the mint functionality will only 
		// be shown if the visitor doesn't already hold a token.
		// If the contract is soulbound (implies only one), the mint will only be
		// shown if the visitor doesn't already hold a token.
		//
		// If the contract is not mintable, the mint button will be grayed out.
		// If the visitor doesn't have enough balance to mint, the mint button 
		// will be grayed out.
		//
		self::theMintSec(intval($index));

		// When dealing with memberships, it will be done before the custom code section.
		//
		// With this section, if the contract supports the IMemV1 interface, this section 
		// will be shown. 
		//
		self::theMembershipSec(intval($index));

		if( true == $_IsSingle ) {
			// This is the location where we want to output the custom code.
			// Now we make room for custom functionality that is unique to the project
			//var_dump($this->cCustomNFT);
			if( method_exists($this->cCustomNFT,'customHTML') ) {

				// Output a horizontal line to denote the change.
				echo "<div id='customSecId'><center><hr style='color:lightgray;width:75%'></center>";

				// Get the section from the project.
				echo $this->cCustomNFT->customHTML();
				//echo "Done with custom sections<br>";

				echo "  </div><div style='clear: both'></div>";
			}
		}

		// If we have a custom project that it handling displaying the tokens 
		// themselves, then we don't want to double up that work.
		if( $this->gData['showHolderSection'] != false ) {
			self::theHoldings(intval($index));
		}

		// The Agent section is only shown to agents of the network. If the
		// visitor is an agent, it will be shown.
		self::theAgentSec(intval($index));

		//
		// This section will show functionality that is available to both the owner and
		// titled for the smart contract. Right now, it manages:
		// withdraw of ower balance,
		// toggling the mint lock.
		//
		// Withdrawing a balance:
		// IPayV1 has both payWithdraw() and payWithdrawTitled(). The difference between these
		// two routines is that payWithdraw() will withdraw the balance of the visitor, but 
		// payWithdrawTitled() can be triggered by either owner or titled and will only withdraw
		// the titled funds. If owner != titled and the owner visits, a balance will be shown
		// for Titled (not owner).
		//
		// If there is a balance on the Participant, Agent or Website smart contracts, this 
		// code will show a withdraw button which calls the ICore WithdrawAll() function.
		// This function only allows the project titled to claim the funds.
		//
		self::theAdminSec($index); // admin stuff like mint toggle 
		//self::theOwnerSec(intval($index));

		//
		// This section simply shows links to the wallets of both the registered owner
		// and titled on the smart contract.
		//
		self::theOwnersLinksSec(intval($index)); // show owner and titled links

		// The burn section is shown last. This section will only be shown for contracts
		// that support burning. Burn functionality is provided with:
		//
		// IBurn burn(tokenId),
		// IPayV2 as payBurn(tokenId)=payable uses payPrice(INDEX) to get the cost. or
		// IERC721ExV1 as payBurn(tokeId)=payable uses payBurnPrice() to get the cost.
		// ICore as soulboundburn()=payable using IPartV1 or IWebV1 pricesRead() to get the cost.
		// 
		// Depending on the conditions, when the user clicks on the RIP (burn) image, the code
		// will need to call the correct burn handler for the situation.
		self::theBurnSec(intval($index));

		self::theEnd();

		echo "</div>";
	
	}

	//
	// The main routine echo's blocks out as it processes them. 
	//
	public function thePage($_arrParams)
	{
		$cDSNReadme = new CDSNReadme();
		$arrData = $cDSNReadme->data();

		$dsncommon = new DSNCommon();
		if( null == $dsncommon ) 
		{ 
			exit('ERORR: thePage() sees dsncommon as null');
		}

		echo "<!DOCTYPE html>";

		$theTitle = $arrData['tabTitle'];
		$theDesc = "Selene Network Distributed Sales Network with Custom NFTs.";

		echo $dsncommon->headerInfo($theTitle,$theDesc);

		// When we add script for the client machine to fetch, it has to be built off
		// the URL (theRootUR). 

		// load project common functionality
		$theCommonJSFile = $GLOBALS['theRootURL'].'/dsn/dsncommon.js';
		//var_dump($theWaJSFile);
		echo "<script type='text/javascript' src='".$theCommonJSFile."' defer></script>";

		// this is for handling nfts with interfaces
		$theJSFile = $GLOBALS['theRootURL'].'/dsn/interfaces.js';
		echo "<script type='text/javascript' src='".$theJSFile."' defer></script>";
		// this is for handling the legacy participant and website nfts
		$theJSExFile = $GLOBALS['theRootURL'].'/dsn/dsnex.js';
		echo "<script type='text/javascript' src='".$theJSExFile."' defer></script>";
		$theJSFile = $GLOBALS['theRootURL'].'/dsn/pay.js';
		echo "<script type='text/javascript' src='".$theJSFile."' defer></script>";
		$theJSFile = $GLOBALS['theRootURL'].'/dsn/mem.js';
		echo "<script type='text/javascript' src='".$theJSFile."' defer></script>";
		$theJSFile = $GLOBALS['theRootURL'].'/dsn/dsn.js';
		echo "<script type='text/javascript' src='".$theJSFile."' defer></script>";

		//
		// If the loading NFT has custom data, we're going to get it here. 
		// If it does any javascript functionality, they will give this code
		// the file to load.
		//
		$this->customData = array();
		// If the project has custom JavaScript, we'll need to load that here.
		if( $this->cCustomNFT != NULL ) {

			if( method_exists($this->cCustomNFT,'theData') ) {
				$this->customData = $this->cCustomNFT->theData();

				// Now if the custom data supports any coins other than tfuel,
				// lets get that array and add it to our globals.
				if(isset($this->customData['enableCoins'])) {
					//echo "custom Supports Multi-coins<br>";
					$this->gData['enableCoins'] = $this->customData['enableCoins'];
				}
			}
		}
		// Now see if we have custom JavaScript to load.
		if( isset($this->customData['javaScriptName']) ) {
			//var_dump($this->customData['javaScriptName']);
			// When we load a custom project, the user will have referenced a PHP file in the 
			// project directory(location), thus all we should need here is a filename.ext.
			echo "<script type='text/javascript' src='".$this->customData['javaScriptName']."' defer></script>";
		}

		// start of body.

		echo "<body>";
		echo $dsncommon->theCSS();
		echo '<div class="blackout" id="blackoutId" >';
		echo self::globalVars($dsncommon,$_arrParams);

		//echo "After globalVars<br>";
		// Here is were the page gets built. 
		//var_dump($this->gData);
		//echo "<br>";
		if( isset($this->gData['enableCoins'])) {
			echo $dsncommon->connectRow($this->gData['enableCoins']);
		} else {
			echo $dsncommon->connectRow(null);
		}
		echo $dsncommon->errorRow();

		// If we're in single mode, we'll just show one project. Else, we'll 
		// setup for the gallery.
		$IsSingle = false;
		if( isset($this->customData['isSingleView']) ) {
			if( true == $this->customData['isSingleView'] ) {
				$IsSingle = true;
			}
		} 

		if( $IsSingle ) {
			// show the body for a single entity.
			self::theProject(0, $IsSingle);
		}
		else {
			// show a common gallery
			$count = $arrData['galleryLimit'];
			for($i=0;$i<$count;$i++) {
				self::theProject($i, $IsSingle);
			}
		}

		echo $dsncommon->theFooter();
		echo "</div>";
		echo "</body>";
		echo "</html>";
	}
}


if( !function_exists("run_the_code") ) {
function run_the_code() {

	$plugin = new Theta_nft();
	$plugin->Init(null);
	$plugin->thePage();
}
run_the_code();
}

