<?php

include_once(dirname(__FILE__).'/../../includes/dbc.php');
include_once(dirname(__FILE__).'/Manage.php');

class ModuleImport extends Module
{
  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Name = 'Import';
    $this->Version = '1.0';
    $this->Creator = 'Chronos';
    $this->License = 'GNU/GPL';
    $this->Description = 'Support for import of data.';
    $this->Dependencies = array('Translation');
  }

  function DoStart(): void
  {
    $this->System->RegisterPage(['import'], 'PageImport');
  }
}

class Import
{
  var $Version;
  var $Group;
  var $NewItemCount;
  var $System;

  function __construct(System $System)
  {
    $this->System = &$System;
  }

  function SetVersion($Version)
  {
    $DbResult = $this->System->Database->query('SELECT * FROM `ClientVersion` WHERE `Version` = "'.$Version.'"');
    $this->Version = $DbResult->fetch_assoc();
  }

  function InsertItem($Value)
  {
    $insert = true;
    $Columns = '';
    //$Values = '';
    foreach ($this->Group['Items'] as $GroupItem)
    {
      $Columns .= ', `'.$GroupItem['Column'].'` ';
     // $Values .= ', "'.$Value[$GroupItem['Column']].'"';
    }
    $Columns = substr($Columns, 1);
    $Where = ' (`'.$this->Group['PrimaryKeyItem'].'` = "'.$Value[$this->Group['PrimaryKeyItem']].'")  AND (`Language`=0) ' ;

    $DbResultMiddle = $this->System->Database->query('SELECT `VersionEnd`,`VersionStart`, `ID`, `Entry`, '.$Columns.' FROM `'.$this->Group['TablePrefix'].'` WHERE '.$Where.' AND `VersionStart` <= '.$this->Version['BuildNumber'].' AND `VersionEnd` >= '.$this->Version['BuildNumber'].' ORDER BY `VersionEnd` DESC LIMIT 1');
    $DbResultBefore = $this->System->Database->query('SELECT `VersionEnd`,`VersionStart`, `ID`, `Entry`, '.$Columns.' FROM `'.$this->Group['TablePrefix'].'` WHERE '.$Where.' AND `VersionEnd` <= '.$this->Version['BuildNumber'].' ORDER BY `VersionEnd` DESC LIMIT 1');
    $DbResultAfter  = $this->System->Database->query('SELECT `VersionEnd`,`VersionStart`, `ID`, `Entry`, '.$Columns.' FROM `'.$this->Group['TablePrefix'].'` WHERE '.$Where.' AND `VersionStart` >= '.$this->Version['BuildNumber'].' ORDER BY `VersionStart` LIMIT 1');

    if (($DbResultMiddle->num_rows > 0) or ($DbResultBefore->num_rows > 0) or ($DbResultAfter->num_rows > 0))
    {
      // Update existed text
      $DbRowMiddle = $DbResultMiddle->fetch_assoc();
      $DbRowAfter = $DbResultAfter->fetch_assoc();
      $DbRowBefore = $DbResultBefore->fetch_assoc();

      if ($this->HaveSameText($this->Group, $DbRowBefore, $Value) and ($DbResultBefore->num_rows > 0))
      {
          $insert = false;
          if ($this->Group['Id'] == 1) 
          {
             $set = ' , EndText = "'.$Value['EndText'].'" , ObjectiveText1 = "'.$Value['ObjectiveText1'].'"'.' , ObjectiveText2 = "'.$Value['ObjectiveText2'].'"'.' , ObjectiveText3 = "'.$Value['ObjectiveText3'].'"'.' , ObjectiveText4 = "'.$Value['ObjectiveText4'].'"';
          } else $set = '';
          $this->System->Database->query('UPDATE `'.$this->Group['TablePrefix'].'` SET `VersionEnd` = "'.$this->Version['BuildNumber'].'" '.$set.' WHERE `ID`='.$DbRowBefore['ID']);
          echo('b ');

      } else
      if ($this->HaveSameText($this->Group, $DbRowAfter, $Value) and ($DbResultAfter->num_rows > 0))
      {
        $insert = false;
        if ($this->Group['Id'] == 1) 
        {
          $set = ' , EndText = "'.$Value['EndText'].'" , ObjectiveText1 = "'.$Value['ObjectiveText1'].'"'.' , ObjectiveText2 = "'.$Value['ObjectiveText2'].'"'.' , ObjectiveText3 = "'.$Value['ObjectiveText3'].'"'.' , ObjectiveText4 = "'.$Value['ObjectiveText4'].'"';
        } else $set = '';
        $this->System->Database->query('UPDATE `'.$this->Group['TablePrefix'].'` SET `VersionStart` = "'.$this->Version['BuildNumber'].'" '.$set.' WHERE `ID`='.$DbRowAfter['ID']);
        echo('a ');
      } else
      {
        if (isset($DbRowAfter['VersionStart'])) 
        {
          if ($DbRowAfter['VersionStart'] <= $this->Version['BuildNumber']) 
          {
            echo('Allready imported '.$DbRowBefore['Entry'].' ');
            $insert = false;
          }
        }
        if (isset($DbRowBefore['VersionEnd'])) 
        {
          if ($DbRowBefore['VersionEnd'] >= $this->Version['BuildNumber']) 
          {
            echo('Allready imported '.$DbRowBefore['Entry'].' ');
            $inserted = false;
          }
        }

        // if [DEPRECATED] do not import
        foreach ($this->Group['Items'] as $GroupItem) 
        {
          if (false !== strpos($Value[$GroupItem['Column']],'[DEPRECATED')) 
          {
            echo('d '.$DbRowBefore['Entry'].' ');
            $insert = false;
          }
        }

        if ($insert) 
        {
          $insert = false;
          foreach ($this->Group['Items'] as $GroupItem)
          {
            if ($Value[$GroupItem['Column']] <> '') $insert = true;
          }
        }

        if (isset($DbRowMiddle['Entry'])) $insert = false;
        if (isset($DbRowAfter['Entry'])) $Value['Entry'] = $DbRowAfter['Entry'];
        if (isset($DbRowBefore['Entry'])) $Value['Entry'] = $DbRowBefore['Entry'];

        if ($insert)
        {
          $Columns = '`Entry`, `Language`, `VersionStart`, `VersionEnd`';
          $Values = $Value['Entry'].', 0, '.$this->Version['BuildNumber'].', '.$this->Version['BuildNumber'];
          foreach ($this->Group['Items'] as $GroupItem)
          {
            $Columns .= ', `'.$GroupItem['Column'].'`';
            $Values .= ', "'.$Value[$GroupItem['Column']].'"';
          }
          $this->System->Database->query('INSERT `'.$this->Group['TablePrefix'].'` ('.$Columns.') VALUES ('.$Values.')');

          echo('
          '.$Value['Entry'].' = '.$DbRowBefore['VersionStart'].'.'.$DbRowBefore['VersionEnd'].'< '.$this->Version['BuildNumber'].' <'.$DbRowAfter['VersionStart'].'.'.$DbRowAfter['VersionEnd'].'... '.$DbRowMiddle['VersionStart'].' '.$DbRowMiddle['VersionEnd'].'
          ');

          if (false !== strpos($Values,'[DEPRECATED'))
          echo($Values);

          echo('# ');
          $InsertId = $this->System->Database->insert_id;
          $this->System->ModuleManager->Modules['Log']->WriteLog('Text <a href="form.php?group='.$this->Group['Id'].'&amp;ID='.$InsertId.'">'.$InsertId.'</a> ('.$Value['Entry'].') ze skupiny '.$this->Group['Name'].' byl v nové verzi '.$this->Version['Version'].' změněn.', LOG_TYPE_IMPORT);
        }
      }
    } else
    {
      // Insert new text
      if (is_numeric($Value[$this->Group['PrimaryKeyItem']])) $Value['Entry'] = $Value[$this->Group['PrimaryKeyItem']];
      else
      {
        // Get new unused Entry for tables without numeric id
        $Value['Entry'] = 1;
        $DbResult = $this->System->Database->query('SELECT MAX(`Entry`) FROM `'.$this->Group['TablePrefix'].'`');
        if ($DbResult->num_rows > 0)
        {
          $DbRow = $DbResult->fetch_row();
          $Value['Entry'] += $DbRow[0];
        }
      }
      $Columns = '`Entry`, `Language`, `VersionStart`, `VersionEnd`';
      $Values = $Value['Entry'].', 0, '.$this->Version['BuildNumber'].', '.$this->Version['BuildNumber'];
      $insert = false;
      foreach ($this->Group['Items'] as $GroupItem)
      {
        $Columns .= ', `'.$GroupItem['Column'].'`';
        $Values .= ', "'.$Value[$GroupItem['Column']].'"';
        if ($Value[$GroupItem['Column']] <> '') $insert = true;
      }
      if ($insert) 
      {
        $this->System->Database->query('INSERT `'.$this->Group['TablePrefix'].'` ('.$Columns.') VALUES ('.$Values.')');
        $InsertId = $this->System->Database->insert_id;
        echo('+ ');
        $this->NewItemCount++;
        $this->System->ModuleManager->Modules['Log']->WriteLog('Text <a href="form.php?group='.$this->Group['Id'].'&amp;ID='.$InsertId.'">'.$InsertId.'</a> ('.$Value['Entry'].') ze skupiny '.$this->Group['Name'].' byl v nové verzi '.$this->Version['Version'].' přidán.', LOG_TYPE_IMPORT);
      }
    }
  }

  function ImportLUA()
  {
    $Output = 'Načítání textů z LUA souboru...';

    if (($this->Group['LuaFileName'] != '') and ($this->Group['TablePrefix'] != ''))
    {
      $Output .= '<br />'.$this->Group['Name'].'<br />';
      //  if ($this->Group['LastVersion'] < $this->Version['BuildNumber'] + 1)
      {
        $File = new FileStream();

        $File->OpenFile(dirname(__FILE__).'/../../source/'.$this->Version['Version'].'/lua/'.$this->Group['LuaFileName'].'.lua');
        $this->NewItemCount = 0;
        $Count = 0;
        while (!$File->EOF())
        {
          $Line = $File->ReadLine();
          if (strpos($Line, '=') !== false)
          {
            $LineParts = explode('=', $Line, 2);
            $Value['ShortCut'] = trim($LineParts[0]);
            $Line = trim($LineParts[1]);
            if ($Line[0] == '"')
            {
              // Quoted string value
              $Line = substr($Line, 1); // Skip start qoute
              $TempLine = str_replace('\"', '  ', $Line); // Temporary remove slashed quotes
              $Value['Text'] = substr($Line, 0, strpos($TempLine, '"'));
              $Value['Text'] = str_replace('\n', "\n", $Value['Text']);
              $Value['Text'] = addslashes(stripslashes($Value['Text']));
              $Line = trim(substr($Line, strpos($TempLine, '"') + 1)); // Skip closing quote and semicolon
            } else
            {
              // Nonstring value
              $Value['Text'] = substr($Line, 0, strpos($Line, ';'));
            }
            $Line = substr($Line, strpos($Line, ';') + 1);
            $Value['Comment'] = addslashes(stripslashes(substr($Line, 3))); // Skip " --"

            $this->InsertItem($Value);
          };
          $Count++;
        }
        $Output .= '<br />Celkem: '.$Count.'  Nových: '.$this->NewItemCount.'<br />';
        $this->UpdateLastVersion();
      }
      // else $Output .= ShowMessage('Již importován pro verzi '.$this->Version['Version'], MESSAGE_CRITICAL);
    } else $Output .= ShowMessage('Není definováno jméno zdrojového souboru', MESSAGE_CRITICAL);
    $Output .= ShowMessage('Dokončeno.');
    return $Output;
  }

  function UpdateTranslated()
  {
    $TranslationTree = $this->System->ModuleManager->Modules['Translation']->GetTranslationTree();
    $Output = '<br /><br />Začínám se synchronizací VersionEnd u přeložených textů<br />';
    foreach ($TranslationTree as $Group)
    {
      $Output .= '<br />'.$Group['Name'].' ';
      $do = true;
      while ($do)
      {
        $DbResult = $this->System->Database->query('SELECT `gs_tran`.`ID`, '.
          '`gs_tran`.`VersionEnd` AS `VersionEnd_tran`, '.
          '`gs_tran`.`VersionStart` AS `VersionStart_tran`, '.
          '`gs_orig`.`VersionEnd` AS `VersionEnd_orig`, '.
          '`gs_orig`.`VersionStart` AS `VersionStart_orig` FROM `'.
        $Group['TablePrefix'].'` AS `gs_tran` JOIN `'.$Group['TablePrefix'].
          '` AS `gs_orig` ON `gs_orig`.`ID` = `gs_tran`.`Take` WHERE '.
          '`gs_tran`.`VersionEnd` <> `gs_orig`.`VersionEnd` OR `gs_tran`.`VersionStart` <> `gs_orig`.`VersionStart`');
        $do = ($DbResult->num_rows > 0);
        while ($DbRow = $DbResult->fetch_assoc())
        {
          echo('`');
          $this->System->Database->query('UPDATE `'.$Group['TablePrefix'].'` SET `VersionEnd` = '.$DbRow['VersionEnd_orig'].', `VersionStart` = '.$DbRow['VersionStart_orig'].' WHERE `ID` = '.$DbRow['ID']);
          $Output .= '. ';
        }
      }
      $Output .= '<strong>Dokončeno.</strong>';
    }
    return $Output;
  }

  function HaveSameText($Group, $DbRow2, $Value)
  {
    $result = true;
    foreach ($Group['Items'] as $GroupItem)
    {
      $old = $DbRow2[$GroupItem['Column']];
      $old = str_replace(chr(10), '', $old);
      $old = str_replace(chr(13), '', $old);
      $old = str_replace('\n', '', $old);
      $old = str_replace('\r', '', $old);
      $old = str_replace('\"', '"', $old);
      $old = str_replace('\\\\', '\\', $old);
      $old = str_replace('\32', '32', $old);
      $old = str_replace('\124', '124', $old);
      $old = str_replace("\'", "'", $old);
      $old = str_replace("Â", "", $old);
      $old = str_replace("�", "", $old);
      $old = str_replace('-', '', $old);
      $old = str_replace(' ', '', $old);
      $old = strtolower($old);
      $old = str_replace('$b', '', $old);

      if ($this->Group['Id'] == 1)
      {
        while ($part = substr($old, strpos($old, '<'), strpos($old, '>')-strpos($old, '<')))
        {
          if ($part <> '') 
          {
            $old = str_replace($part.'>', '', $old);
          }
        }
      }

      if (($GroupItem['MangosColumn'] <> '') and ($Group['MangosDatabase'] == 'mangos'))
        $new = $Value[$GroupItem['MangosColumn']];
        else $new = $Value[$GroupItem['Column']];

      $new = str_replace(chr(10), '', $new);
      $new = str_replace(chr(13), '', $new);
      $new = str_replace('\n', '', $new);
      $new = str_replace('\r', '', $new);
      $new = str_replace('\"', '"', $new);
      $new = str_replace('\\\\', '\\', $new);
      $new = str_replace('\32', '32', $new);
      $new = str_replace('\124', '124', $new);
      $new = str_replace("\'", "'", $new);
      $new = str_replace("Â", "", $new);
      $new = str_replace("�", "", $new);
      $new = str_replace('-', '', $new);
      $new = str_replace(' ', '', $new);
      $new = strtolower($new);
      $new = str_replace('$b', '', $new);

      if ($this->Group['Id'] == 1)
      {
        while ($part = substr($new, strpos($new, '<'), strpos($new, '>')-strpos($new, '<')))
        {
          if ($part <> '') 
          {
            $new = str_replace($part.'>', '', $new);
          }
        }
      }

      if (($old == 'null') or ($old == 'NULL')) $old = '';
      if (($new == 'null') or ($new == 'NULL')) $new = '';

      if (($new <> '') and ($old <> $new) and ($GroupItem['Column'] <> 'Comment'))
      {
        //  echo $old.'X'.$new;
        if ( ($GroupItem['Column'] <> 'EndText')
        and ($GroupItem['Column'] <> 'ObjectiveText1')
        and ($GroupItem['Column'] <> 'ObjectiveText2')
        and ($GroupItem['Column'] <> 'ObjectiveText3')
        and ($GroupItem['Column'] <> 'ObjectiveText4') )
          $result = false;
      }
    }

    return $result;
  }

  function ImportDBC()
  {
    global $System;

    $Output = 'Načítání textů z DBC souboru...';
    if (($this->Group['DBCFileName'] != '') and ($this->Group['TablePrefix'] != ''))
    {
      $Output .= '<br />'.$this->Group['Name'].'<br />';

      // Load string column index list
      $DbResult = $System->Database->query('SELECT * FROM `GroupItem` JOIN `GroupItemDBC` ON `GroupItem`.`Id` = `GroupItemDBC`.`GroupItem` AND `GroupItemDBC`.`ClientVersion` = '.$this->Version['Id'].'  WHERE `GroupItem`.`Group` = '.$this->Group['Id']);

      $ColumnIndexes = array();
      $ColumnFormat = array();
      while ($DbRow = $DbResult->fetch_assoc())
      {
        $ColumnFormat[$DbRow['ColumnIndex']] = FORMAT_STRING;
        $ColumnIndexes[$DbRow['GroupItem']] = $DbRow['ColumnIndex'];
      }

      $DBCFile = new DBCFile();
      $DBCFile->OpenFile(dirname(__FILE__).'/../../source/'.$this->Version['Version'].'/dbc/'.$this->Group['DBCFileName'].'.dbc', $ColumnFormat);
      $ItemCount = $DBCFile->GetRecordCount();
      $this->NewItemCount = 0;
      $Count = 0;

      for ($I = 0; $I < $ItemCount; $I++)
      {
        foreach ($this->Group['Items'] as $GroupItem)
        if (array_key_exists($GroupItem['Id'], $ColumnIndexes))
        {
          $Value[$GroupItem['Column']] = addslashes($DBCFile->GetString($I, $ColumnIndexes[$GroupItem['Id']]));
        }

        // Get multicolumn value
        $Columns = explode(',', $this->Group['DBCIndex']);
        $ColumnValue = '';
        foreach ($Columns as $Column)
        {
          $ColumnValue .= '_'.$DBCFile->GetUint($I, $Column);
        }
        $ColumnValue = substr($ColumnValue, 1);
        $Value[$this->Group['PrimaryKeyItem']] = $ColumnValue;
        $this->InsertItem($Value);
        $Count++;
      }
      $Output .= '<br />Celkem: '.$Count.'  Nových: '.$this->NewItemCount.'<br />';
      $this->UpdateLastVersion();
    }
    $Output .= '<strong>Dokončeno.</strong>';
    return $Output;
  }

  function ImportGroup($GroupId)
  {
    $TranslationTree = $this->System->ModuleManager->Modules['Translation']->GetTranslationTree();

    $this->Group = $TranslationTree[$GroupId];

    if ($this->Group['SourceType'] == 'dbc') $Output = $this->ImportDBC();
    else if ($this->Group['SourceType'] == 'sql') $Output = $this->ImportSQL();
    else if ($this->Group['SourceType'] == 'lua') $Output = $this->ImportLUA();
    else $Output = ShowMessage('Neznámý typ zdroje pro import', MESSAGE_CRITICAL);
    $Output .= $this->UpdateTranslated();
    return $Output;
  }

  function ImportSQL()
  {
    $Output = '';
    $File = new FileStream();
    $File->OpenFile(dirname(__FILE__).'/../../source/'.$this->Version['Version'].'/sql/'.$this->Group['MangosTable'].'.sql');
    $this->NewItemCount = 0;
    $Count = 0;
    $FollowStructure = false;
    $i = 0;
    while ((!$File->EOF()))
    {
      $Line = $File->ReadLine();
      // Struktura
      if (strpos($Line, 'CREATE TABLE `'.$this->Group['MangosTable'].'`') !== false)
      {
        $Line = '';
        $FollowStructure = true;
        $i = 0;
      }
      if ((strpos($Line, ';') !== false) and ($FollowStructure == true))
      {
        $FollowStructure = false;
      }
      if (($FollowStructure == true) and ($Line != ''))
      {
        $str = substr($Line, 0, strpos($Line, '`'));
        $Line = substr($Line, strpos($Line, '`') + 1);
        $Line = substr($Line, 0, strpos($Line, '`'));
        if (strlen($str) < 3) $structure[$i] = $Line;
        $i++;
      }

      // data
      if ((strpos($Line, 'INSERT INTO `'.$this->Group['MangosTable'].'`') !== false) and (isset($structure)))
      {
        while ((strpos($Line, ');') === false) or ($File->EOF()))
          $Line = $Line.$File->ReadLine();
        $Line = str_replace("),\n(", '),(', $Line);

        $Line = substr($Line, strpos($Line, '(') + 1);
        $Line = substr($Line, 0, strpos($Line, ');'));
        $LineParts = explode('),(', $Line);

        unset($Line);

        $value_buff = '';
        $Value = '';
        foreach ($LineParts as $LinePart)
        {

          unset($Value, $value_buff);
          foreach ($structure as $i => $column)
          {
            if (substr($LinePart, 0, 1) != "'")
            {
              $value_buff = substr($LinePart, 0, strpos($LinePart, ','));
              $LinePart = substr($LinePart, strlen($value_buff) + 1);
            } else
            {
              $LinePart = substr($LinePart, 1);
              $value_buff = substr($LinePart, 0, strpos($LinePart, "'"));
              while (substr($value_buff, strlen($value_buff) - 1, 1) == "\\")
              {
                $str = substr($LinePart, strlen($value_buff));
                $str2 = substr($str, 0, strpos($str, "'", 1));
                $value_buff = $value_buff.$str2;
                $str = substr($str, strlen($str2));
              }
              $LinePart = substr($LinePart, strlen($value_buff) + 2);
            }
            if (($value_buff != 'null') and ($value_buff != 'NULL'))
            {
              $str = '';
              while (substr($value_buff, strlen($value_buff) - 1,1) == " ")
              {
                $value_buff = substr($value_buff, 0, strlen($value_buff) - 1);
                $str .= ' ';
              }
              $str2 = '';
              while (substr($value_buff, 0, 1) == ' ')
              {
                $value_buff = substr($value_buff, 1, strlen($value_buff) - 1);
                $str2 .= ' ';
              }
              $Value[$column] = $str2.trim($value_buff).$str;
            } else
            {
              $Value[$column] = '';
            }
          }
          foreach ($this->Group['Items'] as $GroupItem)
          {
            if ($GroupItem['MangosColumn'] != '')
            {
              if (isset($Value[$GroupItem['MangosColumn']]))
              {
                $Value[$GroupItem['Column']] = $Value[$GroupItem['MangosColumn']];
              }
              else 
              {
                $Value[$GroupItem['Column']] = '';
                $Value[$GroupItem['MangosColumn']] ='';
              }
            }
          }

          // Get multicolumn value
          $Columns = explode(',', $this->Group['MangosTableIndex']);
          $ColumnValue = '';
          foreach ($Columns as $Column)
          {
            $ColumnValue .= '_'.$Value[$Column];
          }
          $ColumnValue = substr($ColumnValue, 1);
          $Value[$this->Group['PrimaryKeyItem']] = $ColumnValue;
          $this->InsertItem($Value);
          $Count++;
        }
      }
    }
    $Output = '<br />Celkem: '.$Count.'  Nových: '.$this->NewItemCount.'<br />';
    $this->UpdateLastVersion();
    return $Output;
  }

  function UpdateLastVersion() 
  {
    $DbResult = $this->System->Database->query('SELECT * FROM `Group` WHERE `Id`='.$this->Group['Id']);
    $Version = $DbResult->fetch_assoc();
    if ($Version['LastVersion'] < $this->Version['BuildNumber'])
      $this->System->Database->query('UPDATE `Group` SET `LastVersion` = "'.$this->Version['BuildNumber'].'", `LastImport` = NOW() WHERE `Id`='.$this->Group['Id']);
  }
}