/**
 * 产品试用评价表PDFのコントローラです。
 */
public class BeforeOPDPDFExtensionController {

    /** 処理対象の見積オブジェクトのIDです。 */
    private Id targetId;
    private String pdfNo;

    /** 処理対象の見積オブジェクトです。 */
    private QuoteIrai__c irai;
    private Opportunity opp;
    private ConsumableSample__c cs;
    
    /** 1ページに表示する明細の数です。 */
    private Integer rowSize = 36;

    /** 最終ページに表示する明細の数です。 */
    private Integer lastRowSize = 24;

    /** 製品名を開業する文字数です。 */
    private Integer nameMax = 23;

    /** 印刷するページ数です。 */
    public Integer maxPageNumber { get; private set; }

    /** 印刷対象の見積の配下にある見積品目データです。 */
    public List<LineItemBean[]> printRecords { get; private set; }
    /**
     * 印刷するデータを格納するオブジェクを定義する、インナークラスです。
     */
    public class LineItemBean {
        public OpportunityLineItem oli { get; private set; }
        public QuoteIraiLineItem__c qli { get; private set; }
        public ConsumableSampleLineItem__c csli { get; private set; }
        
        public String productCode { get; private set; }
        public String productname { get; private set; }
        public Decimal quantity { get; private set; }
        
        public Decimal Packing_list_manual { get; private set; }
        
        public LineItemBean(OpportunityLineItem oli) {
            this.oli = oli;
            this.qli = null;
            this.csli = null;
            
            this.productCode = oli.ProductCode__c;
            this.productname = oli.Name__c;
            this.quantity = oli.Quantity;
        }
        
        public LineItemBean(QuoteIraiLineItem__c qli) {
            this.oli = null;
            this.qli = qli;
            this.csli = null;
            
            this.productCode = qli.ProductCode__c;
            this.productname = qli.Name__c;
            this.quantity = qli.Quantity__c;
        }
        
        public LineItemBean(ConsumableSampleLineItem__c csli) {
            this.oli = null;
            this.qli = null;
            this.csli = csli;
            
            this.productCode = csli.ProductCode__c;
            this.productname = csli.Name__c;
            this.quantity = csli.Quantity__c;
            this.Packing_list_manual = csli.Product2__r.Packing_list_manual__c;
            if (this.Packing_list_manual == null || this.Packing_list_manual <= 0) {
                this.Packing_list_manual = 1;
            }
        }
    }

    /**
     * 印刷するデータを格納するオブジェクトです。
     * ページ側は、このオブジェクト経由で印刷するデータにアクセスします。
     */
    public Parameters params { get; set; }

    /**
     * 印刷するデータを格納するオブジェクを定義する、インナークラスです。
     */
    public class Parameters {
        public String lineType { get; set; }
        public String sysNo { get; set; }
        public String hpName { get; set; }
        public String department { get; set; }
    }

    /**
     * コンストラクタです。
     * テスト用に作成しました。本来は不要です。
     */
    public BeforeOPDPDFExtensionController() {
        
    }

    /**
     * Visualforceページがアクセスするコンストラクタです。
     * 印刷するデータを収集し、インスタンス変数にセットします。
     * @param controller スタンダードコントローラーのインスタンス
     */
    public BeforeOPDPDFExtensionController(ApexPages.StandardController controller) {
        
    }
    
    /**
     * 契約内訳で、actionから呼ばれます。
     */    
    public void startContract() {
        this.params = new Parameters();
        this.rowSize = 37;
        this.lastRowSize = 37;
        this.nameMax = 35;
        // 見積依頼
        if (String.isBlank(ApexPages.currentPage().getParameters().get('qid')) == false) {
            this.targetId = ApexPages.currentPage().getParameters().get('qid');
            this.params.lineType = 'quo';
        }
        // 引合ボタン
        else if (String.isBlank(ApexPages.currentPage().getParameters().get('oid')) == false) {
            this.targetId = ApexPages.currentPage().getParameters().get('oid');
            this.params.lineType = 'opp';
        }
        // 消耗品
        else if (String.isBlank(ApexPages.currentPage().getParameters().get('csid')) == false) {
            this.targetId = ApexPages.currentPage().getParameters().get('csid');
            this.params.lineType = 'cs';
        }
        
        if (String.isBlank(ApexPages.currentPage().getParameters().get('pdfNo')) == false) {
            this.pdfNo = ApexPages.currentPage().getParameters().get('pdfNo');
        }
        
        this.mainProc(this.targetId);
    }
    
