<?php
defined('_JEXEC') or die('Restricted access');

class ARTIOFusionChartsHelper
{

    function loadCategories()
    {
        $types = JFolder::folders(ARTIOFUSIONCHARTS_BASE_ABS);
        $categories = array();
        foreach ($types as $type) {
            if (($category = ARTIOFusionChartsHelper::loadCategory($type)) !== null) {
                $categories[] = $category;
            }
        }
        return $categories;
    }

    function loadCategory($type)
    {
        $file = ARTIOFusionChartsHelper::getChartMainCategoryParams($type);
        if (file_exists($file)) {
            require ($file);
            $category = new stdClass();
            $category->name = $categoryName;
            $category->base = $type;
            $charts = JFolder::folders(ARTIOFusionChartsHelper::getChartCategoryBase($type));
            $categoryCharts = array();
            foreach ($charts as $item) {
                if (($chart = ARTIOFusionChartsHelper::loadChart($item, $type)) !== null) {
                    $categoryCharts[] = $chart;
                }
            }
            $category->charts = $categoryCharts;
            return $category;
        }
        return null;
    }

    function getCategoryNamesArray($categories)
    {
        $names = array();
        foreach ($categories as $category) {
            $names[$category->base] = $category->name;
        }
        return $names;
    }

    function loadChart($item, $type, $chart = null)
    {
        $file = ARTIOFusionChartsHelper::getChartMainParams($type, $item);
        if (file_exists($file)) {
            require ($file);
            if ($chart === null) {
                $chart = new stdClass();
                $chart->params = '';
                $chart->data = array();
            }
            $chart->name = $chartName;
            $chart->chartType = $chartType;
            $chart->chartLanguages = isset($chartLanguages) ? $chartLanguages : array();
            $chart->chartSetting = isset($chartSetting) ? $chartSetting : array();
            $chart->base = $item;
            $chart->icon = ARTIOFusionChartsHelper::getChartIcon($type, $item);
            $chart->preview = ARTIOFusionChartsHelper::getChartPrewiev($type, $item);
            $chart->chart = ARTIOFusionChartsHelper::getChartFile($type, $item);
            $chart->paramsSource = ARTIOFusionChartsHelper::getChartParams($type, $item);
            $chart->paramsCategoriesSource = ARTIOFusionChartsHelper::getChartCategoriesParams($type, $item);
            $chart->paramsCategorySource = ARTIOFusionChartsHelper::getChartCategoryParams($type, $item);
            $chart->paramsDatasetSource = ARTIOFusionChartsHelper::getChartDatasetParams($type, $item);
            $chart->paramsSetSource = ARTIOFusionChartsHelper::getChartSetParams($type, $item);
            $chart->form = new JParameter('', $chart->paramsSource);
            $chart->params = ARTIOFusionChartsHelper::quote($chart->params);
            $chart->form->loadINI($chart->params);
            $chart->link = ARTIOFusionChartsHelperRoute::getCreateRoute($type, $item);
            return $chart;
        }
        return null;
    }

    function getXMLSingle($chart)
    {
        $sets = ARTIOFusionChartsHelper::renderSets($chart);
        $params = ARTIOFusionChartsHelper::renderParams($chart->params);
        $lines = $chart->chartSetting['useTrendLines'] ? ARTIOFusionChartsHelper::getXMLTrendLines($chart) : '';
        return '<' . CHART . ' ' . $params . '>' . $sets . $lines . '</' . CHART . '>';
    }

    function getXMLMulti($chart)
    {
        $categories = ARTIOFusionChartsHelper::renderCategories($chart);
        $params = ARTIOFusionChartsHelper::renderParams($chart->params);
        $lines = ARTIOFusionChartsHelper::getXMLTrendLines($chart);
        return '<' . CHART . ' ' . $params . '>' . $categories . $lines . '</' . CHART . '>';
    }

