<?php

class TallyXML
{
	public $file = "AllMaster.xml";

	public static $LEDGER = "LEDGER";
	public static $GROUP = "GROUP";
	public static $STOCKITEM = "STOCKITEM";
	public static $STOCKGROUP = "STOCKGROUP";
	public static $UNIT = "UNIT";
/*
	public function __construct()
	{
	}
*/
	public static function Parse($file="", $nodeName="", $parent="", $toFile="")
	{
		if (empty($file) || !is_file($file))
		{
			return false;
		}

		try {
			$xml = new XMLReader();
			$xml->open('compress.zlib://' . $file);

			$return = array();

			$xml->moveToAttribute($nodeName);

			while($xml->read())
			{
				if ($xml->nodeType != XMLReader::ELEMENT || $xml->name != $nodeName)
				{
					continue;
				}

				switch($xml->name)
				{
					case "STOCKITEM":
						$item = array();

						$element = new SimpleXMLElement($xml->readOuterXML());

						$item["\$Name"] = $xml->getAttribute("NAME");
						$item["category"] = strval($element->PARENT);
						// $item["\$GSTRepUoM"] = strval($element->BASEUNITS);
						$item["\$BaseUnits"] = strval($element->BASEUNITS);
						$item["\$VatBaseUnit"] = strval($element->VATBASEUNIT);
						$item["\$BasicRateOfExcise"] = strval($element->BASICRATEOFEXCISE);
						$item["\$GSTTypeofSupply"] = strval($element->GSTTYPEOFSUPPLY);
						$item["\$IsRateInclusiveVAT"] = strval($element->ISRATEINCLUSIVEVAT);
						$item["\$InclusiveTax"] = strval($element->INCLUSIVETAX);
						$item["\$GSTApplicable"] = strval($element->GSTAPPLICABLE);
						$item["\$_ClosingBalance"] = strval($element->CLOSINGBALANCE);
						$item["\$_ClosingValue"] = strval($element->CLOSINGVALUE);
						$item["\$_ClosingRate"] = strval($element->CLOSINGRATE);
						$item["\$_OpeningBalance"] = strval($element->OPENINGBALANCE);
						$item["\$_OpeningValue"] = strval($element->OPENINGVALUE);
						$item["\$_OpeningRate"] = strval($element->OPENINGRATE);
/*
						$item["\$_ClosingBalance"] = strval($element->OPENINGBALANCE);
						$item["\$_ClosingValue"] = strval($element->OPENINGVALUE);
						$item["\$_ClosingRate"] = strval($element->OPENINGRATE);
*/
						// \$GSTConvUnit, \$GSTItemUnits, \$RateofMRP, \$_LastSalePrice, \$_LastPurcPrice

						if (!empty($item["\$_ClosingRate"]))
						{
							$item["\$_ClosingRate"] = str_replace(array($item["\$BaseUnits"], "/", " "), "", $item["\$_ClosingRate"]);
						}
						if (!empty($item["\$_ClosingBalance"]))
						{
							$item["\$_ClosingBalance"] = str_replace(array($item["\$BaseUnits"], "/", " "), "", $item["\$_ClosingBalance"]);
						}
						if (!empty($item["\$_OpeningRate"]))
						{
							$item["\$_OpeningRate"] = str_replace(array($item["\$BaseUnits"], "/", " "), "", $item["\$_OpeningRate"]);
						}
						if (!empty($item["\$_OpeningBalance"]))
						{
							$item["\$_OpeningBalance"] = str_replace(array($item["\$BaseUnits"], "/", " "), "", $item["\$_OpeningBalance"]);
						}

						$item["\$_LastSalePrice"] = $item["\$_ClosingRate"];
						$item["\$_LastPurcPrice"] = 0;

						unset($element);
						$return[] = $item;
					break;
					case "STOCKGROUP":
						$item = array(
							"name" => $xml->getAttribute("NAME")
						);

						//$element = new SimpleXMLElement($xml->readOuterXML());
						//unset($element);

						$return[] = $item;
					break;
					case "GROUP":
						$item = array(
							"name" => $xml->getAttribute("NAME"),
							"reservedName" => $xml->getAttribute("RESERVEDNAME")
						);

						$element = new SimpleXMLElement($xml->readOuterXML());
						$item["parent"] = strval($element->PARENT);
						unset($element);

						$return[] = $item;
					break;
					case "LEDGER":
						$item = array(
							"\$Name" => $xml->getAttribute("NAME"),
							// "reservedName" => $xml->getAttribute("RESERVEDNAME"),
							"\$Email" => "",
							"\$LedgerContact" => "",
							"\$LedgerMobile" => "",
							"\$LedgerPhone" => "",
							"\$Address" => "",
							"\$_Address1" => "",
							"\$_Address2" => "",
							"\$PANApplicableFrom" => ""
						);

						$element = new SimpleXMLElement($xml->readOuterXML());

						$_parent = strval($element->PARENT);
						if (!empty($parent) && $parent != $_parent)
						{
							break;
						}
						else if ($_parent != "Sundry Debtors" && $_parent != "Sundry Creditors")
						{
							break;
						}
						
						$item["\$PinCode"] = !empty(strval($element->PINCODE))? strval($element->PINCODE) : (isset($element->xpath("LEDMAILINGDETAILS.LIST/PINCODE")[0]) ? strval($element->xpath("LEDMAILINGDETAILS.LIST/PINCODE")[0]): '');
						$item["\$_PrimaryGroup"] = $parent;
						$item["\$StateName"] = !empty(strval($element->STATENAME)) ? strval($element->STATENAME) : (!empty(strval($element->PRIORSTATENAME)) ? strval($element->PRIORSTATENAME) :'');
						$item["\$LedStateName"] = strval($element->LEDSTATENAME);
						$item["\$_ClosingBalance"] = strval($element->OPENINGBALANCE);
						// $item["\$_ClosingBalance"] = strval($element->CLOSINGBALANCE);
						$item["\$PartyGSTIN"] = !empty(strval($element->PARTYGSTIN))? strval($element->PARTYGSTIN) : (isset($element->xpath("LEDGSTREGDETAILS.LIST/GSTIN")[0]) ? strval($element->xpath("LEDGSTREGDETAILS.LIST/GSTIN")[0]): '');
						$item["\$CountryName"] = strval($element->COUNTRYNAME);
						$item["\$GSTRegistrationType"] = strval($element->GSTREGISTRATIONTYPE);
						$item["\$TDSApplicable"] = strtoupper(strval($element->ISTDSAPPLICABLE)) == "NO" ? 0 : 1;

						$child = $element->xpath("ADDRESS.LIST");
						if(empty($child)){
							$child = $element->xpath("LEDMAILINGDETAILS.LIST/ADDRESS.LIST");
						}
						
						if (!empty($child) && $child[0])
						{
							$addr = array_filter((array)$child[0]->ADDRESS);
							if (!empty($addr[0]))
							{
								$item["\$Address"] = rtrim(str_replace(",,", ",", $addr[0]), ",");
								if (!empty($addr[1]))
								{
									$item["\$_Address1"] = rtrim(str_replace(",,", ",", $addr[1]), ",");

									unset($addr[0]);
									unset($addr[1]);

									if (!empty($addr))
									{
										$item["\$_Address2"] = rtrim(str_replace(",,", ",", implode(",", $addr)), ",");
									}
								}
							}

							// $item["\$Address"] = str_replace(",,", ",", implode(",", array_filter((array)$child[0]->ADDRESS)));
						}

						/*
						if ($item["parent"] == "Sundry Debtors" && $item["name"] == "Abirami Eye Hospital,Dindugul")
						{
							print_R($item);exit;
						}
						*/
// print_R($element);
						unset($element);

						$return[] = $item;
					break;
					default:
						$element = new SimpleXMLElement($xml->readOuterXML());
						$return[] = (array)$element;
					break;
				}

// if (count($return)){ break; }
			}

			$xml->close();

			if (!empty($toFile))
			{
				file_put_contents($toFile, json_encode($return, JSON_PRETTY_PRINT));
			}

			return $return;
		}
		catch(Exception $e)
		{
			throw $e;
			// $e->getMessage();
			return false;
		}
	}

	public static function ReplaceInFile($path, $string, $replace)
	{
		set_time_limit(0);

		if (is_file($path) === true)
		{
			$file = fopen($path, 'r');
			$temp = tempnam('./', 'tmp');

			if (is_resource($file) === true)
			{
				while (feof($file) === false)
				{
					$fget = fgets($file, 1024*1024*16); // 1<<24
		            $fget = preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', $replace, $fget);
		            $fget = str_replace($string, $replace, $fget);
		            file_put_contents($temp, $fget, FILE_APPEND);
					// file_put_contents($temp, str_replace($string, $replace, fgets($file)), FILE_APPEND);
				}

				fclose($file);
			}

			unlink($path);
		}

		return rename($temp, $path);
	}
}

// TallyXML::Parse("AllMaster.xml", TallyXML::LEDGER, "AllMaster-LEDGER.json");
// TallyXMLParser::Parse("AllMaster.xml", "CURRENCY", "AllMaster-CURRENCY.json");


