<?php
/* Demonstration of available options on the qrCode() command */
// require __DIR__ . '/../autoload.php';
require 'autoload.php';

use Mike42\Escpos\Printer;
// use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;

// $connector = new FilePrintConnector("php://stdout");
$connector = new WindowsPrintConnector("EPSON TM-T20 Receipt");
$printer   = new Printer($connector);

class NfcCodePrint{
  private $p_chars_line = 64;

  // Cabeçalho do Cupom
  private $ds_fantasia = '';
  private $ds_razao    = '';
  private $ds_endereco = '';
  private $ds_cidade   = '';
  private $ds_estado   = '';

  private $ds_emissor_cnpj ='';
  private $ds_emissor_ie   ='';
  private $ds_emissor_im   ='';
  private $nr_extrato_venda='';

  // informações do consumidor
  private $ds_dest_doc ='';
  private $ds_dest_nome='';

  // array com os produtos
  private $p_itens_prod = array();

  // rodapé do Cupom
  private $vl_total_cfe = '0.00';
  private $ds_forma_pgto= 'DINHEIRO';
  private $vl_pago_forma= '0.00';
  private $vl_troco     = '0.00';

  // $p_pgto_prod = array();
  private $dt_cfe = '';
  private $cd_loja= '';
  private $nr_caixa='';
  private $ds_nome_operador='';
  private $nr_cupom_venda= '';
  private $ds_info_adic  = '';

  private $nr_serie_sat = '';
  private $ts_cfe = '';

  private $ds_chave  = '';
  private $ds_qrcode = "VQG7EUMQD9vcXQxOFxBhBaESsJVPB95VBtXOkquE2eZCcTLzbIfAqGsFawlD2t/Il3JbGwZVcbNLKmF1sU9fxHhJDzkuaR+wjH+QQ9yb9HEZ2MbLs5ni1LBy4+k2xFibiWB5Frh8QJ44iZYHeMNf610Fg3lYsaVo5WjyWA53Y5a00CSxWYwG82pLxyUPNfvJ5tGcG43xZIfykJmHzpllk17yP+dYke6ZaOcunWgRihs+yYXsGc+DKQNoQ9BX+O4odXbBbKmXjmDs4GYMZy4PhHpFt/XJJNZK9jkmx7b6jlh2E2J0FTMy3knfb/H/rbLPIcnYEWg/93m5Qoqk5EtqIA==";

  private $ds_versao_sw = '';
  private $ds_assinatura_MD5 = '';

  // métodos mágicos get e set
  public function __set($atrib, $value){
    $this->$atrib = $value;
  }

  /*
  public function __get($atrib){
    return $this->$atrib;
  }*/