    function getXMLTrendLines($chart)
    {
        $xml = '';
        foreach ($chart->lines as $line) {
            $xml .= '<line ';
            if ($line->start_value)
                $xml .= " startValue='" . ARTIOFusionChartsHelper::quote($line->start_value) . "' ";
            if ($line->end_value)
                $xml .= " endValue='" . ARTIOFusionChartsHelper::quote($line->end_value) . "' ";
            if ($line->color)
                $xml .= " color='" . ARTIOFusionChartsHelper::quote($line->color) . "' ";
            if ($line->display)
                $xml .= " displayvalue='" . ARTIOFusionChartsHelper::quote($line->display) . "' ";
            if ($line->thickness)
                $xml .= " thickness='" . ARTIOFusionChartsHelper::quote($line->thickness) . "' ";
            $xml .= " isTrendZone='" . ARTIOFusionChartsHelper::quote($line->zone) . "' ";
            $xml .= " showOnTop='" . ARTIOFusionChartsHelper::quote($line->top) . "' ";
            if ($line->alpha)
                $xml .= " alpha='" . ARTIOFusionChartsHelper::quote($line->alpha) . "' ";
            $xml .= '/>';
        }
        return "<trendLines>$xml</trendLines>";
    }

    function getTypesNamesArray($categories)
    {
        $names = array();
        foreach ($categories as $category) {
            $namesTypes = ARTIOFusionChartsHelper::getChartsNamesArray($category);
            $names = array_merge($names, $namesTypes);
        }
        return $names;
    }

    function getChartsNamesArray($category)
    {
        $names = array();
        foreach ($category->charts as $type) {
            $names[$type->base] = $type->name;
        }
        return $names;
    }

    function importListJS()
    {
        ARTIOFusionChartsHelper::importJS('list.js');
    }

    function importFusionJS()
    {
        ARTIOFusionChartsHelper::importJS('FusionCharts.js');
    }

    function importChartJS()
    {
        ARTIOFusionChartsHelper::importJS('chart.js');
    }

    function importColorPicker()
    {
        ARTIOFusionChartsHelper::importJS('jscolor/jscolor.js');
    }

    function importJS($name)
    {
        $document = &JFactory::getDocument();
        $document->addScript(ARTIOFUSIONCHARTS_ASSETS_JS . $name);
    }

    function importLinesJS()
    {
        ARTIOFusionChartsHelper::importJS('lines.js');
    }

    function importMultiSeriesJS()
    {
        ARTIOFusionChartsHelper::importJS('multi-series.js');
    }

    function importJoomlaToolsJS()
    {
        ARTIOFusionChartsHelper::importJS('joomla-tools.js');
    }

    function importLang()
    {
        require_once (ARTIOFUSIONCHARTS_BASE_LANG . DS . 'chart.php');
    }

    function importStyle()
    {
        $document = &JFactory::getDocument();
        $document->addStyleSheet(ARTIOFUSIONCHARTS_ASSETS_CSS . 'style.css');
    }

    function renderSets($chart)
    {
        $result = '';
        if (is_array($chart->data)) {
            foreach ($chart->data as $item) {
                $result .= "<set name='" . ARTIOFusionChartsHelper::quote($item->label) . "' ";
                $result .= "value='" . ARTIOFusionChartsHelper::quote($item->value) . "' color='" . ARTIOFusionChartsHelper::quote($item->color) . "' ";
                $result .= "hoverText='" . ARTIOFusionChartsHelper::quote($item->htext) . "' link='" . ARTIOFusionChartsHelper::quote($item->link) . "' ";
                $result .= "alpha='" . ARTIOFusionChartsHelper::quote($item->alpha) . "' showName='" . ARTIOFusionChartsHelper::quote($item->show) . "' ";
                if ($chart->chartSetting['addIsSliced']) {
                    $result .= "isSliced='" . ARTIOFusionChartsHelper::quote($item->isSliced) . "' ";
                }
                $result .= "/>";
            }
        }
        return $result;
    }

