<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This class provides invoice rending use TCPDF
 *
 * @package    Invoice
 * @category   Helpers
 * @author     Deon George
 * @copyright  (c) 2009-2013 Open Source Billing
 * @license    http://dev.osbill.net/license.html
 */
class Invoice_Tcpdf_Default extends Invoice_Tcpdf {
	// Current line being printed
	public $sum_y = 0;

	private $max_lines_page = 51;
	protected $show_service_range = TRUE;

	/**
	 * Draw the logo
	 */
	public function drawCompanyLogo() {
		$x = 9; $y = 7;
		$size = 25;
		$logo = $this->co->logo_file();

		if (is_file($logo))
			$this->Image($logo,$x,$y,$size);
	}

	/**
	 * Draw the Company Address
	 */
	public function drawCompanyAddress() {
		// Add the company address next to the logo
		$x = 40; $y = 7;

		$this->SetFont('helvetica','B',10);
		$this->SetXY($x,$y); $this->Cell(0,0,$this->co->name()); $y += 4;

		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,$this->co->taxid()); $y += 6;

		$this->SetXY($x,$y); $this->Cell(0,0,$this->co->street(', ')); $y += 4;
		$this->SetXY($x,$y); $this->Cell(0,0,sprintf('%s, %s %s',$this->co->city(),$this->co->state(),$this->co->pcode())); $y += 4;

		$y += 2;
		$this->SetXY($x,$y); $this->Cell(0,0,'Phone:'); $this->SetXY($x+16,$y); $this->Cell(0,0,$this->co->phone()); $y += 4;
		if ($this->co->fax()) {
			$this->SetXY($x,$y); $this->Cell(0,0,'Fax:'); $this->SetXY($x+16,$y); $this->Cell(0,0,$this->co->fax()); $y += 4;
		}
		$this->SetXY($x,$y); $this->Cell(0,0,'Web:'); $this->SetXY($x+16,$y); $this->addHtmlLink(URL::base(TRUE,TRUE),URL::base(TRUE,TRUE)); $y += 4;
	}

	/**
	 * Draw the remmittence stub
	 */
	public function drawRemittenceStub() {
		// Draw the remittance line
		$this->Line(9,195,200,195);

		$x = 18; $y = 200;

		$this->SetFont('helvetica','B',13);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Payment Remittence')); $y +=5;

		$this->SetFont('helvetica','',8);
		$this->SetXY($x,$y); $this->Cell(0,0,_('PLEASE NOTE: Cheques are no longer accepted for payment,')); $y +=3;
		$this->SetXY($x,$y); $this->Cell(0,0,_('please use an online method of payment.')); $y +=3;

		// Due Date
		$x = 110; $y = 200;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Issue Date'));
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->display('date_orig'),0,0,'R');

		// Account ID
		$y = 205;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Account Number'));
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->account->refnum(),0,0,'R');

		// Invoice number
		$y = 210;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Invoice Number'));
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->refnum(TRUE),0,0,'R');

		// Company Address