  // faz a montagem para o cupom
  function montarCupom(){

    $this->setCenterText($this->ds_fantasia);
    $this->setCenterText($this->ds_razao);
    $this->setCenterText($this->ds_endereco);
    $this->setCenterText($this->ds_cidade . "-" . $this->ds_estado);

    $info_emissor = 'CNPJ ' . $this->ds_emissor_cnpj . ' IE ' . $this->ds_emissor_ie . ' IM ' . $this->ds_emissor_im;
    $this->setCenterText($info_emissor);
    $this->setLinhaTracejada();

    $ds_extrato_venda = 'Extrato Nro. { á definir}' . $this->nr_extrato_venda;
    $this->setCenterTextBold($ds_extrato_venda, 1, 1);
    $this->setCenterTextBold("CUPOM FISCAL ELETRÔNICO - SAT", 1, 2);
    $this->setLinhaTracejada();

    $this->setLeftText("CPF/CNPJ do Consumidor: " . $this->ds_dest_doc);
    $this->setLeftText("Razão Social / Nome: " . $this->ds_dest_nome );
    $this->setLinhaTracejada();

    /*
    criar um array com a seguinte estrutura dentro de outro item 'pro'
    Array
    (
        [cProd] => 1
        [xProd] => TANG MARACUJA
        [NCM] => 21060910
        [CFOP] => 5102
        [uCom] => UN
        [qCom] => 1.0000
        [vUnCom] => 2.00
        [vProd] => 2.00
        [indRegra] => A
        [vItem] => 2.00
    )
    */
    $array_itens_prod = $this->p_itens_prod;

    $ds_titulo_itens = '# | COD | DESC | QTD | UN | VL UN R$ |VL ITEM R$';
    $this->setLeftText($ds_titulo_itens);
    $this->setLinhaTracejada();

    // foreach ($array_itens_prod as $key => $array_item) {
    for ($i=0; $i < count($array_itens_prod) ; $i++) {
      $p_item = (array)$array_itens_prod[$i]['prod'];

      // dados do produto
      $nr_item = $i +1;
      $ds_info_produto  = substr("000$nr_item", -3);
      $ds_info_produto .= " " . substr("00000000000000" . $p_item['cProd'], -14);
      $ds_info_produto .= " " . $p_item['xProd'] . " ";

      // dados da venda do item
      $ds_item_valores  = " " . $p_item['qCom'];
      $ds_item_valores .= " " . $p_item['uCom'];
      $ds_item_valores .= " X ". $p_item['vUnCom'];
      $ds_item_valores .= " " . $p_item['vProd'];

      // se tamanho da linha maior de $p_chars_line 64 caracteres, quebra linha
      if(strlen($ds_info_produto . $ds_item_valores)>$this->p_chars_line){
        $this->setLeftText(substr($ds_info_produto, 0, $this->p_chars_line));
        $this->setRigthText($ds_item_valores);
      }else{
        $linha_item = $this->setStringCharsLine($ds_info_produto, $ds_item_valores);
        $this->setCenterText($linha_item);
      }
    }

    $linha_total = $this->setStringCharsLine("TOTAL R$ ", $this->vl_total_cfe);
    $this->setCenterTextBold($linha_total, 1, 2 );
    $vl_troco = $this->vl_total_cfe;

    /*
    echo "<br>INFO " . $p_item['xProd'];
    echo "<br>ITEM $ds_item_valores";

    $p_pgto_prod = array((array)$this->p_pgto_prod);

    echo "<pre>";
    print_r($array_pagto);
    echo "</pre>";
    exit;
    */

    $array_pagto = $this->p_pgto_prod;
    // se houve mais de uma forma de pagamento, faz loop
    foreach ($array_pagto as $key => $value) {

        $cd_forma_pgto = $value['cMP'];
        $vl_pago_forma = $value['vMP'];

        $ds_forma_pgto = $this->getDescricaoMP( $cd_forma_pgto);

        $linha_pgto = $this->setStringCharsLine($ds_forma_pgto, $vl_pago_forma);
        $this->setCenterText($linha_pgto, 1, 1 );
        $vl_troco -= $vl_pago_forma;
      }

      $vl_troco = number_format($vl_troco, 2, ',', ' ');

      $linha_troco = $this->setStringCharsLine("Troco R$ ", $vl_troco);
      $this->setCenterText($linha_troco);
      $this->setLinhaTracejada();

      $this->setCenterTextBold("OBSERVAÇÕES DO CONTRIBUINTE", 1, 1);
      $ds_emissor_obs = "DataMov: " . date("d-m-Y", strtotime($this->ts_cfe)) . " Loja: " . substr("0000" . $this->cd_loja, -4) . " Terminal: " . $this->nr_caixa . " N.Cupom : " . $this->nr_cupom_venda;
      $this->setCenterText($ds_emissor_obs);
      $this->setLinhaTracejada();

      $this->setCenterText($this->ds_emissor_obs);
      $this->setLeftText($this->ds_info_adic);

      $this->setCenterTextBold("SAT No." . $this->nr_serie_sat, 1, 1);

      $this->setCenterText($this->ts_cfe);
      // $this->setCenterTextBold($this->ds_chave, 1, 1);
      $this->setCodigoBarras();

      // qr_code do cupom fiscal
      // estrutura chaveConsulta|timeStamp|valorTotal|CPFCNPJValue|assinaturaQRCODE
      $p_qr_code = $this->ds_chave . "|" . $this->ts_cfe . "|" . $this->vl_total_cfe . "|" . $this->ds_dest_doc . "|" . $this->ds_qrcode;
      $this->setQrCode($p_qr_code);

      // rodapé do Cfe, informações de Versão do SW
      $this->setLinhaTracejada();
      $this->setLeftText("MD-5: " . $this->ds_assinatura_MD5);
      $info_loja = "PDV:" . $this->nr_caixa .
                   " LJ:" . substr("0000" . $this->cd_loja, -4) .
                   " COO:" . $this->nr_cupom_venda .
                   " Operador:" . $this->id_operador . " " . $this->ds_nome_operador;
      $info_loja = $this->setStringCharsLine($info_loja,"");
      $this->setLeftText($info_loja);
      $this->setLeftText($this->ds_versao_sw);
  }