    function renderCategories($chart, $addNewLines = false)
    {
        $newLine = $addNewLines ? ARTIOFUSIONCHARTS_END_LINE : '';
        $data = "<categories $chart->categoryParams>" . $newLine;
        foreach ($chart->categories as $category) {
            $data .= "<category name='" . ARTIOFusionChartsHelper::quote($category->value) . "' $category->params />" . $newLine;
        }
        $data .= '</categories>' . $newLine;
        foreach ($chart->datasets as $dataset) {
            $data .= "<dataset seriesname='" . ARTIOFusionChartsHelper::quote($dataset->value) . "' $dataset->params >" . $newLine;
            foreach ($dataset->sets as $set) {
                $data .= "<set value='" . ARTIOFusionChartsHelper::quote($set->value) . "' $set->params />" . $newLine;
            }
            $data .= '</dataset>' . $newLine;
        }
        return $data;
    }

    function renderParams($params)
    {
        $data = explode("\n", $params);
        $txt = '';
        $mustEncoded = ARTIOFusionChartsHelper::mustEncoded();
        mb_internal_encoding("UTF-8");
        foreach ($data as $item) {
            $parts = explode('=', $item);
            if (isset($parts[0]) && isset($parts[1])) {
                if (in_array($parts[0], $mustEncoded)) {
                    $parts[1] = ARTIOFusionChartsHelper::encode($parts[1]);
                }
                $txt .= " $parts[0]='$parts[1]' ";
            }
        }
        return $txt;
    }

    function mustEncoded()
    {
        return array('numberSuffix' , 'numberPrefix');
    }

