package doc.walkthru;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.benow.java.annotations.StringLength;
import org.benow.java.annotations.xml.XMLNodeType;
import org.benow.repository.mapping.JSQLArrayList;
import org.benow.repository.mapping.JSQLList;
import org.benow.repository.mapping.JSQLObject;
import org.benow.repository.mapping.JSQLQuery;
import org.benow.repository.mapping.JSQLFieldMapping.JSQLIgnore;
import org.benow.repository.mapping.JSQLFieldMapping.SimpleJoin;

public abstract class PerformerImpl extends JSQLObject implements Performer {

  /**
   * Wrapper for linking performer and url
   */
  public static class PerformerURL extends JSQLObject {
    public PerformerImpl performer;
    @XMLNodeType(XMLNodeType.ATTRIBUTE)
    public URL link;

    protected PerformerURL() {
      super();
    }

    public PerformerURL(PerformerImpl p, URL link) {
      super();
      this.performer = p;
      this.link = link;
    }
  }

  // serialVersionUID is used by the repository to determine when tables need changing
  private static final long serialVersionUID = 1L;
  // no limit on the length
  private String biography;
  // links, stored in repository
  @SimpleJoin("performer")
  private final JSQLList<PerformerURL> links = new JSQLArrayList<PerformerURL>(this, "links");
  // @StringLength is a hint for the repository which guides table column construction and makes for nice schema 
  @StringLength(128)
  private String name;
  @JSQLIgnore
  private List<Album> albums;

  // a zero parameter constructor is required by the repository
  protected PerformerImpl() {
    super();
  }
  
  public PerformerImpl(String name) {
    super();
    this.name=name;
  }
  
  
  @Override
  public String getBiography() {
    return biography;
  }

  @Override
  public List<Album> getDiscography() {
    // get albums done by this performer by using a query
    albums = JSQLQuery.getObjectByFieldQuery(AlbumImpl.class, "performer", this).getObjects();
    for (Album album : albums) {
      album.getTracks();
    }
    return albums;
  }

  @Override
  public List<URL> getLinks() {
    // ensure that the links field is populated.  If it is, there is very little overhead
    fetchFieldQuiet("links");
    List<URL> ulinks = new ArrayList<URL>();
    for (PerformerURL p : links)
      ulinks.add(p.link);
    return ulinks;
  }

  @Override
  public String getName() {
    return name;
  }

  public void removeLink(URL link) {
    fetchFieldQuiet("links");
    for (PerformerURL p : links) {
      if (p.link.equals(link)) {
        links.remove(p);
        break;
      }
    }
  }

  public void addLink(URL link) {
    links.add(new PerformerURL(this, link));
  }

}