<?php

/**
 * @package Csv
 */

/**
 * Takes a CSV file or CSV string and converts it to an array.
 */
class Interspire_Csv_Importer extends Interspire_Csv_Abstract
{
	/**
	 * @var string $_beforeParse
	 */
	private $_beforeParse = '';

	/**
	 * @var array $_afterParse
	 */
	private $_afterParse  = [];

	/**
	 * @var array $_config
	 */
	private $_config      = [
				'delimiter' => ',',
				'enclosure' => '"',
				'newLine'   => "\n"
			];
	
	/**
	 * @param String $csvToParse
	 * @param Mixed $config
	 */
	public function __construct($csvToParse, $config = null)
	{
		$this->setConfig($config);
		
		if (is_file($csvToParse)) {
			$this->_beforeParse = file_get_contents($csvToParse);
		} else {
			$this->_beforeParse = $csvToParse;
		}
	}
	
	/**
	 * @return Array
	 */
	public function parse()
	{
		// split the file into lines
		$lines = explode($this->_config['newLine'], $this->_beforeParse);
		
		// foreach line, we will parse it into columns and set the line to a columns array
		foreach ($lines as $lineIndex => $line) {
			// we add extra padding to the line so that if the last character was a delimiter
			// then it will catch that and add an empty column at the end
			$line       = $line . ' ';
			$open       = false;
			$lineLength = strlen($line);
			$colIndex   = 0;
			$cols       = [];
			
			for ($charIndex = 0; $charIndex < $lineLength; $charIndex++) {
				$lastChar    = $charIndex ? $line[$charIndex - 1] : '';
				$char        = $line[$charIndex];
				$nextChar    = $charIndex + 1 != $lineLength ? $line[$charIndex + 1] : '';
				$isEnclosure = $char == $this->_config['enclosure'] && $lastChar != '\\';
				
				if (!isset($cols[$colIndex])) {
					$cols[$colIndex] = '';
				}
				
				// if this an opening enclosure, set open to true and continue the loop
				if (!$open && $isEnclosure) {
					$open = true;
					
					continue;
				}
				
				// if this is a closing enclosure
				if ($open && $isEnclosure) {
					$open = false;
					
					continue;
				}
				
				if (!$open && $char == $this->_config['delimiter']) {
					$colIndex++;
					
					continue;
				}
				
				$cols[$colIndex] .= $char;
			}
			
			// iterate through each column and trim clean it up
			foreach ($cols as &$col) {
				$col = trim($col);
			}
			
			// set the current line
			$lines[$lineIndex] = $cols;
		}
		
		$this->_afterParse = $lines;
		
		return $this->_afterParse;
	}
}