    function encode($string)
    {
        $chTable = array(' ' => '%20' , '!' => '%21' , '"' => '%22' , '#' => '%23' , '$' => '%24' , '%' => '%25' , '&' => '%26' , '\'' => '%28' , '(' => '%28' , ')' => '%29' , '*' => '%2A' , '+' => '%2B' , ',' => '%2C' , '-' => '%2D' , '.' => '%2E' , '/' => '%2F' , '0' => '%30' , '1' => '%31' , '2' => '%32' , '3' => '%33' , '4' => '%34' , '5' => '%35' , '6' => '%36' , '7' => '%37' , '8' => '%38' , '9' => '%39' , ':' => '%3A' , ';' => '%3B' , '<' => '%3C' , '=' => '%3D' , '>' => '%3E' , '?' => '%3F' , '@' => '%40' , 'A' => '%41' , 'B' => '%42' , 'C' => '%43' , 'D' => '%44' , 'E' => '%45' , 'F' => '%46' , 'G' => '%47' , 'H' => '%48' , 'I' => '%49' , 'J' => '%4A' , 'K' => '%4B' , 'L' => '%4C' , 'M' => '%4D' , 'N' => '%4E' , 'O' => '%4F' , 'P' => '%50' , 'Q' => '%51' , 'R' => '%52' , 'S' => '%53' , 'T' => '%54' , 'U' => '%55' , 'V' => '%56' , 'W' => '%57' , 'X' => '%58' , 'Y' => '%59' , 'Z' => '%5A' , '[' => '%5B' , '\\' => '%5C' , ']' => '%5D' , '^' => '%5E' , '_' => '%5F' , '`' => '%60' , 'a' => '%61' , 'b' => '%62' , 'c' => '%63' , 'd' => '%64' , 'e' => '%65' , 'f' => '%66' , 'g' => '%67' , 'h' => '%68' , 'i' => '%69' , 'j' => '%6A' , 'k' => '%6B' , 'l' => '%6C' , 'm' => '%6D' , 'n' => '%6E' , 'o' => '%6F' , 'p' => '%70' , 'q' => '%71' , 'r' => '%72' , 's' => '%73' , 't' => '%74' , 'u' => '%75' , 'v' => '%76' , 'w' => '%77' , 'x' => '%78' , 'y' => '%79' , 'z' => '%7A' , '{' => '%7B' , '|' => '%7C' , '}' => '%7D' , '~' => '%7E' , '' => '%7F' , '€' => '%80' , '' => '%81' , '‚' => '%82' , 'ƒ' => '%83' , '„' => '%84' , '…' => '%85' , '†' => '%86' , '‡' => '%87' , 'ˆ' => '%88' , '‰' => '%89' , 'Š' => '%8A' , '‹' => '%8B' , 'Œ' => '%8C' , '' => '%8D' , 'Ž' => '%8E' , '' => '%8F' , '' => '%90' , '‘' => '%91' , '’' => '%92' , '“' => '%93' , '”' => '%94' , '•' => '%95' , '–' => '%96' , '—' => '%97' , '˜' => '%98' , '™' => '%99' , 'š' => '%9A' , '›' => '%9B' , 'œ' => '%9C' , '' => '%9D' , 'ž' => '%9E' , 'Ÿ' => '%9F' , '' => '%A0' , '¡' => '%A1' , '¢' => '%A2' , '£' => '%A3' , '' => '%A4' , '¥' => '%A5' , '|' => '%A6' , '§' => '%A7' , '¨' => '%A8' , '©' => '%A9' , 'ª' => '%AA' , '«' => '%AB' , '¬' => '%AC' , '¯' => '%AD' , '®' => '%AE' , '¯' => '%AF' , '°' => '%B0' , '±' => '%B1' , '²' => '%B2' , '³' => '%B3' , '´' => '%B4' , 'µ' => '%B5' , '¶' => '%B6' , '·' => '%B7' , '¸' => '%B8' , '¹' => '%B9' , 'º' => '%BA' , '»' => '%BB' , '¼' => '%BC' , '½' => '%BD' , '¾' => '%BE' , '¿' => '%BF' , 'À' => '%C0' , 'Á' => '%C1' , 'Â' => '%C2' , 'Ã' => '%C3' , 'Ä' => '%C4' , 'Å' => '%C5' , 'Æ' => '%C6' , 'Ç' => '%C7' , 'È' => '%C8' , 'É' => '%C9' , 'Ê' => '%CA' , 'Ë' => '%CB' , 'Ì' => '%CC' , 'Í' => '%CD' , 'Î' => '%CE' , 'Ï' => '%CF' , 'Ð' => '%D0' , 'Ñ' => '%D1' , 'Ò' => '%D2' , 'Ó' => '%D3' , 'Ô' => '%D4' , 'Õ' => '%D5' , 'Ö' => '%D6' , '' => '%D7' , 'Ø' => '%D8' , 'Ù' => '%D9' , 'Ú' => '%DA' , 'Û' => '%DB' , 'Ü' => '%DC' , 'Ý' => '%DD' , 'Þ' => '%DE' , 'ß' => '%DF' , 'à' => '%E0' , 'á' => '%E1' , 'â' => '%E2' , 'ã' => '%E3' , 'ä' => '%E4' , 'å' => '%E5' , 'æ' => '%E6' , 'ç' => '%E7' , 'è' => '%E8' , 'é' => '%E9' , 'ê' => '%EA' , 'ë' => '%EB' , 'ì' => '%EC' , 'í' => '%ED' , 'î' => '%EE' , 'ï' => '%EF' , 'ð' => '%F0' , 'ñ' => '%F1' , 'ò' => '%F2' , 'ó' => '%F3' , 'ô' => '%F4' , 'õ' => '%F5' , 'ö' => '%F6' , '÷' => '%F7' , 'ø' => '%F8' , 'ù' => '%F9' , 'ú' => '%FA' , 'û' => '%FB' , 'ü' => '%FC' , 'ý' => '%FD' , 'þ' => '%FE' , 'ÿ' => '%FF');
        $length = mb_strlen($string);
        $encoded = '';
        for ($i = 0; $i < $length; $i ++) {
            $char = mb_substr($string, $i, 1);
            $encoded .= isset($chTable[$char]) ? $chTable[$char] : $char;
        }
        return $encoded;
    }

    function getXMLName($id, $alias, $datetime, $real = false)
    {
        $datetime = str_replace(array(' ' , ':'), '-', $datetime);
        return ($real ? ARTIOFUSIONCHARTS_CACHE_URL : ARTIOFUSIONCHARTS_CACHE_ABS) . $id . '-' . $alias . '-' . $datetime . '.xml';
    }

