<?php
/*******************************************************************************

    Copyright 2014 Whole Foods Co-op

    This file is part of IT CORE.

    IT CORE is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    IT CORE is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    in the file license.txt along with IT CORE; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*********************************************************************************/

class GumCheckTemplate 
{
    private $check_number;
    private $amount;
    private $amount_as_words;
    private $check_date;
    private $memo;
    private $my_address = array();
    private $their_address = array();
    private $bank_address = array(
        'Members Cooperative',
        'Credit Union',
        '215 N 40th Ave West',
        'Duluth, MN 55807',
    );

    private $routing_no = 'xxxxxxxxxx';
    private $checking_no = 'yyyyyyyyyyyy';

    const POSITION_BOTTOM = 1;
    const POSITION_TRI_1 = 2;
    const POSITION_TRI_2 = 3;
    const POSITION_TRI_3 = 4;
    private $position = 1;
    private $micrShift = false;

    public function setPosition($p)
    {
        $this->position = $p;
    }

    public function shiftMICR($m)
    {
        $this->micrShift = true;
    }

    public function addBankLine($line)
    {
        $this->bank_address[] = $line;
    }
    
    public function __construct($custdata, $meminfo, $amount, $memo='', $check_number=false, $date=false)
    {
        global $FANNIE_PLUGIN_SETTINGS;
        $dbc = FannieDB::get($FANNIE_PLUGIN_SETTINGS['GiveUsMoneyDB']);
        $settings = new GumSettingsModel($dbc);

        if (!$date) {
            $this->check_date = date('m/d/Y');
        } else {
            $this->check_date = $date;
        }

        $this->memo = $memo;
        $this->check_number = $check_number;

        $this->amount = $amount;
        $dollars = floor($amount);
        $cents = round(($amount - $dollars) * 100);
        $nf = new NumberFormatter('en_US', NumberFormatter::SPELLOUT);
        $this->amount_as_words = ucwords($nf->format($dollars)) . ' And ' . str_pad($cents, 2, '0', STR_PAD_LEFT) . '/100';

        $this->their_address[] = $custdata->FirstName() . ' ' . $custdata->LastName();
        if (strstr($meminfo->street(), "\n")) {
            foreach (explode("\n", $meminfo->street()) as $line) {
                $this->their_address[] = $line;
            }
        } else {
            $this->their_address[] = $meminfo->street();
        }
        $this->their_address[] = $meminfo->city() . ', ' . $meminfo->state() . ' ' . $meminfo->zip();

        $settings->key('routingNo');
        if ($settings->load()) {
            $this->routing_no = $settings->value();
        }
        $settings->key('checkingNo');
        if ($settings->load()) {
            $this->checking_no = $settings->value();
        }

        $this->my_address[0] = 'Name of Co-op';
        $settings->key('storeName');
        if ($settings->load()) {
            $this->my_address[0] = $settings->value();
        }
        $this->my_address[1] = 'Street Address';
        $settings->key('storeAddress');
        if ($settings->load()) {
            $this->my_address[1] = $settings->value();
        }
        $this->my_address[2] = '';
        $settings->key('storeCity');
        if ($settings->load()) {
            $this->my_address[2] .= $settings->value() . ', ';
        } else {
            $this->my_address[2] .= 'City, ';
        }
        $settings->key('storeState');
        if ($settings->load()) {
            $this->my_address[2] .= $settings->value() . ' ';
        } else {
            $this->my_address[2] .= 'XX ';
        }
        $settings->key('storeZip');
        if ($settings->load()) {
            $this->my_address[2] .= $settings->value();
        } else {
            $this->my_address[2] .= '12345';
        }
        $this->my_address[3] = 'Tel: 555-867-5309';
        $settings->key('storePhone');
        if ($settings->load()) {
            $this->my_address[3] = 'Tel: ' . $settings->value();
        }
    }

