<?php
/* SVN FILE: $Id$ */
/**
 * SassString class file.
 * @author      Chris Yates <chris.l.yates@gmail.com>
 * @copyright   Copyright (c) 2010 PBM Web Development
 * @license      http://phamlp.googlecode.com/files/license.txt
 * @package      PHamlP
 * @subpackage  Sass.script.literals
 */

require_once 'SassLiteral.php';

/**
 * SassString class.
 * Provides operations and type testing for Sass strings.
 * @package      PHamlP
 * @subpackage  Sass.script.literals
 */
class SassString extends SassLiteral
{
  const MATCH = '/^(((["\'])(.*?)(\3))|(-[a-zA-Z-]+[^\s]*?))/i';
  const _MATCH = '/^(["\'])(.*?)(\1)?$/'; // Used to match strings such as "Times New Roman",serif
  const VALUE = 2;
  const QUOTE = 3;

  /**
   * @var string string quote type; double or single quotes, or unquoted.
   */
  public $quote;

  /**
   * class constructor
   * @param string string
   * @return SassString
   */
  public function __construct($value)
  {
    preg_match(self::_MATCH, $value, $matches);
    if ((isset($matches[self::QUOTE]))) {
      $this->quote =  $matches[self::QUOTE];
      $this->value = $matches[self::VALUE];
    } else {
      $this->quote =  '';
      $this->value = $value;
    }
  }

  /**
   * String addition.
   * Concatenates this and other.
   * The resulting string will be quoted in the same way as this.
   * @param sassString string to add to this
   * @return sassString the string result
   */
  public function op_plus($other)
  {
    $this->value .= $other->value;

    return $this;
  }

  /**
   * String multiplication.
   * this is repeated other times
   * @param sassNumber $other the number of times to repeat this
   * @return sassString the string result
   */
  public function op_times($other)
  {
    if (!($other instanceof SassNumber) || !$other->isUnitless()) {
      throw new SassStringException('Value must be a unitless number', SassScriptParser::$context->node);
    }
    $this->value = str_repeat($this->value, $other->value);

    return $this;
  }

  /**
   * Equals - works better
   */
  public function op_eq($other)
  {
    return new SassBoolean($this->value == $other->value || $this->toString() == $other->toString());
  }

  /**
   * Evaluates the value as a boolean.
   */
  public function toBoolean()
  {
    $value = strtolower(trim($this->value, ' "\''));
    if (!$value || in_array($value, array('false', 'null', '0'))) {
      return FALSE;
    }

    return TRUE;
  }

  /**
   * Returns the value of this string.
   * @return string the string
   */
  public function getValue()
  {
    return $this->value;
  }

  /**
   * Returns a string representation of the value.
   * @return string string representation of the value.
   */
  public function toString()
  {
    if ($this->quote) {
        $value = $this->quote . $this->value . $this->quote;
    } else {
        $value = strlen(trim($this->value)) ? trim($this->value) : $this->value;
    }

    return $value;
  }

  public function toVar()
  {
    return SassScriptParser::$context->getVariable($this->value);
  }

  public function getTypeOf()
  {
    if (SassList::isa($this->toString())) {
      return 'list';
    }

    return 'string';
  }

  /**
   * Returns a value indicating if a token of this type can be matched at
   * the start of the subject string.
   * @param string the subject string
   * @return mixed match at the start of the string or false if no match
   */
  public static function isa($subject)
  {
    return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
  }
}