  // retorna o objecto como texto
  public function toString(){
    $st_ret = $printer->getPrintBuffer();
    return $st_ret;
  }

  // imprime diretamente para impressora
  public function imprimir(){
    global $printer;
    // $this->montarCupom();

    $printer-> cut();
    $printer-> close();

    return true;
  }


  function getDescricaoMP($cd_mp){
    $ds_ret = 'Dinheiro';
    switch ($cd_mp) {
        case '01':
            $ds_ret = 'Dinheiro';
            break;
        case '02':
            $ds_ret = 'Cheque';
            break;
        case '03':
            $ds_ret = 'Cartão de Crédito';
            break;
        case '04':
            $ds_ret = 'Cartão de Débito';
            break;
        case '05':
            $ds_ret = 'Crédito Loja';
            break;
        case '10':
            $ds_ret = 'Vale Alimentação';
            break;
        case '11':
            $ds_ret = 'Vale Refeição';
            break;
        case '12':
            $ds_ret = 'Vale Presente';
            break;
        case '13':
            $ds_ret = 'Vale Combustível';
            break;
        case '99':
            $ds_ret = 'Vale Combustível';
            break;
        }
    return $ds_ret;
  }

  // linha tracejada para divisão de sessões
  function setLinhaTracejada(){
    $texto = "-";
    $ds_print = str_pad($texto, $this->p_chars_line, "-");
    $this->setLeftText($ds_print);
  }

  // acrescenta espacos para justificar o texto
  function setStringCharsLine($texto1, $texto2){
    $nr_char = $this->p_chars_line - strlen($texto2);

    $ds_ret = str_pad($texto1, $nr_char);
    $ds_ret.= $texto2;
    return $ds_ret;
  }

  function setCodigoBarras(){
    global $printer;

    /*
    $printer->selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH);
    $printer->selectPrintMode(Printer::BARCODE_CODE128);
    $printer->text($standard ["title"] . "\n");
    $printer->setEmphasis(true);
    $printer->text("Content: " . $barcode ["content"] . "\n");
    $printer->barcode($barcode ["content"], $type);
    $printer->barcode($barcode ["content"]);
    $printer->feed();*/
    $chave_clear = substr($this->ds_chave, -44);
    $chave_clear = $this->setStringBarra($chave_clear);

    echo "<br>$chave_clear";


    $printer->selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH);
    // $printer->setEmphasis(true);
    // $printer->text($chave_clear . "\n");
    $printer->setEmphasis(false);

    // $barcode = "{C" . chr(21) . chr(32) . chr(43) . $chave_clear;
    // $barcode = "{C" . substr($chave_clear, 0, 4) . chr(32) . substr($chave_clear, 5, 4);
    $barcode = "{C" . $chave_clear;

