define(function(require) {

    var List = require('../../data/List');
    var zrUtil = require('zrender/core/util');
    var SeriesModel = require('../../model/Series');
    var completeDimensions = require('../../data/helper/completeDimensions');

    return SeriesModel.extend({

        type: 'series.parallel',

        dependencies: ['parallel'],

        getInitialData: function (option, ecModel) {
            var parallelModel = ecModel.getComponent(
                'parallel', this.get('parallelIndex')
            );
            var parallelAxisIndices = parallelModel.parallelAxisIndex;

            var rawData = option.data;
            var modelDims = parallelModel.dimensions;

            var dataDims = generateDataDims(modelDims, rawData);

            var dataDimsInfo = zrUtil.map(dataDims, function (dim, dimIndex) {

                var modelDimsIndex = zrUtil.indexOf(modelDims, dim);
                var axisModel = modelDimsIndex >= 0 && ecModel.getComponent(
                    'parallelAxis', parallelAxisIndices[modelDimsIndex]
                );

                if (axisModel && axisModel.get('type') === 'category') {
                    translateCategoryValue(axisModel, dim, rawData);
                    return {name: dim, type: 'ordinal'};
                }
                else if (modelDimsIndex < 0) {
                    return completeDimensions.guessOrdinal(rawData, dimIndex)
                        ? {name: dim, type: 'ordinal'}
                        : dim;
                }
                else {
                    return dim;
                }
            });

            var list = new List(dataDimsInfo, this);
            list.initData(rawData);

            // Anication is forbiden in progressive data mode.
            if (this.option.progressive) {
                this.option.animation = false;
            }

            return list;
        },

        /**
         * User can get data raw indices on 'axisAreaSelected' event received.
         *
         * @public
         * @param {string} activeState 'active' or 'inactive' or 'normal'
         * @return {Array.<number>} Raw indices
         */
        getRawIndicesByActiveState: function (activeState) {
            var coordSys = this.coordinateSystem;
            var data = this.getData();
            var indices = [];

            coordSys.eachActiveState(data, function (theActiveState, dataIndex) {
                if (activeState === theActiveState) {
                    indices.push(data.getRawIndex(dataIndex));
                }
            });

            return indices;
        },

        defaultOption: {
            zlevel: 0,                  // 一级层叠
            z: 2,                       // 二级层叠

            coordinateSystem: 'parallel',
            parallelIndex: 0,

            label: {
                normal: {
                    show: false
                },
                emphasis: {
                    show: false
                }
            },

            inactiveOpacity: 0.05,
            activeOpacity: 1,

            lineStyle: {
                normal: {
                    width: 1,
                    opacity: 0.45,
                    type: 'solid'
                }
            },
            progressive: false, // 100
            smooth: false,

            animationEasing: 'linear'
        }
    });

    function translateCategoryValue(axisModel, dim, rawData) {
        var axisData = axisModel.get('data');
        var numberDim = convertDimNameToNumber(dim);

        if (axisData && axisData.length) {
            zrUtil.each(rawData, function (dataItem) {
                if (!dataItem) {
                    return;
                }
                // FIXME
                // time consuming, should use hash?
                var index = zrUtil.indexOf(axisData, dataItem[numberDim]);
                dataItem[numberDim] = index >= 0 ? index : NaN;
            });
        }
        // FIXME
        // 如果没有设置axis data, 应自动算出，或者提示。
    }

    function convertDimNameToNumber(dimName) {
        return +dimName.replace('dim', '');
    }

    function generateDataDims(modelDims, rawData) {
        // parallelModel.dimension should not be regarded as data
        // dimensions. Consider dimensions = ['dim4', 'dim2', 'dim6'];

        // We detect max dim by parallelModel.dimensions and fist
        // item in rawData arbitrarily.
        var maxDimNum = 0;
        zrUtil.each(modelDims, function (dimName) {
            var numberDim = convertDimNameToNumber(dimName);
            numberDim > maxDimNum && (maxDimNum = numberDim);
        });

        var firstItem = rawData[0];
        if (firstItem && firstItem.length - 1 > maxDimNum) {
            maxDimNum = firstItem.length - 1;
        }

        var dataDims = [];
        for (var i = 0; i <= maxDimNum; i++) {
            dataDims.push('dim' + i);
        }

        return dataDims;
    }
});