    public function renderAsHTML()
    {
       $ret = '<div class="checkPreview" style="border: solid 1px black; 
                background-color: #ccc; padding: 3px; width: 100%;">'; 

       $ret .= '<div class="checkRowOne">';
       $ret .= '<div style="float:left; width: 30%; text-align:left;">';
       $ret .= '<b>' . $this->memo . '</b><br />';
       foreach($this->my_address as $line) {
           $ret .= $line . '<br />';
       }
       $ret .= '</div>';
       $ret .= '<div style="float:left; width: 20%; text-align:center;">';
       foreach($this->bank_address as $line) {
           $ret .= $line . '<br />';
       }
       $ret .= '</div>';
       $ret .= '<div style="float:left; width: 45%; text-align:right;">';
       $ret .= '<b>Check Number: ' . $this->check_number . '</b><br />';
       $ret .= '<b>Date: ' . $this->check_date . '</b><br />';
       $ret .= '<b>Amount: ' . str_pad(number_format($this->amount, 2), 25, '*', STR_PAD_LEFT).'</b>';
       $ret .= '</div>';
       $ret .= '</div>'; // end checkRowOne

       $ret .= '<div style="clear:left; width=100%; text-align:center;">This checkvoid after 90 days</div>';

       $ret .= '<div style="clear:left; width=100%; font-weight:bold; text-align:right;margin-right:30px;">';
       $ret .= $this->amount_as_words;
       $ret .= '</div>';

       $ret .= '<div class="checkRowTwo">';
       $ret .= '<div style="float: left; width: 60%; text-align: left; font-weight: bold;">';
       foreach($this->their_address as $line) {
            $ret .= $line . '<br />';
       }
       $ret .= '</div>';
       $ret .= '<div style="float: left; width: 30%; text-align: center;">';
       $ret .= 'Authorized By Signature';
       $ret .= '</div>';
       $ret .= '</div>'; // end checkRowTwo;

       $ret .= '<div style="clear:left; width: 100%; text-align: center;">';
       $ret .= $this->check_number;
       $ret .= '<span style="margin-left:100px;">&nbsp;</span>';
       $ret .= str_repeat('*', strlen($this->routing_no)-4) . substr($this->routing_no, -4);
       $ret .= '<span style="margin-left:100px;">&nbsp;</span>';
       $ret .= str_repeat('*', strlen($this->checking_no)-4) . substr($this->checking_no, -4);
       $ret .= '</div>';

       $ret .= '</div>';

       return $ret;
    }

    private function getRectangle($margins)
    {
        $check_left_x = ($margins['left'] > 3.175) ? $margins['right'] : 3.175 - $margins['left'];
        $check_right_x = 203.2 - $margins['left'];
        switch ($this->position) {
            case self::POSITION_TRI_1:
                $check_top_y = 3.10 - $margins['top'];
                $check_bottom_y = $check_top_y + 71.347;
                return array($check_left_x, $check_top_y, $check_right_x, $check_bottom_y);
            case self::POSITION_TRI_2:
                $check_top_y = 91.0 - $margins['top'];
                $check_bottom_y = $check_top_y + 71.347;
                return array($check_left_x, $check_top_y, $check_right_x, $check_bottom_y);
            case self::POSITION_TRI_3:
                $check_top_y = 180.675 - $margins['top'];
                $check_bottom_y = $check_top_y + 71.347;
                return array($check_left_x, $check_top_y, $check_right_x, $check_bottom_y);
            case self::POSITION_BOTTOM:
            default:
                $check_top_y = 193.675 - $margins['top'];
                $check_bottom_y = 265.112 - $margins['top'];
                return array($check_left_x, $check_top_y, $check_right_x, $check_bottom_y);
        }
    }

