<?php
/**
 * @author RIHARDS SLINS
 * @version 19/03/2014
 */

require_once dirname(__FILE__).'/Array.php';

class Diff_Renderer_Html_RSSideBySide extends Diff_Renderer_Html_Array
{
	/**
	 * Render a and return diff with changes between the two sequences
	 * displayed side by side.
	 *
	 * @return string The generated side by side diff.
	 */
	public function render()
	{
		$changes = parent::render();

		$html = '';
		if(empty($changes)) {
			return $html;
		}
		$html .= '<div class="DiffContainer">';
			$html .= '<div class="DiffLeftContainer">';
				$html .= '<div><strong>Current System</strong></div>';
				$html .= '<div class="numberColumn"><pre>';
					foreach($changes as $i => $blocks) {
						if($i > 0) {
							$html .= '<div>&hellip;</div>';
						}
						foreach($blocks as $change) {
							$change_tag = $change['tag'];
							if($change['tag'] == 'equal') {
								foreach($change['base']['lines'] as $no => $line) {
									$fromLine = $change['base']['offset'] + $no + 1;
									$html .= '<div>'.$fromLine.'</div>';
								}
							}
							// Added lines only on the right side
							else if($change['tag'] == 'insert') {
								foreach($change['changed']['lines'] as $no => $line) {
									$html .= "<div>&nbsp;</div>";
								}
							}
							// Show deleted lines only on the left side
							else if($change['tag'] == 'delete') {
								foreach($change['base']['lines'] as $no => $line) {
									$fromLine = $change['base']['offset'] + $no + 1;
									$html .= '<div>'.$fromLine.'</div>';
								}
							}
							// Show modified lines on both sides
							else if($change['tag'] == 'replace') {
								if(count($change['base']['lines']) >= count($change['changed']['lines'])) {
									foreach($change['base']['lines'] as $no => $line) {
										$fromLine = $change['base']['offset'] + $no + 1;
										$html .= '<div>'.$fromLine.'</div>';
									}
								}
								else {
									foreach($change['changed']['lines'] as $no => $changedLine) {
										if(!isset($change['base']['lines'][$no])) {
											$fromLine = '&nbsp;';
											$line = '&nbsp;';
										}
										else {
											$fromLine = $change['base']['offset'] + $no + 1;
											$line = '<div>'.$change['base']['lines'][$no].'</div>';
										}
										$html .= '<div>'.$fromLine.'</div>';
									}
								}
							}
						}
					}
				$html .= '</pre></div><!--end of numberColumn-->';
				$html .= '<div class="codeColumn"><pre>';
					foreach($changes as $i => $blocks) {
						if($i > 0) {
							$html .= '&hellip;<br/>';
						}
						foreach($blocks as $change) {
							// Equal changes should be shown on both sides of the diff
							if($change['tag'] == 'equal') {
								foreach($change['base']['lines'] as $no => $line) {
									$html .= '<span class="line">'.( $line == "" ? "&nbsp;" : $line).'</span><br/>';
								}
							}
							// Added lines only on the right side
							else if($change['tag'] == 'insert') {
								foreach($change['changed']['lines'] as $no => $line) {
									$toLine = $change['changed']['offset'] + $no + 1;
									$html .= '<span class="line">&nbsp;</span><br/>';
								}
							}
							// Show deleted lines only on the left side
							else if($change['tag'] == 'delete') {
								foreach($change['base']['lines'] as $no => $line) {
									$fromLine = $change['base']['offset'] + $no + 1;
									$html .= '<span class="line line-delete">'.($line == "" ? "&nbsp;" : $line).'</span><br/>';
								}
							}
							// Show modified lines on both sides
							else if($change['tag'] == 'replace') {
								if(count($change['base']['lines']) >= count($change['changed']['lines'])) {
									foreach($change['base']['lines'] as $no => $line) {
										$fromLine = $change['base']['offset'] + $no + 1;
										$html .= '<span class="line line-replace">'.($line == "" ? "&nbsp;" : $line).'</span><br/>';
										if(!isset($change['changed']['lines'][$no])) {
											$toLine = '&nbsp;';
											$changedLine = '&nbsp;';
										}
										else {
											$toLine = $change['base']['offset'] + $no + 1;
										}
									}
								}
								else {
									foreach($change['changed']['lines'] as $no => $changedLine) {
										if(!isset($change['base']['lines'][$no])) {
											$fromLine = '&nbsp;';
											$line = '&nbsp;';
										}
										else {
											$fromLine = $change['base']['offset'] + $no + 1;
											$line = $change['base']['lines'][$no];
										}
										$html .= '<span class="line line-replace">'.($line == "" ? "&nbsp;" : $line).'</span><br/>';
									}
								}
							}
						}
					}
				$html .= '</pre></div><!--end of codeColumn-->';
			$html .= '</div>';


			$html .= '<div class="DiffRightContainer">';
				$html .= '<div><strong>Actual Version</strong></div>';
				$html .= '<div class="numberColumn"><pre>';
					foreach($changes as $i => $blocks) {
						if($i > 0) {
							$html .= '&hellip;<br/>';
						}

						foreach($blocks as $change) {
							// Equal changes should be shown on both sides of the diff
							if($change['tag'] == 'equal') {
								foreach($change['base']['lines'] as $no => $line) {
									$toLine = $change['changed']['offset'] + $no + 1;
									$html .= "<div>".$toLine.'</div>';
								}
							}
							// Added lines only on the right side
							else if($change['tag'] == 'insert') {
								foreach($change['changed']['lines'] as $no => $line) {
									$toLine = $change['changed']['offset'] + $no + 1;
									$html .= "<div>".$toLine.'</div>';
								}
							}
							// Show deleted lines only on the left side
							else if($change['tag'] == 'delete') {
								foreach($change['base']['lines'] as $no => $line) {
									$html .= '<div>&nbsp;</div>';
								}
							}
							// Show modified lines on both sides
							else if($change['tag'] == 'replace') {
								if(count($change['base']['lines']) >= count($change['changed']['lines'])) {
									foreach($change['base']['lines'] as $no => $line) {
										if(!isset($change['changed']['lines'][$no])) {
											$toLine = '&nbsp;';
											$changedLine = '&nbsp;';
										}
										else {
											$toLine = $change['base']['offset'] + $no + 1;
											$changedLine = '<div>'.$change['changed']['lines'][$no].'</div>';
										}
										$html .= '<div>'.$toLine.'</div>';
									}
								}
								else {
									foreach($change['changed']['lines'] as $no => $changedLine) {
										if(!isset($change['base']['lines'][$no])) {
											$fromLine = '&nbsp;';
											$line = '&nbsp;';
										}
										else {
											$fromLine = $change['base']['offset'] + $no + 1;
											$line = '<div>'.$change['base']['lines'][$no].'</div>';
										}
										$toLine = $change['changed']['offset'] + $no + 1;
										$html .= '<div>'.$toLine.'  </div>';
									}
								}
							}
						}
					}
					$html .= '</pre></div><!--end of numberColumn-->';
					$html .= '<div class="codeColumn"><pre>';
					foreach($changes as $i => $blocks) {
						if($i > 0) {
							$html .= '&hellip;<br/>';
						}

						foreach($blocks as $change) {
							// Equal changes should be shown on both sides of the diff
							if($change['tag'] == 'equal') {
								foreach($change['base']['lines'] as $no => $line) {
									$html .= '<span class="line">'.($line == "" ? "&nbsp;" : $line).'</span><br/>';
								}
							}
							// Added lines only on the right side
							else if($change['tag'] == 'insert') {
								foreach($change['changed']['lines'] as $no => $line) {
									$html .= '<span class="line line-insert">'.($line == "" ? "&nbsp;" : $line).'</span><br/>';
								}
							}
							// Show deleted lines only on the left side
							else if($change['tag'] == 'delete') {
								foreach($change['base']['lines'] as $no => $line) {
									$html .= '<span class="line">&nbsp;</span><br/>';
								}
							}
							// Show modified lines on both sides
							else if($change['tag'] == 'replace') {
								if(count($change['base']['lines']) >= count($change['changed']['lines'])) {
									foreach($change['base']['lines'] as $no => $line) {
										$fromLine = $change['base']['offset'] + $no + 1;
										if(!isset($change['changed']['lines'][$no])) {
											$toLine = '&nbsp;';
											$changedLine = '&nbsp;';
										}
										else {
											$toLine = $change['base']['offset'] + $no + 1;
											$changedLine = $change['changed']['lines'][$no];
										}
										$html .= '<span class="line line-replace">'.($changedLine == "" ? "&nbsp;" : $changedLine).'</span><br/>';
									}
								}
								else {
									foreach($change['changed']['lines'] as $no => $changedLine) {
										if(!isset($change['changed']['lines'][$no])) {
											$fromLine = '&nbsp;';
											$line = '&nbsp;';
										}
										else {
											$fromLine = $change['base']['offset'] + $no + 1;
											
											$line = $changedLine;
										}
										$html .= '<span class="line line-replace">'.($line == "" ? "&nbsp;" : $line).'</span><br/>';
									}
								}
							}
						}
					}
				$html .= '</pre></div><!--end of codeColumn-->';
			$html .= '</div>';
			$html .= '<div style="clear:both"></div>';
		$html .= '</div><!--end of .DiffContainer-->';
		return $html;
	}
}