package au.com.codeka.warworlds.common.sim;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;

import java.util.List;

import javax.annotation.Nullable;

import au.com.codeka.warworlds.common.proto.Building;
import au.com.codeka.warworlds.common.proto.Colony;
import au.com.codeka.warworlds.common.proto.Design;

/**
 * Helper class for working with ship and building designs.
 */
public class DesignHelper {
  /** Gets a list of all the {@link Design}s we have. */
  public static List<Design> getDesigns() {
    return DesignDefinitions.designs.designs;
  }

  /** Gets a list of all the {@link Design}s of the given {@link Design.DesignKind} we have. */
  public static Iterable<Design> getDesigns(final Design.DesignKind kind) {
    return Iterables.filter(getDesigns(), new Predicate<Design>() {
      @Override
      public boolean apply(@Nullable Design design) {
        return design != null && design.design_kind.equals(kind);
      }
    });
  }

  /** Gets the {@link Design} with the given identifier. */
  public static Design getDesign(Design.DesignType type) {
    for (Design design : getDesigns()) {
      if (design.type.equals(type)) {
        return design;
      }
    }

    throw new IllegalStateException("No design with id=" + type + " found.");
  }

  /** Gets the display name of the given design, correctly pluralized. */
  public static String getDesignName(Design design, boolean plural) {
    return design.display_name + (plural ? "s" : "");
  }

  public static String getDependenciesHtml(Colony colony, Design design) {
    return getDependenciesHtml(colony, design, 0);
  }

  /**
   * Returns the dependencies of the given design a string for display to the user. Dependencies
   * that we don't meet will be coloured red, those that we meet with be green.
   */
  // TODO: localize this string
  public static String getDependenciesHtml(Colony colony, Design design, int level) {
    String required = "Required: ";
    List<Design.Dependency> dependencies = design.dependencies;
    if (level > 1) {
      dependencies = design.upgrades.get(level - 2).dependencies;
    }

    if (dependencies == null || dependencies.size() == 0) {
      required += "none";
    } else {
      int n = 0;
      for (Design.Dependency dep : dependencies) {
        if (n > 0) {
          required += ", ";
        }

        boolean isMet = false;
        for (Building building : colony.buildings) {
          if (building.design_type.equals(dep.type) && building.level >= dep.level) {
            isMet = true;
            break;
          }
        }

        Design dependentDesign = getDesign(dep.type);
        required += "<font color=\""+(isMet ? "green" : "red")+"\">";
        required += dependentDesign.display_name;
        if (dep.level > 1) {
          required += " lvl " + dep.level;
        }
        required += "</font>";
        n++;
      }
    }

    return required;
  }
}

@@ -1957,16 +1957,23 @@
   String
+Builder
  require
@@ -1976,16 +1976,57 @@
 uired = 
+new StringBuilder();%0A    required.append(
 %22Require
@@ -2029,16 +2029,17 @@
 uired: %22
+)
 ;%0A    Li
@@ -2268,18 +2268,23 @@
 ired
- += 
+.append(
 %22none%22
+)
 ;%0A  
@@ -2405,16 +2405,21 @@
 ired
- += 
+.append(
 %22, %22
+)
 ;%0A  
@@ -2735,20 +2735,24 @@
 required
- += 
+.append(
 %22%3Cfont c
@@ -2763,40 +2763,91 @@
 =%5C%22%22
-+(isMet ? %22green%22 : %22red%22)+
+);%0A        required.append(isMet ? %22green%22 : %22red%22);%0A        required.append(
 %22%5C%22%3E%22
+)
 ;%0A  
@@ -2860,20 +2860,24 @@
 required
- += 
+.append(
 dependen
@@ -2896,16 +2896,17 @@
 lay_name
+)
 ;%0A      
@@ -2950,22 +2950,52 @@
 ired
- += %22 lvl %22 + 
+.append(%22 lvl %22);%0A          required.append(
 dep.
@@ -2999,16 +2999,17 @@
 ep.level
+)
 ;%0A      
@@ -3032,12 +3032,16 @@
 ired
- += 
+.append(
 %22%3C/f
@@ -3045,16 +3045,17 @@
 %3C/font%3E%22
+)
 ;%0A      
@@ -3095,16 +3095,27 @@
 required
+.toString()
 ;%0A  %7D%0A%7D%0A

Switch to StringBuilder