    /**
     * 主処理です。
     * @param quoteId 見積番号
     */
    private void mainProc(String id) {
        
        if (this.params.lineType == 'quo') {
            List<QuoteIrai__c> irais =  [SELECT Id, Account__r.Name, IraiSubject__c FROM QuoteIrai__c WHERE Id = :id];
            if (irais.size() > 0) {
                irai = irais[0];
            } else {
                return;
            }
        } else if (this.params.lineType == 'opp') {
            List<Opportunity> opps =  [SELECT Id, Hospital__r.Name, Department_Name__c FROM Opportunity WHERE Id = :id];
            if (opps.size() > 0) {
                opp = opps[0];
            } else {
                return;
            }
        } else if (this.params.lineType == 'cs') {
            List<ConsumableSample__c> css =  [SELECT Id, Contact__r.Hospital_name__c, Contact__r.Department__c FROM ConsumableSample__c WHERE Id = :id];
            if (css.size() > 0) {
                cs = css[0];
            } else {
                return;
            }
        }
        
        this.setQueryStringData();
        this.bindQuoteData(id);
        this.bindQuoteLineData();
    }

    /**
     * URLパラメータを取得して、インスタンス変数にセットします。
     */
    private void setQueryStringData() {
        try {
            String rawRowSize = ApexPages.currentPage().getParameters().get('rowSize');
            this.rowSize = rawRowSize != null ? Integer.valueOf(rawRowSize) : this.rowSize;
        }
        catch (Exception e) {
            
        }
    }

    /**
     * 見積データを、インスタンス変数にセットします。
     * @param quoteId 見積ID
     */
    private void bindQuoteData(String quoteId) {
        if (String.isBlank(this.pdfNo) == false) {
            this.params.sysNo = this.pdfNo;
        } else {
            this.params.sysNo = ControllerUtil.selectCommonSequence('EvaluationPDF_NextValue__c','EvaluationPDF_Format__c');
        }
        
        if (this.params.lineType == 'quo') {
            this.params.hpName = this.irai.Account__r.Name;
            this.params.department = this.irai.IraiSubject__c;
        } else if (this.params.lineType == 'opp') {
            this.params.hpName = this.opp.Hospital__r.Name;
            this.params.department = this.opp.Department_Name__c;
        } else if (this.params.lineType == 'cs') {
            this.params.hpName = this.cs.Contact__r.Hospital_name__c;
            this.params.department = this.cs.Contact__r.Department__c;
        }
    }

