/*!
 * 
 * 4DView Pro library 0.0.0
 * 
 * Copyright(c) 4D SAS.  All rights reserved.
 * 
 * 4D (the "Software") and the corresponding source code remain
 * the exclusive property of 4D and/or its licensors and are protected by national
 * and/or international legislations.
 * 
 * This file is part of the source code of the Software provided under the relevant
 * 4D License Agreement available on http://www.4D.com/license whose compliance
 * constitutes a prerequisite to any use of this file and more generally of the
 * Software and the corresponding source code.
 * 
 */
(function () {

  let attributes = [
    'bestFitColumns',
    'bestFitRows',
    'blackAndWhite',
    'centering',
    'columnEnd',
    'columnStart',
    'firstPageNumber',
    'fitPagesTall',
    'fitPagesWide',
    'footerCenter',
    'footerCenterImage',
    'footerLeft',
    'footerLeftImage',
    'footerRight',
    'footerRightImage',
    'headerCenter',
    'headerCenterImage',
    'headerLeft',
    'headerLeftImage',
    'headerRight',
    'headerRightImage',
    'margin',
    'orientation',
    'pageOrder',
    'pageRange',
    'paperSize',
    'qualityFactor',
    'repeatColumnEnd',
    'repeatColumnStart',
    'repeatRowEnd',
    'repeatRowStart',
    'rowEnd',
    'rowStart',
    'showBorder',
    'showColumnHeader',
    'showGridLine',
    'showRowHeader',
    'useMax',
    'watermark',
    'zoomFactor'
  ];

  function restrainToSupportedAttributes(printInfo) {
    let ret = {};

    attributes.forEach(attribute => {
      if (attribute in printInfo) {
        ret[attribute] = printInfo[attribute]();
      }
    });
    return ret;
  }

  function makePrintInfoAttribute(printInfo, attribute) {
    let ret = null;
    if (printInfo[attribute] === null) {
      ret = undefined;
    } else {
      switch (attribute) {
        case 'paperSize':
          {
            if ('kind' in printInfo[attribute]) {
              ret = new GC.Spread.Sheets.Print.PaperSize(GC.Spread.Sheets.Print.PaperKind[printInfo[attribute].kind]);
            }
            else if (('width' in printInfo[attribute]) && ('height' in printInfo[attribute])) {
              ret = new GC.Spread.Sheets.Print.PaperSize(printInfo[attribute].width, printInfo[attribute].height);
            }
          }
          break;

        default:
          ret = printInfo[attribute];
          break;
      }
    }
    return ret;
  }

  function makePrintInfo(printInfo) {
    let ret = new GC.Spread.Sheets.Print.PrintInfo();

    let keys = Object.keys(printInfo);

    keys.forEach(attribute => {
      if (attributes.find(validAttribute => {
        return validAttribute === attribute;
      }) != undefined) {
        ret[attribute](makePrintInfoAttribute(printInfo, attribute));
      }
    });
    return ret;
  }

  Utils.addCommand('print', function (params) {
    let sheetIndex = Utils.resolveSheetIndex(params.sheetIndex);

    Utils.spread.print(sheetIndex);
  });

  Utils.addCommand('set-print-info', function (params) {
    let instance = Utils.resolveSheet(params.sheetIndex);

    if (instance != null) {
      if (('printInfo' in params) && (typeof (params.printInfo) === 'object')) {
        let printInfo = makePrintInfo(params.printInfo);
        instance.printInfo(printInfo);
      }
    }
  });

  Utils.addCommand('get-print-info', function (params) {
    let ret = null;
    let instance = Utils.resolveSheet(params.sheetIndex);

    if (instance != null) {
      let printInfo = instance.printInfo();
      ret = restrainToSupportedAttributes(printInfo);
    }
    return ret;
  });

  Utils.addCommand('set-print-line-visible', function (params) {
    let instance = Utils.resolveSheet(params.sheetIndex);

    if (instance != null) {
      if (('visible' in params) && (typeof (params.visible) === 'boolean')) {
        instance.isPrintLineVisible(params.visible);
      }
    }
  });

  Utils.addCommand('is-print-line-visible', function (params) {
    let ret = {value:false};
    let instance = Utils.resolveSheet(params.sheetIndex);

    if (instance != null) {
      ret.value = instance.isPrintLineVisible();
    }

    return ret;
  });

  Utils.addCommand('set-page-break', function (params) {

    if (('pageBreak' in params) && (params.pageBreak.constructor === Array)) {

      params.ranges.forEach(range => {
        let instancesArray = [];

        Utils.getRanges(range, instancesArray);

        instancesArray.forEach(i => {
          let sheetIndex = Utils.spread.getSheetIndex(i.sheet.name());

          if ((i.row == 0) && (i.rowCount == 1048576)) {
            i.sheet.setColumnPageBreak(i.column);
          } else if ((i.column == 0) && (i.columnCount == 1048576)) {
            i.sheet.setRowPageBreak(i.row);
          } else if ((i.row != 0) && (i.column != 0)) {
            i.sheet.setColumnPageBreak(i.column);
            i.sheet.setRowPageBreak(i.row);
          }
        });
      });
    }
  });

  Utils.addCommand('is-page-break', function (params) {
    let ret = {value:false};

    if (('pageBreak' in params) && (params.pageBreak.constructor === Array)) {

      ret.value = params.ranges.every(range => {
        let instancesArray = [];

        Utils.getRanges(range, instancesArray);

        return instancesArray.every(i => {
          let sheetIndex = Utils.spread.getSheetIndex(i.sheet.name());

          if ((i.row == 0) && (i.rowCount == 1048576)) {
            return i.sheet.getColumnPageBreak(i.column);
          } else if ((i.column == 0) && (i.columnCount == 1048576)) {
            return i.sheet.getRowPageBreak(i.row);
          } else if ((i.row != 0) && (i.column != 0)) {
            return i.sheet.getColumnPageBreak(i.column) && i.sheet.getRowPageBreak(i.row);
          } else {
            return false;
          }
        });
      });
    }
    return ret;
  });

})();
