<?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information please see
 * <http://phing.info>.
*/

include_once 'C:\Lib\csstidy-1.3\class.csstidy.php';
include_once 
'phing/filters/BaseParamFilterReader.php';
include_once 
'phing/filters/ChainableReader.php';

/**
 * This filter uses the PHP package CssTidy.  This file was modeled after the XsltFilter and TidyFilter included with Phing.
 * 
 * <p>
 * Sample build.xml target:<br/>
 * <pre>
 *     <target name="pack-css">
 *        <copy todir="./Web/css" overwrite="true">
 *            <fileset dir="../Web/css">
 *                <include name="*.css" />
 *            </fileset>
 *
 *            <filterchain>
 *                <filterreader classname="phing.filters.CssTidyFilter">
 *                    <param name="remove_last_;" value="true"/>
 *                    <param name="preserveCss" value="false"/>
 *                    <param name="template" value="high_compression"/>
 *                </filterreader>
 *            </filterchain>
 *        </copy>
 *    </target>
 * </pre>
 * 
 * @author Zach Leatherman <http://www.zachleat.com>
 * @version   $Revision: 1.0 $ $Date: 2007/08/10 23:29 $
 * @package   phing.filters
 */
class CssTidyFilter extends BaseParamFilterReader implements ChainableReader {

    private 
$removeBackslashes// true
    
private $compressColors// true
    
private $compressFontWeight// true
    
private $lowercaseSelectors// false
    
private $optimizeShorthand// 1 ?
    
private $removeLastSemicolon// false
    
private $propertyCase// 1 (default) for lower, 2 for upper, else for neither
    
private $sortProperties// false
    
private $sortSelectors// false
    
private $mergeSelectors//  1 for explode multiple selectors, 2 (default) tries to merge, else for neither
    
private $discardInvalidProperties// false
    
private $cssLevel// CSS2.1
    
private $preserveCss// false
    
private $timestamp// false, adds a timestamp to output
    
private $template// compression level, low_compression, default (default), high_compression, highest_compression

    
public function setRemoveBackslashes($v) {
        
$this->removeBackslashes $v;
    }
    public function 
setCompressColors($v) {
        
$this->compressColors $v;
    }
    public function 
setCompressFontWeight($v) {
        
$this->compressFontWeight $v;
    }
    public function 
setLowercaseSelectors($v) {
        
$this->lowercaseSelectors $v;
    }
    public function 
setOptimizeShorthand($v) {
        
$this->optimizeShorthand $v;
    }
    public function 
setRemoveLastSemicolon($v) {
        
$this->removeLastSemicolon $v;
    }
    public function 
setPropertyCase($v) {
        
$this->propertyCase $v;
    }
    public function 
setSortProperties($v) {
        
$this->sortProperties $v;
    }
    public function 
setSortSelectors($v) {
        
$this->sortSelectors $v;
    }
    public function 
setMergeSelectors($v) {
        
$this->mergeSelectors $v;
    }
    public function 
setDiscardInvalidProperties($v) {
        
$this->discardInvalidProperties $v;
    }
    public function 
setCssLevel($v) {
        
$this->cssLevel $v;
    }
    public function 
setPreserveCss($v) {
        
$this->preserveCss $v;
    }
    public function 
setTimestamp($v) {
        
$this->timestamp $v;
    }
    public function 
setTemplate($v) {
        
$this->template $v;
    }