    public function renderAsPDF($pdf)
    {
        $margins = $pdf->GetMargins();
        // this was written BEFORE patching
        // fpdf to correctly return the top margin
        // set to zero to mimic old, broken fpdf
        $margins['top'] = 0.0; 
        list($check_left_x, $check_top_y, $check_right_x, $check_bottom_y) = $this->getRectangle($margins);
        $line_height = 5;

        $pdf->SetFont('Arial', 'B', 10);

        $pdf->SetXY($check_left_x, $check_top_y);
        $pdf->Cell(0, $line_height, $this->memo, 0, 1);
        if ($this->position == SELF::POSITION_BOTTOM) {
            $pdf->Ln($line_height);
        }
        $pdf->SetFont('Arial', '', 10);
        $envelope_window_tab = 15;
        foreach($this->my_address as $line) {
            $pdf->SetX($check_left_x + $envelope_window_tab);
            $pdf->Cell(0, $line_height, $line, 0, 1);
        }

        $bank_offset = 90; 
        $pdf->SetXY($check_left_x + $bank_offset, $check_top_y);
        foreach($this->bank_address as $line) {
            $pdf->SetX($check_left_x + $bank_offset);
            $pdf->Cell(30, $line_height, $line, 0, 1, 'C');
        }

        $right_col1 = 130;
        $right_col2 = 170;
        $pdf->SetFont('Arial', 'B', 10);
        $pdf->SetXY($check_left_x + $right_col1, $check_top_y);
        $pdf->Cell(30, $line_height, 'Check Number:', 0, 0, 'R');
        $pdf->SetX($check_left_x + $right_col2);
        $pdf->Cell(30, $line_height, $this->check_number, 0, 0, 'R');
        $pdf->SetXY($check_left_x + $right_col1, $check_top_y+(1.5*$line_height));
        $pdf->Cell(30, $line_height, 'Date:', 0, 0, 'R');
        $pdf->SetX($check_left_x + $right_col2);
        $pdf->Cell(30, $line_height, $this->check_date, 0, 0, 'R');
        $pdf->SetXY($check_left_x + $right_col1, $check_top_y+(3*$line_height));
        $pdf->Cell(30, $line_height, 'Amount:', 0, 0, 'R');
        $pdf->SetX($check_left_x + $right_col2);
        $pdf->Cell(30, $line_height, str_pad(number_format($this->amount, 2), 25, '*', STR_PAD_LEFT), 0, 0, 'R');

        $pdf->SetFont('Arial', '', 10);
        $pdf->SetXY($check_left_x, $check_top_y + (7*$line_height));
        $pdf->Cell(0, $line_height, 'This check void after 90 days', 0, 1, 'C');
        $pdf->SetFont('Arial', 'B', 10);
        $pdf->Cell(0, $line_height, $this->amount_as_words.'   ', 0, 1, 'R');

        $pdf->SetXY($check_left_x + $envelope_window_tab, $check_top_y + (8.5*$line_height));
        if ($this->position != self::POSITION_BOTTOM) {
            $pdf->SetXY($check_left_x + $envelope_window_tab, $check_top_y + (10.0*$line_height));
        }
        foreach($this->their_address as $line) {
            $pdf->SetX($check_left_x + $envelope_window_tab);
            $pdf->Cell(0, $line_height, $line, 0, 1);
        }

        $pdf->Image(dirname(__FILE__) . '/img/sig.png', $check_right_x - 63.5, $check_top_y + (9*$line_height), 50.5);
        $pdf->SetXY($check_right_x - 63.5, $check_top_y + (13*$line_height));
        $pdf->Cell(63.5, $line_height, 'Authorized By Signature', 'T');

        // Seem to have random MICR alignment problems
        // here at times
        $pdf->SetXY($check_left_x + 34.5, $check_bottom_y + $line_height - 1);
        if ($this->micrShift) {
            $pdf->SetXY($check_left_x + 37.8, $check_bottom_y + $line_height - 1);
        }
        if (!isset($pdf->fonts['gnumicr'])) {
            $pdf->AddFont('GnuMICR', '', 'GnuMICR.php');
        }
        $pdf->SetFont('GnuMICR', '', 12);
        // In the MICR font:
        // A is the symbol for routing/transit
        // B is the symbol for amount
        // C is the symbol for account ("on-us")
        // D is the symbol for dash
        $bottom_line = 'C' . $this->check_number . 'C';
        $bottom_line .= ' ';
        $bottom_line .= 'A' . $this->routing_no . 'A';
        $bottom_line .= ' ';
        $bottom_line .= $this->checking_no . 'A';
        $pdf->Cell(0, $line_height, $bottom_line);

        return true;
    }
}