//		$y = 216;
//		$this->SetFont('helvetica','',10);
//		$this->SetXY(18,$y); $this->Cell(0,0,$this->co->name()); $y += 4;
//		$this->SetXY(18,$y); $this->Cell(0,0,$this->co->street(', ')); $y += 4;
//		$this->SetXY(18,$y); $this->Cell(0,0,sprintf('%s, %s %s',$this->co->city(),$this->co->state(),$this->co->pcode())); $y += 4;

		// Previous Due
		$y = 215;
		$this->SetFont('helvetica','',9);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Previous Due'));
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->account->invoices_due_total($this->io->date_orig,TRUE),0,0,'R');

		$y = 219;
		$this->SetFont('helvetica','',9);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Amount Due').' '.$this->io->display('due_date'));
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->due(TRUE),0,0,'R');

		// Total Due
		$y = 224;
		$this->SetFont('helvetica','B',10);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Total Payable'));
		$this->SetXY($x,$y); $this->Cell(0,0,Currency::display($this->io->due() ? $this->io->total()+$this->io->account->invoices_due_total($this->io->date_orig,TRUE) : 0),0,0,'R');

		// Draw the Customers Address
		$x = 25; $y = 248;

		$this->SetFont('helvetica','B',12);

		if ($this->billToCompany && ! empty($this->io->account->company))
			$name = $this->io->account->company;
		else
			$name = $this->io->account->name();

		$this->SetXY($x,$y); $this->Cell(0,0,html_entity_decode($name,ENT_NOQUOTES)); $y += 5;
		$this->SetXY($x,$y); $this->Cell(0,0,sprintf('%s %s ',$this->io->account->address1,$this->io->account->address2)); $y += 5;
		$this->SetXY($x,$y); $this->Cell(0,0,sprintf('%s, %s %s',$this->io->account->city,$this->io->account->state,$this->io->account->zip)); $y += 5;
	}

	/**
	 * Draw the invoice header
	 */
	public function drawInvoiceHeader() {
		$x = 125; $y = 10;

		// Draw a box.
		$this->SetFillColor(245);
		$this->SetXY($x-1,$y-1); $this->Cell(0,35+5+($this->io->total_credits() ? 5 : 0),'',1,0,'',1);

		// Draw a box around the invoice due date and amount due.
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y); $this->Cell(0,0,'TAX INVOICE');
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->refnum(TRUE),0,0,'R');

		// Invoice number at top of page.
		$y += 7;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Issue Date')); $y += 5;
		$this->SetXY($x,$y); $this->Cell(0,0,_('Amount Due'));

		$y -= 5;
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->display('date_orig'),0,0,'R'); $y += 5;
		$this->SetXY($x,$y); $this->Cell(0,0,$this->io->display('due_date'),0,0,'R');

		$y += 5;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Previous Due'));
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x+55,$y); $this->Cell(0,0,$this->io->account->invoices_due_total($this->io->date_orig,TRUE),0,0,'R');

		$y += 5;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Current Charges'));
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x+55,$y); $this->Cell(0,0,$this->io->total(TRUE),0,0,'R');

		$y += 5;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,'Payments Received');
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x+55,$y); $this->Cell(0,0,$this->io->payments_total('TRUE'),0,0,'R');

		if ($this->io->total_credits()) {
			$y += 5;
			$this->SetFont('helvetica','',10);
			$this->SetXY($x,$y); $this->Cell(0,0,'Credits Received');
			$this->SetFont('helvetica','B',11);
			$this->SetXY($x+55,$y); $this->Cell(0,0,$this->io->total_credits(TRUE),0,0,'R');
		}

		$y += 5;
		$this->SetFont('helvetica','',10);
		$this->SetXY($x,$y); $this->Cell(0,0,'Total Payable');
		$this->SetFont('helvetica','B',11);
		$this->SetXY($x+55,$y); $this->Cell(0,0,Currency::display($this->io->due() ? $this->io->total()+$this->io->account->invoices_due_total($this->io->date_orig) : 0),0,0,'R');
	}

	/**
	 * Draw any news messages
	 * @todo Limit the size of the news to 6 lines
	 */
	public function drawNews($news) {
		if (! $news)
			return;

		$x = 9; $y = 170;

		# Draw a box.
		$this->SetFillColor(243);
		$this->SetXY($x-1,$y-1); $this->Cell(0,20,'',1,0,'',1);

		$this->SetFont('helvetica','',8);
		$this->SetXY($x,$y); $this->MultiCell(0,3,str_replace('\n',"\n",$news),0,'L',0);
	}

	/**
	 * Draw our available payment methods
	 * @todo make this list dynamic
	 */
	public function drawPaymentMethods() {
		$x = 120; $y = 242;

		# Draw a box.
		$this->SetFillColor(235);
		$this->SetXY($x-1,$y-2); $this->Cell(0,32,'',1,0,'',1);

		$this->SetFont('helvetica','B',8);
		$this->SetXY($x,$y); $this->Cell(0,0,'This invoice can be paid by:'); $y += 4;

		# Direct Credit
		$logo = Kohana::find_file('media','img/invoice-payment-dd','png');
		$this->Image($logo,$x+1,$y,8);
		$this->SetFont('helvetica','B',8);
		$this->SetXY($x+10,$y); $this->Cell(0,0,'Direct Credit to our Bank Account'); $y += 3;
		$this->SetFont('helvetica','',8);
		$this->SetXY($x+10,$y); $this->Cell(0,0,'BSB:'); $y += 3;
		$this->SetXY($x+10,$y); $this->Cell(0,0,'ACCOUNT:'); $y += 3;
		$this->SetXY($x+10,$y); $this->Cell(0,0,'REF:'); $y += 3;

		$y -= 9;
		$this->SetFont('helvetica','B',8);
		$this->SetXY($x+30,$y); $this->Cell(0,0,Company::bsb()); $y += 3;
		$this->SetXY($x+30,$y); $this->Cell(0,0,Company::account()); $y += 3;
		$this->SetXY($x+30,$y); $this->Cell(0,0,$this->io->refnum()); $y += 3;

/*
		# Direct Debit
		$y += 3;
		$logo = sprintf('%s/%s',PATH_THEMES.DEFAULT_THEME,'invoice/invoice-payment-dd.png');
		$this->Image($logo,$x+1,$y,8);
		$this->SetFont('helvetica','B',8);
		$this->SetXY($x+10,$y); $this->Cell(0,0,'Direct Debit'); $y += 3;
		$this->SetFont('helvetica','',8);
		$this->SetXY($x+10,$y); $this->Cell(0,0,'Please visit '); $this->SetXY($x+30,$y); $this->addHtmlLink($inv->print['site']['URL'].'?_page=invoice:user_view&id='.$inv->getPrintInvoiceNum(),$inv->print['site']['URL']); $y += 3;
*/

		# Paypal
		$y += 3;
		$logo = Kohana::find_file('media','img/invoice-payment-pp','png');
		$this->Image($logo,$x+1,$y,8);
		$this->SetFont('helvetica','B',8);
		$this->SetXY($x+10,$y); $this->Cell(0,0,'Pay Pal/Credit Card'); $y += 3;
		$this->SetFont('helvetica','',8);
		$this->SetXY($x+10,$y); $this->Cell(0,0,'Please visit '); $this->SetXY($x+30,$y); $this->addHtmlLink(URL::base(TRUE,TRUE),URL::base(TRUE,TRUE)); $y += 3;
	}

	/**
	 * Draw previous invoices due
	 */
	public function drawSummaryInvoicesDue() {
		$x = 125; $y = $this->sum_y ? $this->sum_y : 55;

		$items = $this->io->account->invoices_due($this->io->date_orig);

		# Calculate the box size
		$box = count($items) < $this->itemsPreviousMax ? count($items) : $this->itemsPreviousMax;

		# Draw a box.
		$this->SetFillColor(245);
		$this->SetXY($x-1,$y-1); $this->Cell(0,5*(1+$box)+1,'',1,0,'',1);

		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y); $this->Cell(0,0,_('Previous Invoices Due')); $y += 5;

		$this->SetFont('helvetica','',11);
		$i = 0;
		$sum_total = 0;
		foreach ($items as $line) {
			if (++$i < $this->itemsPreviousMax) {
				$this->SetXY($x,$y);
				$this->Cell(0,0,sprintf('%s %s',$line->display('date_orig'),$line->refnum(TRUE)));
				$this->Cell(0,0,$line->due(TRUE),0,0,'R'); $y += 5;

			} else {
				$sum_total += $line->due();
			}
		}

		if ($sum_total) {
			$this->SetXY($x,$y);
			$this->SetFont('helvetica','I',11);
			$this->Cell(0,0,'Other invoices');
			$this->SetFont('helvetica','',11);
			$this->Cell(0,0,Currency::display($sum_total),0,0,'R'); $y += 5;
		}

		$this->sum_y = $y+5;
	}

	/**
	 * This will draw the Summary Box, with the summary of the items
	 * on the invoice.
	 */
	public function drawSummaryLineItems() {
		if (! $this->show_itemized)
			return;

		$items = $this->io->items_summary();

		// Calculate the box size
		$box = count($items) < $this->itemsSummaryMax ? count($items) : $this->itemsSummaryMax;

		// Our starting position
		$x = 10; $y = $this->sum_y ? $this->sum_y : 55;

		// Draw a box.
		$this->SetFillColor(245);
		$this->SetXY($x-1,$y-1);
		$this->Cell(0,5*(
			1+1+1+3+($this->io->total_discounts() ? 1 : 0)+1+($this->io->total_credits() ? 1 : 0)+$box
			)+1+4,'',1,0,'',1);

		$this->SetFont('helvetica','B',11);
		$this->SetXY($x,$y);
		$this->Cell(0,0,_('Current Charges Summary')); $y += 5;

		$this->SetY($y);
		$this->SetFont('helvetica','',9);

		$i = $subtotal = 0;
		foreach ($items as $name => $line) {
			if ($i < $this->itemsSummaryMax) {
				$this->SetX($x);
				$this->Cell(0,0,sprintf('%3.0f',$line['quantity']));
				$this->SetX($x+8);
				$this->Cell(0,0,$name);
				$this->SetX($x+135);
				$this->Cell(0,0,Currency::display($line['subtotal']),0,0,'R');

				$y += 5;
				$this->SetY($y);
			}

			$i++;
			if ($i == $this->itemsSummaryMax) {
				$this->SetFont('helvetica','B',11);
				$this->SetX($x);
				$this->Cell(0,0,_('The above is just a summary. To view a detailed list of charges, please visit our website.'));
			}

			$subtotal += $line['subtotal'];
		}

		// Calculate our rounding error
		// @todo This shouldnt be required.
		#$subtotal = Currency::round($subtotal-$this->io->total_discounts());

		if (Currency::round($this->io->subtotal()) != $subtotal) {
			$this->SetFont('helvetica','',9);
			$this->SetX($x);
			$this->Cell(0,0,'Other');
			$this->SetX($x+135);
			$this->Cell(0,0,Currency::display($this->io->subtotal()-$subtotal),0,0,'R');

			$y += 5;
			$this->SetY($y);
		}

		// Draw Discounts.
		if ($this->io->total_discounts()) {
			$y += 5;
			$this->SetY($y);

			$this->SetFont('helvetica','B',9);
			$this->SetX($x+8);
			$this->Cell(0,0,_('Discount'));
			$this->SetX($x+135);
			$this->Cell(0,0,Currency::display(-$this->io->total_discounts()),0,0,'R');
		}

		// Subtotal and tax.
		$y += 5;
		$this->SetY($y);

		$this->SetFont('helvetica','B',9);
		$this->SetX($x+8);
		$this->Cell(0,0,'Sub Total');
		$this->SetX($x+135);
		$this->Cell(0,0,Currency::display($this->io->subtotal()),0,0,'R');

		$y += 5;
		$this->SetY($y);

		$this->SetX($x+8);
		$this->Cell(0,0,'Taxes');
		$this->SetX($x+135);
		$this->Cell(0,0,Currency::display($this->io->tax()),0,0,'R');

		$y += 5;
		$this->SetY($y);

		$this->SetX($x+8);
		$this->Cell(0,0,'Total Charges This Invoice');
		$this->SetX($x+135);
		$this->Cell(0,0,Currency::display($this->io->total()),0,0,'R');

		// Show payments already received for this invoice
		$y += 5;
		$this->SetY($y);

		$this->SetX($x+8);
		$this->Cell(0,0,'Payments Received');
		$this->SetX($x+135);
		$this->Cell(0,0,$this->io->payments_total(TRUE),0,0,'R');

		if ($this->io->total_credits()) {
			$y += 5;
			$this->SetY($y);

			$this->SetFont('helvetica','B',9);
			$this->SetX($x+8);
			$this->Cell(0,0,_('Less Credits'));
			$this->SetX($x+135);
			$this->Cell(0,0,Currency::display(-$this->io->total_credits()),0,0,'R');
		}

		$y += 5;
		$this->SetY($y);
		$this->SetX($x+8);
		$this->Cell(0,0,'Balance Due');
		$this->SetX($x+135);
		$this->Cell(0,0,$this->io->due(TRUE),0,0,'R');
	}

	/**
	 * This will draw the Summary Box, with the summary of the items
	 * on the invoice.
	 */
	public function drawDetailLineItems() {
		$this->i = 0;

		foreach ($this->io->items_render() as $key => $items) {
			switch ($key) {
				case 's':
					$this->drawLineItems($items);
					break;
			}
		}
	}

	/**
	 * Draws Invoice Detail Items
	 */
	private function drawLineItems(array $items) {
		$track['rs'] = $track = array();
		$x = 10;
		if ($this->i == 0 || $this->i%$this->max_lines_page == 0) {
			$this->y = 5;
			$this->AddPage();

			$this->SetFont('helvetica','B',12);
			$this->SetXY($x,$this->y); $this->Cell(0,0,_('Itemised Charges'));
			$this->Cell(0,0,_('Page #').$this->PageNo(),0,0,'R');
			$this->SetXY($x,$this->y); $this->Cell(0,0,_('Invoice #').$this->io->refnum(TRUE),0,0,'C');

			// Draw table headers
			$this->y += 10;
			$this->SetFont('helvetica','B',8);
			$this->SetXY($x,$this->y);
			$this->Cell(0,0,_('Description'));
			$this->SetX($x+135);
			$this->Cell(0,0,_('Quantity'));
			$this->SetX($x+160);
			$this->Cell(10,0,_('Unit Cost'),0,0,'R');
			$this->SetX($x+135);
			$this->Cell(0,0,_('Amount'),0,0,'R');
			$this->Line($x,$this->y+4,200,$this->y+4);

			$this->y += 5;
			$this->SetY($this->y);
		}

		$last = '';
		foreach ($items as $iio) {
			// So we dont render the same recurring schedule over again
			if (! is_null($iio->recurring_schedule) AND ! in_array($iio->recurring_schedule,$track['rs'])) {
				array_push($track['rs'],$iio->recurring_schedule);
				// echo $iio->display('recurring_schedule');
			}

			// If we are rendering a new service, reset the product id tracking
			if ($iio->service_id != $last) {
				if ($last) {
					$this->y += 6;
					$this->SetY($this->y);
				}

				$last = $iio->service_id;
				$track['p'] = array();
			}

			// So we dont render the same product title over again
			if (! in_array($iio->product_id,$track['p'])) {
				array_push($track['p'],$iio->product_id);

				$this->SetFont('helvetica','',8);
				$this->SetX($x);
				$this->Cell(0,0,sprintf('%s: %s',$iio->service->refnum(TRUE),$iio->name($iio->invoice->account->language)));
				$this->SetFont('helvetica','',7);

				$this->y += 1;
				if ($iio->service->attributes()) {
					foreach ($iio->service->attributes() as $k=>$v) {
						$this->SetFont('helvetica','I',6);
						$this->y += 3;
						$this->SetXY($x+10,$this->y); $this->Cell(0,0,$k);
						$this->SetFont('helvetica','',6);
						$this->SetXY($x+40,$this->y); $this->Cell(0,0,$v);
					}
				}

				$this->y += 2;
				$this->SetY($this->y);
				$this->i++;
			}

			$this->y += 3;
			$this->SetY($this->y);
			$this->SetX($x+10);
			$this->Cell(10,0,sprintf('%s: (%s)',$iio->namesub($iio->invoice->account->language),$iio->refnum()));

			if ($iio->quantity) {
				$this->SetX($x+130);
				$this->Cell(10,0,sprintf('%3.2f',$iio->quantity),0,0,'R');
			}

			if ($iio->price_base) {
				$this->SetX($x+160);
				$this->Cell(10,0,Currency::display($iio->price_base),0,0,'R');
			}

			$this->SetX($x+130);
			$this->Cell(0,0,$iio->total(TRUE),0,0,'R');
		}
	}
}
?>