    /**
     * 見積品目データを取得して、インスタンス変数にセットします。
     */
    private void bindQuoteLineData(){
        this.maxPageNumber = 0;
        // 見積依頼
        if (this.params.lineType == 'quo') {
            String nowId = this.irai.Id;
            Integer repeatCount = null;
            String nowName = null, nowRightAsstModelNo = null;
            List<String> nameStringArray = null;
            QuoteIraiLineItem__c work = null;
            QuoteIraiLineItem__c[] itemsOrg = [SELECT id, ProductCode__c, Name__c, Quantity__c FROM QuoteIraiLineItem__c WHERE QuoteIrai__c = :nowId ORDER BY Item_Order__c ASC];
            QuoteIraiLineItem__c[] items = new List<QuoteIraiLineItem__c>();
            for (Integer i = 0; i < itemsOrg.size(); i++) {
                nowName = itemsOrg[i].Name__c == null ? '' : itemsOrg[i].Name__c;
                nowRightAsstModelNo = '';
                
                nameStringArray = new List<String>();
                repeatCount = (nowName.length() / nameMax) + (Math.mod(nowName.length(), nameMax) > 0 ? 1 : 0);
                for (Integer j = 0; j < repeatCount; j++) {
                    if ((j + 1) == repeatCount) {
                        nameStringArray.add(nowName.substring(j * nameMax));
                    }
                    else {
                        nameStringArray.add(nowName.substring(j * nameMax, (j+1) * nameMax));
                    }
                }
                for (Integer k = 0; k < nameStringArray.size(); k++) {
                    if (k == 0) {
                        work = itemsOrg[i];
                    }
                    else {
                        work = new QuoteIraiLineItem__c();
                    }
                    work.Name__c = nameStringArray[k];
                    items.add(work);
                }
            }
            
            printRecords = new List<LineItemBean[]>();
    
            LineItemBean[] pageItems = new LineItemBean[]{};
            Integer counter = 0;
            for (QuoteIraiLineItem__c c : items) {
    
                if (counter <= rowSize) {
                    pageItems.add(new LineItemBean(c));
                    counter++;
                }
                if (counter == rowSize) {
                    counter = 0;
                    printRecords.add(pageItems);
                    pageItems = new LineItemBean[]{};
                    this.maxPageNumber += 1;
                }
            }
            if (!pageItems.isEmpty()) {
                printRecords.add(pageItems);
                this.maxPageNumber += 1;
            }
            if (printRecords.size() > 0) {
                List<LineItemBean> lastList = printRecords[printRecords.size()-1];
                if (lastList.size() > lastRowSize) {
                    printRecords.add(new List<LineItemBean>());
                    this.maxPageNumber += 1;
                }
            }
        }
        // 引合ボタン
        else if (this.params.lineType == 'opp') {
            String nowId = this.opp.Id;
            Integer repeatCount = null;
            String nowName = null, nowRightAsstModelNo = null;
            List<String> nameStringArray = null;
            OpportunityLineItem work = null;
            OpportunityLineItem[] itemsOrg = [SELECT id, ProductCode__c, Name__c, Quantity FROM OpportunityLineItem WHERE OpportunityId = :nowId ORDER BY Item_Order__c ASC];
            OpportunityLineItem[] items = new List<OpportunityLineItem>();
            for (Integer i = 0; i < itemsOrg.size(); i++) {
                nowName = itemsOrg[i].Name__c == null ? '' : itemsOrg[i].Name__c;
                nowRightAsstModelNo = '';
                
                nameStringArray = new List<String>();
                repeatCount = (nowName.length() / nameMax) + (Math.mod(nowName.length(), nameMax) > 0 ? 1 : 0);
                for (Integer j = 0; j < repeatCount; j++) {
                    if ((j + 1) == repeatCount) {
                        nameStringArray.add(nowName.substring(j * nameMax));
                    }
                    else {
                        nameStringArray.add(nowName.substring(j * nameMax, (j+1) * nameMax));
                    }
                }
                for (Integer k = 0; k < nameStringArray.size(); k++) {
                    if (k == 0) {
                        work = itemsOrg[i];
                    }
                    else {
                        work = new OpportunityLineItem();
                    }
                    work.Name__c = nameStringArray[k];
                    items.add(work);
                }
            }
            
            printRecords = new List<LineItemBean[]>();
    
            LineItemBean[] pageItems = new LineItemBean[]{};
            Integer counter = 0;
            for (OpportunityLineItem c : items) {
    
                if (counter <= rowSize) {
                    pageItems.add(new LineItemBean(c));
                    counter++;
                }
                if (counter == rowSize) {
                    counter = 0;
                    printRecords.add(pageItems);
                    pageItems = new LineItemBean[]{};
                    this.maxPageNumber += 1;
                }
            }
            if (!pageItems.isEmpty()) {
                printRecords.add(pageItems);
                this.maxPageNumber += 1;
            }
            if (printRecords.size() > 0) {
                List<LineItemBean> lastList = printRecords[printRecords.size()-1];
                if (lastList.size() > lastRowSize) {
                    printRecords.add(new List<LineItemBean>());
                    this.maxPageNumber += 1;
                }
            }
        }
        // 消耗品
        else if (this.params.lineType == 'cs') {
            String nowId = this.cs.Id;
            Integer repeatCount = null;
            String nowName = null, nowRightAsstModelNo = null;
            List<String> nameStringArray = null;
            ConsumableSampleLineItem__c work = null;
            ConsumableSampleLineItem__c[] itemsOrg = [SELECT id, ProductCode__c, Name__c, Quantity__c, Product2__r.Packing_list_manual__c FROM ConsumableSampleLineItem__c WHERE ConsumableSample__c = :nowId ORDER BY Item_Order__c ASC];
            ConsumableSampleLineItem__c[] items = new List<ConsumableSampleLineItem__c>();
            for (Integer i = 0; i < itemsOrg.size(); i++) {
                nowName = itemsOrg[i].Name__c == null ? '' : itemsOrg[i].Name__c;
                nowRightAsstModelNo = '';
                
                nameStringArray = new List<String>();
                repeatCount = (nowName.length() / nameMax) + (Math.mod(nowName.length(), nameMax) > 0 ? 1 : 0);
                for (Integer j = 0; j < repeatCount; j++) {
                    if ((j + 1) == repeatCount) {
                        nameStringArray.add(nowName.substring(j * nameMax));
                    }
                    else {
                        nameStringArray.add(nowName.substring(j * nameMax, (j+1) * nameMax));
                    }
                }
                for (Integer k = 0; k < nameStringArray.size(); k++) {
                    if (k == 0) {
                        work = itemsOrg[i];
                    }
                    else {
                        work = new ConsumableSampleLineItem__c();
                    }
                    work.Name__c = nameStringArray[k];
                    items.add(work);
                }
            }
            
            printRecords = new List<LineItemBean[]>();
    
            LineItemBean[] pageItems = new LineItemBean[]{};
            Integer counter = 0;
            for (ConsumableSampleLineItem__c c : items) {
    
                if (counter <= rowSize) {
                    pageItems.add(new LineItemBean(c));
                    counter++;
                }
                if (counter == rowSize) {
                    counter = 0;
                    printRecords.add(pageItems);
                    pageItems = new LineItemBean[]{};
                    this.maxPageNumber += 1;
                }
            }
            if (!pageItems.isEmpty()) {
                printRecords.add(pageItems);
                this.maxPageNumber += 1;
            }
            if (printRecords.size() > 0) {
                List<LineItemBean> lastList = printRecords[printRecords.size()-1];
                if (lastList.size() > lastRowSize) {
                    printRecords.add(new List<LineItemBean>());
                    this.maxPageNumber += 1;
                }
            }
        }
    }
    
}