<?xml version="1.0"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
      contributor license agreements.  See the NOTICE file distributed with
      this work for additional information regarding copyright ownership.
      The ASF licenses this file to You under the Apache License, Version 2.0
      (the "License"); you may not use this file except in compliance with
      the License.  You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
  -->

<!-- Main application to print a DataGrid control on multiple pages. -->

<mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx"
				paddingBottom="0" paddingTop="0" paddingLeft="0" paddingRight="0" initialize="initData()">

     <fx:Script>
        <![CDATA[

		import mx.core.FlexGlobals;
        import mx.printing.*;
        import mx.collections.ArrayCollection;
        import FormPrintView;

        // Declare variables and initialize simple variables.
        [Bindable]
        public var dgProvider:ArrayCollection;
        public var footerHeight:Number = 20;
        public var prodIndex:Number;
        public var prodTotal:Number = 0;

        // Data initialization.
        public function initData():void {
            // Create the data provider for the DataGrid control.
            dgProvider = new ArrayCollection;
        }

        // Fill the dgProvider ArrayCollection with the specified items.
        public function setdgProvider(items:int):void {

            prodIndex=1;
            dgProvider.removeAll();
            for (var z:int=0; z<items; z++)
            {
                var prod1:Object = {};
                prod1.Qty = prodIndex * 7;
                prod1.Index = prodIndex++;
                prodTotal += prod1.Qty;
                dgProvider.addItem(prod1);
            }
        }

        // The function to print the output.
        public function doPrint():void {

            var printJob:FlexPrintJob = new FlexPrintJob();
            if (printJob.start()) {
                // Create a FormPrintView control as a child of the current view.
                var thePrintView:FormPrintView = new FormPrintView();
               FlexGlobals.topLevelApplication.addChild(thePrintView);

                //Set the print view properties.
                thePrintView.width=printJob.pageWidth;
                thePrintView.height=printJob.pageHeight;
                thePrintView.prodTotal = prodTotal;
                // Set the data provider of the FormPrintView component's data grid
                // to be the data provider of the displayed data grid.
                thePrintView.myDataGrid.dataProvider = myDataGrid.dataProvider;
                // Create a single-page image.
                thePrintView.showPage("single");
                // If the print image's data grid can hold all the provider's rows,
                // add the page to the print job.
                if(!thePrintView.myDataGrid.validNextPage)
                {
                    printJob.addObject(thePrintView);
                }
                // Otherwise, the job requires multiple pages.
                else
                {
                    // Create the first page and add it to the print job.
                    thePrintView.showPage("first");
                    printJob.addObject(thePrintView);
                    thePrintView.pageNumber++;
                    // Loop through the following code until all pages are queued.
                    while(true)
                    {
                        // Move the next page of data to the top of the print grid.
                        thePrintView.myDataGrid.nextPage();
                        thePrintView.showPage("last");
                        // If the page holds the remaining data, or if the last page
                        // was completely filled by the last grid data, queue it for printing.
                        // Test if there is data for another PrintDataGrid page.
                        if(!thePrintView.myDataGrid.validNextPage)
                        {
                            // This is the last page; queue it and exit the print loop.
                            printJob.addObject(thePrintView);
                            break;
                        }
                        else
                        // This is not the last page. Queue a middle page.
                        {
                            thePrintView.showPage("middle");
                            printJob.addObject(thePrintView);
                            thePrintView.pageNumber++;
                        }
                    }
                }
                // All pages are queued; remove the FormPrintView control to free memory.
                FlexGlobals.topLevelApplication.removeChild(thePrintView);
            }
            // Send the job to the printer.
            printJob.send();
        }
        ]]>
    </fx:Script>

    <mx:Panel title="DataGrid Printing Example"
			  paddingBottom="10" paddingTop="10" paddingLeft="10" paddingRight="10"
			  height="100%" width="100%">

        <mx:DataGrid id="myDataGrid" dataProvider="{dgProvider}">
            <mx:columns>
                <mx:DataGridColumn dataField="Index"/>
                <mx:DataGridColumn dataField="Qty"/>
            </mx:columns>
        </mx:DataGrid>

        <mx:Text width="100%"
            text="Specify the number of lines and click Fill Grid first. Then you can click Print."/>

        <mx:TextInput id="dataItems" text="35"/>

        <mx:HBox>
            <mx:Button id="setDP" label="Fill Grid" click="setdgProvider(int(dataItems.text))"/>
            <mx:Button id="printDG" label="Print" click="doPrint()"/>
        </mx:HBox>
    </mx:Panel>
</mx:Module>
