<?php

class CommonChecker {
	
	public function getCommons(String $focused, String $source){
		$tokens = [];
		
		$focused = strtolower($focused);
		$source = strtolower($source);
		
		$lastIndex = strlen($source) - 1;
		$previousIndex = -1;
		
		for($i=0; $i < strlen($source); $i++){
			
			$toSearch = substr($source, $i);
			$sbuilt = "";
			
			for($k=0; $k < strlen($toSearch); $k++){
				$sbuilt .= $toSearch{$k};
				$progress = $i + $k;
				
				$a = substr($sbuilt, 0, -1);
				$builtpos = strpos($focused, $sbuilt);
				
				if($builtpos===false && !empty($a) && strpos($focused, $a) === false) break;
				
				if($builtpos===false || $progress === (strlen($source) - 1)){
					$previousPotentialCommon = substr($sbuilt, 0, strlen($sbuilt) -
							($builtpos!==false && $progress == (strlen($source) - 1) ? 0 : 1));
					
					$ppclen = strlen($previousPotentialCommon);
					
					if((!empty($previousPotentialCommon) && strpos($focused, $previousPotentialCommon)!==false) && $ppclen > 1 || ($i == $lastIndex)){
						
						if($i == $lastIndex && (strlen($focused) >= 2 && strlen($source) >= 2)){
							if($focused{0} != $source{0} || $focused{1} != $source{1}) continue;
						}
						
						$index = (!empty($previousPotentialCommon) ? strpos($focused, $previousPotentialCommon) : false);
						
						while($index !== false){
							if($ppclen == 1 && $index != (strlen($focused) - 1)){
								$index = strpos($focused, $previousPotentialCommon, $index + 1);
								continue;
							}
						
							if(isset($tokens[$previousIndex])){
								$previousToken = $tokens[$previousIndex];
								
								$ppcIndexEnd = $index + ($ppclen - 1);
								$ptIndexEnd = $previousIndex + (strlen($previousToken) - 1);
								
								if($index > $previousIndex && $ppcIndexEnd <= $ptIndexEnd){
									$index = strpos($focused, $previousPotentialCommon, $index + 1);
									continue;
								}
							}
							
							$tokens[$index] = $previousPotentialCommon;
							$previousIndex = $index;
							$index = strpos($focused, $previousPotentialCommon, $index + 1);
						}
					}
				}
			}
		}
		
		return $tokens;
	}
	
	/**
	 *
	 * @param String $focused
	 * @param String $source
	 * @param bool $nonexistent
	 * @return array
	 */
	public function commonIndices(String $focused, String $source, bool $nonexistent = false){
		$cmap = $this -> getCommons($focused, $source);
		
		$indices = [];
		foreach($cmap as $index => $value){
			for($k = $index; $k <= ($index + (strlen($value) - 1)); $k++){
				$indices[] = $k;
			}
		}
		
		if($nonexistent){
			$temp = [];
			
			for($i = 0; $i < strlen($focused); $i++){
				if (in_array($i, $indices)) {
					continue;
				} else {
					$temp[] = $i;
				}
			}
			$indices = $temp;
		}
		
		$indices = array_unique($indices);
		return $indices;
	}
	
	/**
	 *
	 * @param String $focused
	 * @param String $source
	 * @return string[]|String[]
	 */
	public function diffstring(String $focused, String $source){
		$tokens = [];
		$indices = $this -> commonIndices($focused, $source, true);
		
		$cbuild = "";
		$skip = -1;
		
		for($i=0; $i < count($indices); $i++){
			$nextelem =(isset($indices[$i + 1]) ? $indices[$i + 1] : -1);
			$missed = abs($indices[$i] - $nextelem) - 1;
			
			if($indices[$i] == strlen($focused) - 1){
				$missed = 1;
			}
			
			if($missed > 0){
				if(strlen($cbuild) > 0){
					$start = $indices[$i] - (strlen($cbuild) - 1);
					$tokens[$start] = strtolower($cbuild);
					$cbuild = "";
				}else{
					if($focused{$indices[$i]} == " "){
						continue;
					}
					$tokens[$indices[$i]] = strtolower($focused{$indices[$i]});
				}
			}else{
				if($nextelem < 0)
					continue;
					
				$cbuild .= ($indices[$i] != $skip ? $focused{$indices[$i]} : "")."{$focused{$nextelem}}";
				$skip = $nextelem;
			}
		}
			
		return $tokens;
	}
		
	/**
	 *
	 * @param String $focused
	 * @param String $source
	 * @return number
	 */
	public function difference(String $focused, String $source){
		return strlen($focused) - strlen(implode($this -> getCommons($focused, $source)));
	}
	
	public function commonlen(String $focused, String $source){
		return strlen($focused) - $this -> difference($focused, $source);
	}
	
	public function removeSpecials(&$str){
		$str = str_replace([".", "_", "-"], "", $str);
	}
	
	public function reverseStrArray(Array &$strs){
		foreach($strs as $k => $str){
			if(is_string($str))
				$strs[$k] = strrev($strs[$k]);
		}
	}
}
	
/* $cc = new CommonChecker();
echo $cc -> difference("loyquibu", "quibuloy");
print_r($cc -> getCommons("loyquibu", "quibuloy")); */
	