    public function 
getRemoveBackslashes() {
        return 
$this->removeBackslashes;
    }
    public function 
getCompressColors() {
        return 
$this->compressColors;
    }
    public function 
getCompressFontWeight() {
        return 
$this->compressFontWeight;
    }
    public function 
getLowercaseSelectors() {
        return 
$this->lowercaseSelectors;
    }
    public function 
getOptimizeShorthand() {
        return 
$this->optimizeShorthand;
    }
    public function 
getRemoveLastSemicolon() {
        return 
$this->removeLastSemicolon;
    }
    public function 
getPropertyCase() {
        return 
$this->propertyCase;
    }
    public function 
getSortProperties() {
        return 
$this->sortProperties;
    }
    public function 
getSortSelectors() {
        return 
$this->sortSelectors;
    }
    public function 
getMergeSelectors() {
        return 
$this->mergeSelectors;
    }
    public function 
getDiscardInvalidProperties() {
        return 
$this->discardInvalidProperties;
    }
    public function 
getCssLevel() {
        return 
$this->cssLevel;
    }
    public function 
getPreserveCss() {
        return 
$this->preserveCss;
    }
    public function 
getTimestamp() {
        return 
$this->timestamp;
    }
    public function 
getTemplate() {
        return 
$this->template;
    }
    
    
/**
     * Reads input and returns CssTidy-filtered output.
     * 
     * @return the resulting stream, or -1 if the end of the resulting stream has been reached
     * 
     * @throws IOException if the underlying stream throws an IOException
     *                        during reading     
     */
    
function read($len null) {
        
        if (!
class_exists('csstidy')) {
            throw new 
BuildException("You must include the csstidy class before you can use the CssTidyFilter.");
        }
        if ( !
$this->getInitialized() ) {
            
$this->_initialize();
            
$this->setInitialized(true);
        }

        
$_css null;
        while ( (
$data $this->in->read($len)) !== -)
            
$_css .= $data;

        if (
$_css === null ) { // EOF?
            
return -1;
        }

        
$out '';
        try {
            
$css = new csstidy();
            if(!empty(
$this->removeBackslashes))
                
$css->set_cfg('remove_blash',$this->removeBackslashes=='true'?true:false);
            if(!empty(
$this->compressColors))
                
$css->set_cfg('compress_colors',$this->compressColors=='true'?true:false);
            if(!empty(
$this->compressFontWeight))
                
$css->set_cfg('compress_font-weight',$this->compressFontWeight=='true'?true:false);
            if(!empty(
$this->lowercaseSelectors))
                
$css->set_cfg('lowercase_s',$this->lowercaseSelectors=='true'?true:false);
            if(!empty(
$this->optimizeShorthand))
                
$css->set_cfg('optimise_shorthands',intval($this->optimizeShorthand));
            if(!empty(
$this->removeLastSemicolon))
                
$css->set_cfg('remove_last_;',$this->removeLastSemicolon=='true'?true:false);
            if(!empty(
$this->propertyCase))
                
$css->set_cfg('case_properties',intval($this->propertyCase));
            if(!empty(
$this->sortProperties))
                
$css->set_cfg('sort_properties',$this->sortProperties=='true'?true:false);
            if(!empty(
$this->sortSelectors))
                
$css->set_cfg('sort_selectors',$this->sortSelectors=='true'?true:false);
            if(!empty(
$this->mergeSelectors))
                
$css->set_cfg('merge_selectors',intval($this->mergeSelectors));
            if(!empty(
$this->discardInvalidProperties))
                
$css->set_cfg('discard_invalid_properties',$this->discardInvalidProperties=='true'?true:false);
            if(!empty(
$this->cssLevel))
                
$css->set_cfg('css_level',$this->cssLevel);
            if(!empty(
$this->preserveCss))
                
$css->set_cfg('preserve_css',$this->preserveCss=='true'?true:false);
            if(!empty(
$this->timestamp))
                
$css->set_cfg('timestamp',$this->timestamp=='true'?true:false);
            if(!empty(
$this->template))
                
$css->load_template($this->template);

            
$css->parse($_css);
            
$out $css->print->plain();
        } catch (
Exception $e) {            
            throw new 
BuildException($e);
        }

        return 
$out;
    }


    
/**
     * Creates a new CssTidyFilter using the passed in Reader for instantiation.
     * 
     * @param reader A Reader object providing the underlying stream.
     *               Must not be <code>null</code>.
     * 
     * @return a new filter based on this configuration, but filtering
     *         the specified reader
     */
    
public function chain(Reader $reader) {
        
$newFilter = new CssTidyFilter($reader);
        
$newFilter->setInitialized(true);
        
$newFilter->setRemoveBackslashes($this->getRemoveBackslashes());
        
$newFilter->setCompressColors($this->getCompressColors());
        
$newFilter->setCompressFontWeight($this->getCompressFontWeight());
        
$newFilter->setLowercaseSelectors($this->getLowercaseSelectors());
        
$newFilter->setOptimizeShorthand($this->getOptimizeShorthand());
        
$newFilter->setRemoveLastSemicolon($this->getRemoveLastSemicolon());
        
$newFilter->setPropertyCase($this->getPropertyCase());
        
$newFilter->setSortProperties($this->getSortProperties());
        
$newFilter->setSortSelectors($this->getSortSelectors());
        
$newFilter->setMergeSelectors($this->getMergeSelectors());
        
$newFilter->setDiscardInvalidProperties($this->getDiscardInvalidProperties());
        
$newFilter->setCssLevel($this->getCssLevel());
        
$newFilter->setPreserveCss($this->getPreserveCss());
        
$newFilter->setTimestamp($this->getTimestamp());
        
$newFilter->setTemplate($this->getTemplate());
        return 
$newFilter;
    }
    
    
/**
     * Initializes any parameters (e.g. config options).
     * This method is only called when this filter is used through a <filterreader> tag in build file.
     */
    
private function _initialize() {        
        
$params $this->getParameters();
        if ( 
$params !== null ) {
            for(
$i 0$_i=count($params) ; $i $_i$i++) {
                if ( 
$params[$i]->getType() === null ) {
                    if (
$params[$i]->getName() === "remove_blash") {
                        
$this->setRemoveBackslashes($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "compress_colors") {
                        
$this->setCompressColors($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "compress_font-weight") {
                        
$this->setCompressFontWeight($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "lowercase_s") {
                        
$this->setLowercaseSelectors($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "optimise_shorthands") {
                        
$this->setOptimizeShorthand($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "remove_last_;") {
                        
$this->setRemoveLastSemicolon($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "case_properties") {
                        
$this->setPropertyCase($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "sort_properties") {
                        
$this->setSortProperties($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "sort_selectors") {
                        
$this->setSortSelectors($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "merge_selectors") {
                        
$this->setMergeSelectors($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "discard_invalid_properties") {
                        
$this->setDiscardInvalidProperties($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "css_level") {
                        
$this->setCssLevel($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "preserve_css") {
                        
$this->setPreserveCss($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "timestamp") {
                        
$this->setTimestamp($params[$i]->getValue());
                    } elseif (
$params[$i]->getName() === "template") {
                        
$this->setTemplate($params[$i]->getValue());
                    }
                }
            }
        }
    }
}