package powerups;

import models.Activation;
import models.Club;
import models.PowerupModel;
import play.twirl.api.Html;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public abstract class Powerup implements Serializable {

    Club club;
    public PowerupModel model;

    public Powerup(Club club, PowerupModel model) {
        this.club = club;
        this.model = model;
    }

    public abstract Html render();

    public static Powerup getPowerup(Activation activation) {
        PowerupModel powerupModel = PowerupModel.find.byId(activation.key.powerupId);
        Club club = Club.find.byId(activation.key.clubId);

        try {
            @SuppressWarnings("unchecked")
            Class<? extends Powerup> c = (Class<? extends Powerup>) Class.forName("powerups." + powerupModel.className);
            Constructor<? extends Powerup> constructor = c.getDeclaredConstructor(Club.class, PowerupModel.class);
            return constructor.newInstance(club, powerupModel);
        } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}

@@ -300,18 +300,233 @@
     
-Club club;
+/**%0A     * Private access as no Powerup should ever be able to change the name of a Club.%0A     */%0A    private final Club club;%0A%0A    /**%0A     * Final, as no view should ever have access to modify its own model runtime.%0A     */
 %0A   
@@ -529,24 +529,30 @@
 %0A    public 
+final 
 PowerupModel
@@ -568,152 +568,1193 @@
     
-public Powerup(Club club, PowerupModel model) %7B%0A        this.club = club;%0A        this.model = model;%0A    %7D%0A%0A    public abstract Html render();%0A
+/**%0A     * Boilerplate constructor used to set up a Powerup. This exposes some vital information for all Powerups.%0A     * @param club The club referenced by the %7B@link models.Activation%7D used to instantiate the Powerup. It is saved%0A     *             for reference.%0A     * @param model The model referenced by the %7B@link models.Activation%7D used to instantiate the Powerup. It is saved%0A     *              so that views may access the data held by the model.%0A     * @see play.db.ebean.Model%0A     */%0A    public Powerup(Club club, PowerupModel model) %7B%0A        this.club = club;%0A        this.model = model;%0A    %7D%0A%0A    /**%0A     * Every powerup must implement a method to render its associated view. For now, only one view may be referenced,%0A     * though this is likely to change as the API matures.%0A     * @return The HTML to insert into the club's view.%0A     * @see views.html.club.show%0A     * @see play.twirl.api.Html%0A     */%0A    public abstract Html render();%0A%0A    /**%0A     * Lazily loads the %7B@link powerups.Powerup%7D associated with the %7B@link models.Activation%7D%0A     * @param activation The activation used to instantiate the Powerup.%0A     * @return The instantiated Powerup.%0A     */
 %0A   
@@ -2531,11 +2531,70 @@
 l;%0A    %7D
+%0A%0A    protected Club getClub() %7B%0A        return club;%0A    %7D
 %0A%7D%0A

Document and restrict the abstract class Powerup.