<?php
/**
 * @author Silviu Schiau <pr@silviu.co>
 * @package Schiau
 * @version 2.2.2
 * @license Apache License Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 * Copyright 2014-2017 Silviu Schiau.
 *
 * This copyright notice
 * shall be included in all copies or substantial portions of the software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * 
 * 	$machineID = 0; // Machine ID (Server ID no.)
 * 	Particle::generateParticle($machineID);
 * 
 *  Time from Particle ID (milisecond precision)
 * 	$particleID = '4611692470816737853';
 * 	Particle::timeFromParticle($particleID);
 *
 */
namespace uuid;

abstract class Intuuid {

	const EPOCH          = 1479533469598;
	const max12bit       = 4095;
	const max41bit       = 1099511627775;
    static $machineId    = null;
	
	
	public static function machineId($mId) {
	    self::$machineId = $mId;
    }
	
	/**
	 * 根据服务器ID
	 *
	 * @return void
	 */
	public static function generateParticle() {
		/*
		* Time - 42 bits
		*/
		$time = floor(microtime(true) * 1000);
		/*
		* Substract custom epoch from current time
		*/
		$time -= self::EPOCH;
		/*
		* Create a base and add time to it
		*/
		$base = decbin(self::max41bit + $time);
		/*
		* Configured machine id - 10 bits - up to 1024 machines
		*/
		$machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT);
		/*
		* sequence number - 12 bits - up to 4096 random numbers per machine
		*/
		$random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT);
		/*
		* Pack
		*/
		$base = $base.$machineid.$random;
		/*
		* Return unique time id no
		*/
		return bindec($base);
    }
	
	/**
	 * 根据毫秒精度
	 *
	 * @param [type] $particle
	 * @return void
	 */
	public static function timeFromParticle($particle) {
		return bindec(substr(decbin($particle),0,41)) - self::max41bit + self::EPOCH;
	}
}