<?php
/**
 * 
 */
/**
 * 
 * @author keiji
 *
 */
class ALP_ClassDefLocMap {
	const REAL_PATH_PATTERN = '/(^[a-zA-Z]:)|(^\/)/';
	const MAPPING_INFORMATION_DELIMITER = '#';
	const LINE_FEED = "\n";
	
	private $_classDefLocMap = array();
	private static $_cacheClassDefLocMap = null;
	
	private static function _getMappingLocation() {
		return dirname(__FILE__) . '/mapping.txt';
	}
	
	public function __construct($newFlag = false) {
		if (!$newFlag) {
			$this->loadMapping();
		}
	}
	
	public function getDefLocMapArray() {
		return $this->_classDefLocMap;
	}
	
	public static function getClassDefinitionLocation($className, $refleshMapInstance = false) {
		if ($refleshMapInstance || ALP_ClassDefLocMap::$_cacheClassDefLocMap === null) {
			ALP_ClassDefLocMap::$_cacheClassDefLocMap = new ALP_ClassDefLocMap();
		}
		return dirname(__FILE__) . DIRECTORY_SEPARATOR . ALP_ClassDefLocMap::$_cacheClassDefLocMap->getClassDefLoc($className);
	}
	
	public function addClassDefLoc($className, $scriptLocation) {
		$this->_classDefLocMap[$className] = ALP_ClassDefLocMap::getRelativePath($scriptLocation, dirname(__FILE__));
	}
	public function getClassDefLoc($className) {
		return isset($this->_classDefLocMap[$className]) ? $this->_classDefLocMap[$className] : null;
	}
	
	public function merge(ALP_ClassDefLocMap $targetDefLocMap) {
		$this->_classDefLocMap = array_merge($this->_classDefLocMap, $targetDefLocMap->getDefLocMapArray());
	}
	
	public function loadMapping() {
		if (file_exists(ALP_ClassDefLocMap::_getMappingLocation())) {
			$mappingText = file_get_contents(ALP_ClassDefLocMap::_getMappingLocation());
			$mappingLineArray = explode(ALP_ClassDefLocMap::LINE_FEED, $mappingText);
			foreach ($mappingLineArray as $mappingLine) {
				$mappingInformation = explode(ALP_ClassDefLocMap::MAPPING_INFORMATION_DELIMITER, $mappingLine);
				if (count($mappingInformation) == 2) {
					$this->addClassDefLoc($mappingInformation[0], $mappingInformation[1]);
				}
			}
		}
	}
	public function saveMapping($mappingLocation = null) {
		$mappingText = '';
		foreach ($this->_classDefLocMap as $className => $classLocation) {
			$mappingText .= ($className . ALP_ClassDefLocMap::MAPPING_INFORMATION_DELIMITER . $classLocation . ALP_ClassDefLocMap::LINE_FEED);
		}
		$mappingLocation = $mappingLocation === null ? ALP_ClassDefLocMap::_getMappingLocation() : $mappingLocation;
		file_put_contents($mappingLocation, $mappingText);
	}
	
	public static function getRelativePath($targetPath, $baseFolderPath) {
		if (preg_match(ALP_ClassDefLocMap::REAL_PATH_PATTERN, $targetPath)) {
			$relativePath = null;
			$targetPathArray = explode(DIRECTORY_SEPARATOR, $targetPath);
			$basePathArray = explode(DIRECTORY_SEPARATOR, $baseFolderPath);
			for ($i = 0; $i < count($basePathArray) && $i < count($targetPathArray); $i++) {
				if ($basePathArray[$i] != $targetPathArray[$i]) {
					break;
				}
			}
			for ($j = $i; $j < count($basePathArray); $j++) {
				if ($relativePath !== null) {
					$relativePath .= DIRECTORY_SEPARATOR;
				}
				$relativePath .= ('..');
			}
			for ($k = $i; $k < count($targetPathArray); $k++) {
				if ($relativePath !== null) {
					$relativePath .= DIRECTORY_SEPARATOR;
				}
				$relativePath .= ($targetPathArray[$k]);
			}
			return $relativePath;
		}
		else {
			return $targetPath;
		}
	}
	
}
?>