    $printer->setBarcodeHeight(64);
    $printer->setBarcodeWidth(4);
    $printer->text($barcode . "\n");
    // $printer->barcode($barcode ["content"], $type);
    $printer->barcode($barcode, Printer::BARCODE_CODE128);
    $printer->feed();
  }

  function setStringBarra($p_string){
    $p_return = '';
    for ($i=0; $i <= strlen($p_string); $i += 4) {
      $p_return .= substr($p_string, $i, 4) . chr(32);
    }
    return $p_return;
  }

  function setQrCode($p_qr_code){
    global $printer;
    $printer -> setJustification(1);
    $printer -> qrCode($p_qr_code, Printer::QR_MODEL_2);
    // $printer -> text("Most simple example\n");
    $printer -> feed();
  }

  function setLeftText($value){
    echo "<br>" . $value;
    global $printer;

    $printer->setJustification(0);
    // $printer -> qrCode($testStr);
    $printer -> setFont(2);
    $printer -> selectPrintMode(1);
    $printer -> setTextSize( 1, 1);
    $printer -> text($value);
    $printer -> setJustification();
    $printer -> feed();
  }

  function setRigthText($value){
    echo "<br>" . $value;
    global $printer;

    $printer->setJustification(2);
    // $printer -> qrCode($testStr);
    $printer -> setFont(2);
    $printer -> selectPrintMode(1);
    $printer -> setTextSize( 1, 1);
    $printer -> text($value);
    $printer -> setJustification();
    $printer -> feed();
  }

  function setCenterText($value){
    echo "<br>" . $value;
    global $printer;

    $printer->setJustification(1);
    $printer->selectPrintMode(1);
    // $printer -> qrCode($testStr);
    $printer -> setFont(2);
    $printer -> setTextSize( 1, 1);
    $printer -> text($value);
    $printer -> setJustification();
    $printer -> feed();
  }

  function setCenterTextBold($value, $p_width, $p_heigth){
    echo "<br>" . $value;
    global $printer;

    $printer -> setJustification(1);
    $printer -> selectPrintMode(40);
    // $printer -> qrCode($testStr);
    $printer -> setFont(1);
    $printer -> setEmphasis(true);
    $printer -> setTextSize($p_width, $p_heigth);
    $printer -> text($value);
    $printer -> setJustification();
    $printer -> feed();
  }

  function title(Printer $printer, $str){
      $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH);
      $printer -> text($str);
      $printer -> selectPrintMode();
  }
}



/*

// Most simple example
// title($printer, "QR code demo\n");

/* $testStr = "Testing 123";
$printer -> qrCode($testStr);
$printer -> text("Most simple example\n");
$printer -> feed();

// Demo of numeric data being packed more densly
title($printer, "Data encoding\n");
$test = array(
    "Numeric"      => "0123456789012345678901234567890123456789",
    "Alphanumeric" => "abcdefghijklmnopqrstuvwxyzabcdefghijklmn",
    "Binary"       => str_repeat("\0", 40));
foreach ($test as $type => $data) {
    $printer -> qrCode($data);
    $printer -> text("$type\n");
    $printer -> feed();
}

// Demo of error correction
title($printer, "Error correction\n");
$ec = array(
    Printer::QR_ECLEVEL_L => "L",
    Printer::QR_ECLEVEL_M => "M",
    Printer::QR_ECLEVEL_Q => "Q",
    Printer::QR_ECLEVEL_H => "H");
foreach ($ec as $level => $name) {
    $printer -> qrCode($testStr, $level);
    $printer -> text("Error correction $name\n");
    $printer -> feed();
}

// Change size
title($printer, "Pixel size\n");
$sizes = array(
    1 => "(minimum)",
    2 => "",
    3 => "(default)",
    4 => "",
    5 => "",
    10 => "",
    16 => "(maximum)");
foreach ($sizes as $size => $label) {
    $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, $size);
    $printer -> text("Pixel size $size $label\n");
    $printer -> feed();
}

// Change model
title($printer, "QR model\n");
$models = array(
    Printer::QR_MODEL_1 => "QR Model 1",
    Printer::QR_MODEL_2 => "QR Model 2 (default)",
    Printer::QR_MICRO => "Micro QR code\n(not supported on all printers)");
foreach ($models as $model => $name) {
    $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, 3, $model);
    $printer -> text("$name\n");
    $printer -> feed();
}
*/
