/*
    TODO
        Ass support for AOP (low proiroty)
*/

use token::Token as Token;
use common::ParseError as ParseError;
use type_name;
use type_name::TypeName as TypeName;

mod test;

pub struct 
 {
    pub type_name: TypeName,
    dependencies: Vec<TypeName>
}

impl Def {
    pub fn accessor_at(&self, index: usize) -> &TypeName {
        &self.dependencies[index]
    }
}

pub fn get_def(tokens: &Vec<Token>, start: usize) -> (Result<Box<Def>, ParseError>, usize) {
    let (type_name_result, seek) = type_name::get_type_name(&tokens, start);
    return match type_name_result {
        Err(e) => (Err(e), seek),
        Ok(type_name) => after_type_name(&tokens, seek, type_name)
    }
}

fn after_type_name(tokens: &Vec<Token>, start: usize, type_name: Box<TypeName>) -> (Result<Box<Def>, ParseError>, usize) {
    let def = Box::new(Def {
        type_name: *type_name,
        dependencies: Vec::new()
    });
    if tokens[start].text == ":" {
        return dependency(&tokens, start + 1, def);
    }
    return (Ok(def), start);
}

fn dependency(tokens: &Vec<Token>, start: usize, mut def: Box<Def>) -> (Result<Box<Def>, ParseError>, usize) {
    let (type_name_result, seek) = type_name::get_type_name(&tokens, start);
    return match type_name_result {
        Err(e) => (Err(e), seek),
        Ok(type_name) => {
            def.dependencies.push(*type_name);
            if tokens[seek].text == "," {
                return dependency(&tokens, seek + 1, def);
            } else {
                (Ok(def), seek)
            }
        }
    }
}

Def