#!/usr/bin/perl -w
# ABSTRACT: A command-line tool for FM synthesis and effects

use 5.018;

use strict;

use Carp;

use Audio::Signal::Preset;

use Data::Dumper;

use constant (
  EPSILON => 0.000001,
  TIMEOUT => 14400.0,
);

use Audio::Signal::Synth;
use Audio::Signal::Tone::Pluck;
use Audio::Signal::Tone::Sine;
use Audio::Signal::Tone::Square;
use Audio::Signal::Tone::Triangle;
use Audio::Signal::Tone::Noise;
use Audio::Signal::Tone::Sawtooth;
use Audio::Signal::Tone::Trapezium;
use Audio::Signal::Tone::Exp;
use Audio::Signal::Tone::WhiteNoise;
use Audio::Signal::Tone::PinkNoise;
use Audio::Signal::Tone::BrownNoise;
use Audio::Signal::Tone::TPDFNoise;
use Audio::Signal::Effect::Fade;
use Audio::Signal::Effect::Chorus;
use Audio::Signal::Effect::Delay;
use Audio::Signal::Effect::Echo;
use Audio::Signal::Effect::Echos;
use Audio::Signal::Effect::Flanger;
use Audio::Signal::Effect::Overdrive;
use Audio::Signal::Effect::Phaser;

{ package Audio::Signal;
    
    use Carp;
    
    use Moose;
    use Moose::Util::TypeConstraints;
    
    use Getopt::Long;
    
    use YAML::Tiny;
        
    use constant DEFAULT_FORMAT => 'YAML';
        
    enum 'Format', [qw(YAML XML JSON)];
    
    has 'format' => (
        is => 'rw',
        isa => 'Format',
    );
    
    has 'preset' => (
        is => 'rw',
        isa => 'Audio::Signal::Preset',
    );
    
    sub get_options {
        my $self = shift;    
        my $opt_format = DEFAULT_FORMAT;
        eval {
            GetOptions('format=s' => \$opt_format);
            $self->format($opt_format);
        };
      
        die "Regrettably, this is not a valid format option.  Choose one of ( [o] YAML, [x] JSON or [x] XML." if $@;
      
        return(0);
    }
    
    sub begin {
        my $self = shift;
        $self->get_options();
        return(0);
    }
    
    sub capture {
        my @lines = <>;
        my $diamond = "@lines";
        
        if($diamond) {
            return($diamond);
        } else {
            return(0);
        }
    }
    
    sub parse {
        my $self = shift;
        $self->preset(Audio::Signal::Preset->new(format => $self->format,diamond => $self->capture));
        if($self->preset->parse()) {
            return(1);
        } else {
            return(0);
        }
    }
    
    sub proc {
        my $self = shift;
        
        return($self->preset->proc());
    }
    
    sub gencmd {
        my $self = shift;
        my $class = shift;
        
        my @cmds;
        
        for my $synth (@{$self->preset->synths}) {            
            push(@cmds,join(' ',$self->preset->process,$self->preset->handle,$synth->gencmd()));            
        }
               
        return(@cmds);
    }
}

1;
