MaterialDirector.java

package com.university.bookstore.builder;

import java.util.List;

import com.university.bookstore.composite.MaterialBundle;
import com.university.bookstore.model.Material;
import com.university.bookstore.model.Media;

/**
 * Director class that orchestrates the construction of complex Material objects
 * using various builders. Demonstrates the Director pattern in conjunction
 * with the Builder pattern for creating predefined configurations.
 * 
 * @author Navid Mohaghegh
 * @version 3.0
 * @since 2024-09-15
 */
public class MaterialDirector {
    
    private final EBookBuilder eBookBuilder;
    private final MaterialBundleBuilder bundleBuilder;
    
    /**
     * Constructs a MaterialDirector with the specified builders.
     * 
     * @param eBookBuilder the EBook builder
     * @param bundleBuilder the MaterialBundle builder
     */
    public MaterialDirector(EBookBuilder eBookBuilder, MaterialBundleBuilder bundleBuilder) {
        this.eBookBuilder = eBookBuilder;
        this.bundleBuilder = bundleBuilder;
    }
    
    /**
     * Constructs a premium EBook with all features enabled.
     * 
     * @param id the EBook ID
     * @param title the EBook title
     * @param author the EBook author
     * @param price the EBook price
     * @return a premium EBook
     */
    public Material buildPremiumEBook(String id, String title, String author, double price) {
        eBookBuilder.reset();
        return eBookBuilder
            .setId(id)
            .setTitle(title)
            .setAuthor(author)
            .setPrice(price)
            .setFileFormat("EPUB")
            .setFileSize(1024 * 1024 * 5) // 5MB
            .setDrmEnabled(false)
            .setWordCount(50000)
            .setQuality(Media.MediaQuality.HIGH)
            .build();
    }
    
    /**
     * Constructs a basic EBook with minimal features.
     * 
     * @param id the EBook ID
     * @param title the EBook title
     * @param author the EBook author
     * @param price the EBook price
     * @return a basic EBook
     */
    public Material buildBasicEBook(String id, String title, String author, double price) {
        eBookBuilder.reset();
        return eBookBuilder
            .setId(id)
            .setTitle(title)
            .setAuthor(author)
            .setPrice(price)
            .setFileFormat("PDF")
            .setFileSize(1024 * 1024 * 2) // 2MB
            .setDrmEnabled(true)
            .setWordCount(30000)
            .setQuality(Media.MediaQuality.MEDIUM)
            .build();
    }
    
    /**
     * Constructs a student EBook with educational features.
     * 
     * @param id the EBook ID
     * @param title the EBook title
     * @param author the EBook author
     * @param price the EBook price
     * @return a student EBook
     */
    public Material buildStudentEBook(String id, String title, String author, double price) {
        eBookBuilder.reset();
        return eBookBuilder
            .setId(id)
            .setTitle(title)
            .setAuthor(author)
            .setPrice(price)
            .setFileFormat("EPUB")
            .setFileSize(1024 * 1024 * 3) // 3MB
            .setDrmEnabled(false)
            .setWordCount(40000)
            .setQuality(Media.MediaQuality.HIGH)
            .build();
    }
    
    /**
     * Constructs a textbook bundle with a 20% discount.
     * 
     * @param bundleName the bundle name
     * @param materials the materials to include in the bundle
     * @return a textbook bundle
     */
    public MaterialBundle buildTextbookBundle(String bundleName, List<Material> materials) {
        bundleBuilder.reset();
        return bundleBuilder
            .setBundleName(bundleName)
            .setMediumDiscount() // 20% discount
            .addMaterials(materials)
            .build();
    }
    
    /**
     * Constructs a course bundle with a 25% discount.
     * 
     * @param bundleName the bundle name
     * @param materials the materials to include in the bundle
     * @return a course bundle
     */
    public MaterialBundle buildCourseBundle(String bundleName, List<Material> materials) {
        bundleBuilder.reset();
        return bundleBuilder
            .setBundleName(bundleName)
            .setBundleDiscount(0.25) // 25% discount
            .addMaterials(materials)
            .build();
    }
    
    /**
     * Constructs a premium bundle with a 30% discount.
     * 
     * @param bundleName the bundle name
     * @param materials the materials to include in the bundle
     * @return a premium bundle
     */
    public MaterialBundle buildPremiumBundle(String bundleName, List<Material> materials) {
        bundleBuilder.reset();
        return bundleBuilder
            .setBundleName(bundleName)
            .setLargeDiscount() // 30% discount
            .addMaterials(materials)
            .build();
    }
    
    /**
     * Constructs a starter bundle with a 10% discount.
     * 
     * @param bundleName the bundle name
     * @param materials the materials to include in the bundle
     * @return a starter bundle
     */
    public MaterialBundle buildStarterBundle(String bundleName, List<Material> materials) {
        bundleBuilder.reset();
        return bundleBuilder
            .setBundleName(bundleName)
            .setSmallDiscount() // 10% discount
            .addMaterials(materials)
            .build();
    }
    
    /**
     * Constructs a nested bundle (bundle containing other bundles).
     * 
     * @param bundleName the bundle name
     * @param bundles the bundles to include
     * @param discount the discount rate
     * @return a nested bundle
     */
    public MaterialBundle buildNestedBundle(String bundleName, List<MaterialBundle> bundles, double discount) {
        bundleBuilder.reset();
        MaterialBundleBuilder builder = bundleBuilder
            .setBundleName(bundleName)
            .setBundleDiscount(discount);
        
        for (MaterialBundle bundle : bundles) {
            builder.addBundle(bundle);
        }
        
        return builder.build();
    }
    
    /**
     * Constructs a custom bundle with specified parameters.
     * 
     * @param bundleName the bundle name
     * @param materials the materials to include
     * @param discount the discount rate
     * @return a custom bundle
     */
    public MaterialBundle buildCustomBundle(String bundleName, List<Material> materials, double discount) {
        bundleBuilder.reset();
        return bundleBuilder
            .setBundleName(bundleName)
            .setBundleDiscount(discount)
            .addMaterials(materials)
            .build();
    }
    
    /**
     * Gets the EBook builder for custom configurations.
     * 
     * @return the EBook builder
     */
    public EBookBuilder getEBookBuilder() {
        return eBookBuilder;
    }
    
    /**
     * Gets the MaterialBundle builder for custom configurations.
     * 
     * @return the MaterialBundle builder
     */
    public MaterialBundleBuilder getBundleBuilder() {
        return bundleBuilder;
    }
    
    /**
     * Creates a new EBook builder instance.
     * 
     * @return a new EBook builder
     */
    public EBookBuilder createEBookBuilder() {
        return new EBookBuilder();
    }
    
    /**
     * Creates a new MaterialBundle builder instance.
     * 
     * @return a new MaterialBundle builder
     */
    public MaterialBundleBuilder createBundleBuilder() {
        return new MaterialBundleBuilder();
    }
}