/**
  * Grabs background images with no-repeat attribute from css and merge them in one file called a sprite.
  * Css is updated with sprite url and correct background positions for affected images.
  * Sprite saved in {Joomla! base}/images/jch-optimize/
  *
  * @param string $sCss       Aggregated css file before sprite generation
  * @param string $sLnEnd     Document line end
  * @return string           Css updated with sprite information on success. Original css on failure
  */
 protected function generateSprite($sCss, $sLnEnd)
 {
     if (extension_loaded('imagick') && extension_loaded('exif')) {
         $sImageLibrary = 'imagick';
     } else {
         if (!extension_loaded('gd') || !extension_loaded('exif')) {
             return $sCss;
         }
         $sImageLibrary = 'gd';
     }
     $iMinMaxImages = $this->params->get('csg_min_max_images', 0);
     $sDelStart = '~';
     $sRegexStart = '(?:(?<=^|})
                         (?=([^{]+?)({[^}]+?(url\\(([^}]+?\\.(?:png|gif|jpe?g))[^}]*?\\))[^}]+?}))
                         (?:(?!(?:\\s(?<!no-)repeat(?:-(?:x|y))?)|(?:background[^;]+?(?:\\s(?:left|right|center|top|bottom)';
     $sRegexMin = '|(?:\\s0)|(?:\\s\\d{1,5}(?:%|in|(?:c|m)m|e(?:m|x)|p(?:t|c|x)))){1,2}[^;]*?;)';
     $sRegexMax = '|(?:\\s[1-9]\\d{0,4}(?:%|in|(?:c|m)m|e(?:m|x)|p(?:t|c|x)))){1,2}[^;]*?;)';
     $sRegexEnd = ')[^}])*?})';
     $sDelEnd = '~sx';
     $aIncludeImages = $this->getArray($this->params->get('csg_include_images'));
     $aExcludeImages = $this->getArray($this->params->get('csg_exclude_images'));
     $sIncImagesRegex = '';
     if (!empty($aIncludeImages[0]) && !$iMinMaxImages) {
         foreach ($aIncludeImages as $sIncImage) {
             $sIncImage = str_replace('.', '\\.', $sIncImage);
             $sIncImagesRegex .= '|(?:(?<=^|})([^{]+?){[^}]+?(url\\(([^}]+?' . $sIncImage . ')[^}]*?\\))[^}]*?})';
         }
     }
     $sExImagesRegex = '';
     if (!empty($aExcludeImages[0]) && $iMinMaxImages) {
         foreach ($aExcludeImages as $sExImage) {
             $sExImage = str_replace('.', '\\.', $sExImage);
             $sExImagesRegex .= '|(?:\\b' . $sExImage . ')';
         }
     }
     $sMinMaxRegex = $iMinMaxImages ? $sRegexMax : $sRegexMin;
     $sRegex = $sDelStart . $sRegexStart . $sMinMaxRegex . $sExImagesRegex . $sRegexEnd . $sIncImagesRegex . $sDelEnd;
     $iResult = preg_match_all($sRegex, $sCss, $aMatches);
     //print_r($aMatches);
     if ($iResult <= 0) {
         return $sCss;
     }
     require_once dirname(__FILE__) . DS . 'cache' . DS . 'css-sprite-gen.inc.php';
     $aDeclaration = $aMatches[2];
     $aImages = $aMatches[4];
     //print_r($aDeclaration);
     //print_r($sImages);
     $aFormValues = array();
     $aFormValues['wrap-columns'] = $this->params->get('csg_wrap_images', 'off');
     $aFormValues['build-direction'] = $this->params->get('csg_direction', 'vertical');
     $aFormValues['image-output'] = $this->params->get('csg_file_output', 'PNG');
     $oSpriteGen = new CssSpriteGen($sImageLibrary, $aFormValues);
     $aImageTypes = $oSpriteGen->GetImageTypes();
     $oSpriteGen->CreateSprite($aImages);
     $aSpriteCss = $oSpriteGen->GetCssBackground();
     //print_r($aSpriteCss);
     $aNeedles = array();
     $aReplacements = array();
     $sImageSelector = '';
     $sBaseUrl = JURI::base(true);
     $sBaseUrl = $sBaseUrl == '/' ? $sBaseUrl : $sBaseUrl . '/';
     for ($i = 0; $i < count($aSpriteCss); $i++) {
         if (@$aSpriteCss[$i]) {
             $aNeedles[] = $aDeclaration[$i];
             preg_match('~(?<=background)(?:[^;]+?)(
                         (?<!/)\\b(?:aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|purple|red|silver|teal|white|yellow)\\b(?!/)
                         |\\#[a-fA-F\\d]{3,6}
                         |rgb\\([^\\)]+?\\))
                         (?:[^;]*?);~ix', $aDeclaration[$i], $aBgColor);
             preg_match('~(?<=background)(?:[^;]+?)\\s(
                             scroll|fixed
                             )\\s(?:(?:[^;]+?)?;)~ix', $aDeclaration[$i], $aBgAttach);
             $sBgImage = 'url(' . $sBaseUrl . 'images/jch-optimize/' . $oSpriteGen->GetSpriteFilename() . ')';
             $sBackground = 'background: ' . @$aBgColor[1] . ' ' . $sBgImage . ' ' . @$aBgAttach[1] . ' ' . $aSpriteCss[$i] . ' no-repeat; ';
             $sDecUnique = preg_replace('~background[^;]+?;~sx', '', $aDeclaration[$i]);
             $aReplacements[] = str_replace('{', '{' . $sLnEnd . $sBackground, $sDecUnique);
         }
     }
     $sCss = str_replace($aNeedles, $aReplacements, $sCss);
     //$sCss    =   $sImageSelector.'{background-image:'.$sBgImage.');}'.$sCss;
     return $sCss;
 }