    function getChart($id)
    {
        $db = &JFactory::getDBO();
        $query = "SELECT * FROM `#__artiofusioncharts` WHERE `id` = '$id'";
        $db->setQuery($query);
        $chart = $db->loadObject();
        if ($chart) {
            $datetime = $chart->modified == $db->getNullDate() ? $chart->created : $chart->modified;
            $chart->file = ARTIOFusionChartsHelper::getChartFile($chart->category, $chart->type);
            $chart->source = ARTIOFusionChartsHelper::getXMLName($chart->id, $chart->alias, $datetime, true);
        }
        return $chart;
    }

    function displayChart($chart, $mask)
    {
        if ($chart) {
            static $count;
            if (is_null($count)) {
                $count = 1;
            }
            $count ++;
            $primaryID = $mask . '-chart-' . $count;
            $secondaryID = $mask . '-chartdiv-' . $count;
            $document = &JFactory::getDocument();
            /* @var $document JDocument */
            $js = '	   var chartObj = null;' . PHP_EOL;
            $js .= '	window.addEvent(\'load\', function() {' . PHP_EOL;
            $js .= '		chartObj = new ARTIOFusionCharts("' . $chart->file . '", "ChartId", "' . $chart->width . '", "' . $chart->height . '", "0", "0");' . PHP_EOL;
            $js .= '		chartObj.setDataURL("' . $chart->source . '");' . PHP_EOL;
            $js .= '		chartObj.render("' . $secondaryID . '");' . PHP_EOL;
            $js .= '	});' . PHP_EOL;
            $document->addScriptDeclaration($js);
            return '<div id="' . $primaryID . '"><div id="' . $secondaryID . '"></div></div>';
        }
        return '<div>' . JText::_('Chart not found') . '</div>';
    }

    function exportParamsInJs($source, $var)
    {
        $js = '';
        $datasetParams = new JParameter('', $source);
        $groups = $datasetParams->getGroups();
        $attributes = $datasetParams->_xml[reset(array_keys($groups))]->_attributes;
        $width = isset($attributes['width']) ? (int) $attributes['width'] : 400;
        $height = isset($attributes['height']) ? (int) $attributes['height'] : 400;
        foreach ($groups as $name => $count) {
            $js .= $datasetParams->render('params', $name);
        }
        $js = ARTIOFusionChartsHelper::quote($js, true);
        $js = "var $var = '" . str_replace(array("\r\n" , "\n"), '', $js) . "';";
        $document = &JFactory::getDocument();
        $document->addScriptDeclaration($js);
        $document->addScriptDeclaration('var ' . $var . 'Width = ' . $width . ';');
        $document->addScriptDeclaration('var ' . $var . 'Height = ' . $height . ';');
    }

    function getMultiChartEmptyCategories(&$chart, $count)
    {
        $chart->categories = array();
        for ($i = 0; $i < $count; $i ++) {
            $chart->categories[] = ARTIOFusionChartsHelper::getEmptyObject(JText::_('Category') . ' ' . ($i + 1), true);
        }
    }

    function getSigleChartEmptySet(&$chart, $columnCount)
    {
        $chart->data = array();
        for ($i = 0; $i < $columnCount; $i ++) {
            $column = new stdClass();
            $column->label = $chart->chartSetting['sampleMask'] . ' ' . ($i + 1);
            $column->value = rand(50, 150);
            $column->color = ARTIOFusionChartsHelper::getColor();
            $column->alpha = 100;
            $column->htext = '';
            $column->link = '';
            $column->show = 1;
            $column->isSliced = rand(0, 1);
            $chart->data[] = $column;
        }
    }

    function getMultiChartEmptyDataset(&$chart, $categoryCount, $datasetCount)
    {
        $chart->datasets = array();
        for ($i = 0; $i < $datasetCount; $i ++) {
            $dataset = ARTIOFusionChartsHelper::getEmptyObject(JText::_('Dataset') . ' ' . ($i + 1));
            $dataset->sets = array();
            for ($j = 0; $j < $categoryCount; $j ++) {
                $dataset->sets[] = ARTIOFusionChartsHelper::getEmptyObject(rand(50, 150), true);
            }
            $chart->datasets[] = $dataset;
        }
    }

