package de.frajul.endlessroll.entities.particles;

import android.content.Context;

import de.frajul.endlessroll.entities.particles.attributes.Attribute;
import de.frajul.endlessroll.entities.particles.attributes.AttributeValueReader;
import de.frajul.endlessroll.entities.particles.attributes.ParticleAttributeType;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ImagePath;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Options;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.ParticleAttributeValueType;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Range;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.SpawnShape;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.Timeline;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TimelineRange;
import de.frajul.endlessroll.entities.particles.attributes.attributeValues.TintTimeline;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Julian on 02.08.2016.
 */
public class ParticleReader {

    private Context context;
    private AttributeValueReader attributeValueReader;

    private List<Attribute> attributes;
    private Attribute currentAttribute;

    public ParticleReader(Context context) {
        this.context = context;
        attributeValueReader = new AttributeValueReader();
    }

    /**
     * reads ParticleEffect from *.pe files
     * !Ignores COUNT, LIFE_OFFSET!
     */
    public ParticleEffect read(String filename) throws Exception {
        try {
            attributes = new ArrayList<>();
            currentAttribute = null;
            InputStream is = context.getAssets().open(filename);
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                handleLine(line);
            }
            reader.close();
            return createParticleEffect();
        } catch (Exception e) {
            throw new Exception("Could not read particleFile: ", e);
        }
    }

    private void handleLine(String line) throws Exception {
        if (line.startsWith("- ")) {
            Attribute attrib = ParticleAttributeType.getByInFileTitle(line).createInstance();
            attributes.add(attrib);
            currentAttribute = attrib;
        } else if (currentAttribute != null)
            attributeValueReader.addValueForAttribute(currentAttribute, line);
    }

    private ParticleEffect createParticleEffect() throws Exception {
        ParticleEffect effect = new ParticleEffect();
        Timeline timeline = null;
        Range range = null;
        for (Attribute attribute : attributes) {
            switch (attribute.getType()) {
                case DELAY:
                    effect.setDelay((Range) attribute.get(ParticleAttributeValueType.RANGE));
                    break;
                case DURATION:
                    effect.setDuration((Range) attribute.get(ParticleAttributeValueType.RANGE));
                    break;
                case COUNT:
                    break;
                case EMISSION:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setEmission(new TimelineRange(timeline, range));
                    break;
                case LIFE:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setLife(new TimelineRange(timeline, range));
                    break;
                case LIFE_OFFSET:
                    break;
                case X_OFFSET:
                    effect.setxOffset((Range) attribute.get(ParticleAttributeValueType.RANGE));
                    break;
                case Y_OFFSET:
                    effect.setyOffset((Range) attribute.get(ParticleAttributeValueType.RANGE));
                    break;
                case SPAWN_SHAPE:
                    effect.setSpawnShape(((SpawnShape) attribute.get(ParticleAttributeValueType.SPAWN_SHAPE)).getShape());
                    break;
                case SPAWN_WIDTH:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setSpawnWidth(new TimelineRange(timeline, range));
                    break;
                case SPAWN_HEIGHT:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setSpawnHeight(new TimelineRange(timeline, range));
                    break;
                case SCALE:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setScale(new TimelineRange(timeline, range));
                    break;
                case VELOCITY:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setVelocity(new TimelineRange(timeline, range));
                    break;
                case ANGLE:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setAngle(new TimelineRange(timeline, range));
                    break;
                case ROTATION:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setRotation(new TimelineRange(timeline, range));
                    break;
                case WIND:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setWind(new TimelineRange(timeline, range));
                    break;
                case GRAVITY:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    range = (Range) attribute.get(ParticleAttributeValueType.RANGE);
                    effect.setGravity(new TimelineRange(timeline, range));
                    break;
                case TINT:
                    effect.setTint((TintTimeline) attribute.get(ParticleAttributeValueType.TINT_TIMELINE));
                    break;
                case TRANSPARENCY:
                    timeline = (Timeline) attribute.get(ParticleAttributeValueType.TIMELINE);
                    effect.setTransparency(timeline);
                    break;
                case OPTIONS:
                    effect.setOptions((Options) attribute.get(ParticleAttributeValueType.OPTIONS));
                    break;
                case IMAGE_PATH:
                    String path = ((ImagePath) attribute.get(ParticleAttributeValueType.IMAGE_PATH)).getImagePath();
                    effect.setTextureName(path);
                    break;
            }
        }
        return effect;
    }
}