    function getEmptyObject($value, $noColor = false)
    {
        $object = new stdClass();
        $object->value = $value;
        $object->params = '';
        if (! $noColor) {
            $object->params = "color='" . ARTIOFusionChartsHelper::getColor() . "'";
        }
        return $object;
    }

    function getColor()
    {
        static $poll;
        if (is_null($poll)) {
            $poll = &ARTIOFusionChartsHelper::getColorsPoll();
        }
        static $index;
        if (is_null($index) || ($index == (count($poll) - 1))) {
            $index = 0;
        } else {
            $index ++;
        }
        $color = isset($poll[$index]) ? $poll[$index] : '';
        return $color;
    }

    function getColorsPoll()
    {
        static $colors;
        if (is_null($colors)) {
            $colors = array('AFD8F8' , 'F6BD0F' , '8BBA00' , 'FF8E46' , '008E8E' , 'D64646' , '8E468E' , '588526' , 'B3AA00' , '008ED6' , '9D080D' , 'A186BE' , 'CC6600' , 'FDC689' , 'ABA000' , 'F26D7D' , 'FFF200' , '0054A6' , 'F7941C' , 'CC3300' , '006600' , '663300' , '6DCFF6');
        }
        return $colors;
    }

    function importColorsToJS()
    {
        $colors = &ARTIOFusionChartsHelper::getColorsPoll();
        foreach ($colors as $i => $color) {
            $colors[$i] = '"' . $color . '"';
        }
        $js = 'var afcolors = new Array(' . implode(',', $colors) . ');';
        $document = &JFactory::getDocument();
        /* @var $document JDocument */
        $document->addScriptDeclaration($js);
    }

    function informAboutCacheDir()
    {
        $msg = '';
        if (! file_exists(ARTIOFUSIONCHARTS_CACHE_ABS)) {
            $msg = 'Cache directory %DIR% not exists. Cannot save the chart XML file.';
        } elseif (! is_writable(ARTIOFUSIONCHARTS_CACHE_ABS)) {
            $msg = 'Cache directory %DIR% is unwriteable. Cannot save the chart XML file.';
        }
        if ($msg) {
            $mainframe = &JFactory::getApplication();
            /* @var $mainframe JApplication */
            $msg = JText::_($msg);
            $msg = str_replace('%DIR%', ARTIOFUSIONCHARTS_CACHE_ABS, $msg);
            $mainframe->enqueueMessage($msg, 'notice');
        }
    }

    function quote($string, $onlyDoubleQuote = false)
    {
        if (! $onlyDoubleQuote) {
            $string = str_replace('"', '&#034;', $string);
        }
        return str_replace("'", '&#039;', $string);
    }

    function getChartCategoryBase($category)
    {
        return ARTIOFUSIONCHARTS_BASE_ABS . DS . $category;
    }

    function getChartMainCategoryParams($category)
    {
        return ARTIOFusionChartsHelper::getChartCategoryBase($category) . DS . 'params.php';
    }

    function getChartBaseAbs($type, $item)
    {
        return ARTIOFUSIONCHARTS_BASE_ABS . DS . $type . DS . $item . DS;
    }

    function getChartBaseUrl($type, $item)
    {
        return ARTIOFUSIONCHARTS_BASE_URL . '/' . $type . '/' . $item . '/';
    }

    function getChartIcon($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseUrl($type, $item) . 'icon.png';
    }

    function getChartPrewiev($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseUrl($type, $item) . 'preview.jpg';
    }

    function getChartFile($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseUrl($type, $item) . CHART_FILE . '_chart.swf';
    }

    function getChartParams($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseAbs($type, $item) . 'params.xml';
    }

    function getChartCategoriesParams($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseAbs($type, $item) . 'params-categories.xml';
    }

    function getChartCategoryParams($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseAbs($type, $item) . 'params-category.xml';
    }

    function getChartDatasetParams($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseAbs($type, $item) . 'params-dataset.xml';
    }

    function getChartSetParams($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseAbs($type, $item) . 'params-set.xml';
    }

    function getChartMainParams($type, $item)
    {
        return ARTIOFusionChartsHelper::getChartBaseAbs($type, $item) . 'params.php';
    }
}
?>
















