16e80583aSopenharmony_ci/**
26e80583aSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
36e80583aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
46e80583aSopenharmony_ci * you may not use this file except in compliance with the License.
56e80583aSopenharmony_ci * You may obtain a copy of the License at
66e80583aSopenharmony_ci *
76e80583aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
86e80583aSopenharmony_ci *
96e80583aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
106e80583aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
116e80583aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126e80583aSopenharmony_ci * See the License for the specific language governing permissions and
136e80583aSopenharmony_ci * limitations under the License.
146e80583aSopenharmony_ci */
156e80583aSopenharmony_ci
166e80583aSopenharmony_ciimport { EventConstants } from '../constants/EventConstants';
176e80583aSopenharmony_ciimport { localEventManager } from '../manager/LocalEventManager';
186e80583aSopenharmony_ciimport { Log } from '../utils/Log';
196e80583aSopenharmony_ci
206e80583aSopenharmony_ciconst TAG = 'PageDesktopModel';
216e80583aSopenharmony_ci
226e80583aSopenharmony_ci/**
236e80583aSopenharmony_ci * PageDesktop Model
246e80583aSopenharmony_ci */
256e80583aSopenharmony_ci
266e80583aSopenharmony_ciexport class PageDesktopModel {
276e80583aSopenharmony_ci  private isAddByDraggingFlag = false;
286e80583aSopenharmony_ci
296e80583aSopenharmony_ci  private constructor() {
306e80583aSopenharmony_ci  }
316e80583aSopenharmony_ci
326e80583aSopenharmony_ci  /**
336e80583aSopenharmony_ci  * Obtains the pageDesktop data model object.
346e80583aSopenharmony_ci  *
356e80583aSopenharmony_ci  * @return PageDesktopModel
366e80583aSopenharmony_ci   */
376e80583aSopenharmony_ci  static getInstance(): PageDesktopModel {
386e80583aSopenharmony_ci    if (globalThis.PageDesktopModel == null) {
396e80583aSopenharmony_ci      globalThis.PageDesktopModel = new PageDesktopModel();
406e80583aSopenharmony_ci    }
416e80583aSopenharmony_ci    return globalThis.PageDesktopModel;
426e80583aSopenharmony_ci  }
436e80583aSopenharmony_ci
446e80583aSopenharmony_ci  /**
456e80583aSopenharmony_ci  * Register for the PageDesktop application list add event.
466e80583aSopenharmony_ci  *
476e80583aSopenharmony_ci  * @param listener
486e80583aSopenharmony_ci   */
496e80583aSopenharmony_ci  registerPageDesktopItemAddEvent(listener): void {
506e80583aSopenharmony_ci    localEventManager.registerEventListener(listener, [
516e80583aSopenharmony_ci      EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_ADD,
526e80583aSopenharmony_ci      EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_DELETE,
536e80583aSopenharmony_ci      EventConstants.EVENT_REQUEST_PAGEDESK_ITEM_UPDATE,
546e80583aSopenharmony_ci      EventConstants.EVENT_REQUEST_PAGEDESK_FORM_ITEM_ADD,
556e80583aSopenharmony_ci      EventConstants.EVENT_SMARTDOCK_INIT_FINISHED,
566e80583aSopenharmony_ci      EventConstants.EVENT_REQUEST_PAGEDESK_REFRESH,
576e80583aSopenharmony_ci      EventConstants.EVENT_REQUEST_FORM_ITEM_VISIBLE
586e80583aSopenharmony_ci    ]);
596e80583aSopenharmony_ci  }
606e80583aSopenharmony_ci
616e80583aSopenharmony_ci  /**
626e80583aSopenharmony_ci  * register badge update event.
636e80583aSopenharmony_ci  *
646e80583aSopenharmony_ci  * @param listener
656e80583aSopenharmony_ci   */
666e80583aSopenharmony_ci  registerPageDesktopBadgeUpdateEvent(listener): void {
676e80583aSopenharmony_ci    localEventManager.registerEventListener(listener, [
686e80583aSopenharmony_ci      EventConstants.EVENT_BADGE_UPDATE
696e80583aSopenharmony_ci    ]);
706e80583aSopenharmony_ci  }
716e80583aSopenharmony_ci
726e80583aSopenharmony_ci  /**
736e80583aSopenharmony_ci  * Unregister application list change listener.
746e80583aSopenharmony_ci  *
756e80583aSopenharmony_ci  * @param listener
766e80583aSopenharmony_ci   */
776e80583aSopenharmony_ci  unregisterEventListener(listener): void {
786e80583aSopenharmony_ci    localEventManager.unregisterEventListener(listener);
796e80583aSopenharmony_ci  }
806e80583aSopenharmony_ci
816e80583aSopenharmony_ci  sendDockItemChangeEvent(appInfo): void {
826e80583aSopenharmony_ci    localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_DOCK_ITEM_ADD, appInfo);
836e80583aSopenharmony_ci  }
846e80583aSopenharmony_ci
856e80583aSopenharmony_ci  /**
866e80583aSopenharmony_ci   * delete blank page from layoutInfo
876e80583aSopenharmony_ci   *
886e80583aSopenharmony_ci   * @param layoutInfo
896e80583aSopenharmony_ci   * @param page
906e80583aSopenharmony_ci   */
916e80583aSopenharmony_ci  deleteBlankPageFromLayoutInfo(layoutInfo, page): boolean {
926e80583aSopenharmony_ci    for (let i = 0; i < layoutInfo.layoutInfo.length; i++) {
936e80583aSopenharmony_ci      if (layoutInfo.layoutInfo[i].page == page) {
946e80583aSopenharmony_ci        return false;
956e80583aSopenharmony_ci      }
966e80583aSopenharmony_ci    }
976e80583aSopenharmony_ci    if (layoutInfo.layoutDescription.pageCount <= 1) {
986e80583aSopenharmony_ci      return false;
996e80583aSopenharmony_ci    }
1006e80583aSopenharmony_ci    layoutInfo.layoutDescription.pageCount--;
1016e80583aSopenharmony_ci    for (let m = 0; m < layoutInfo.layoutInfo.length; m++) {
1026e80583aSopenharmony_ci      if (layoutInfo.layoutInfo[m].page > page) {
1036e80583aSopenharmony_ci        layoutInfo.layoutInfo[m].page--;
1046e80583aSopenharmony_ci      }
1056e80583aSopenharmony_ci    }
1066e80583aSopenharmony_ci    return true;
1076e80583aSopenharmony_ci  }
1086e80583aSopenharmony_ci
1096e80583aSopenharmony_ci  /**
1106e80583aSopenharmony_ci   * get the addByDragging flag
1116e80583aSopenharmony_ci   */
1126e80583aSopenharmony_ci  isAddByDragging(): boolean {
1136e80583aSopenharmony_ci    return this.isAddByDraggingFlag;
1146e80583aSopenharmony_ci  }
1156e80583aSopenharmony_ci
1166e80583aSopenharmony_ci  /**
1176e80583aSopenharmony_ci   * set the addByDragging flag
1186e80583aSopenharmony_ci   * @param {boolean} isAddByDragging
1196e80583aSopenharmony_ci   */
1206e80583aSopenharmony_ci  setAddByDragging(isAddByDragging: boolean): void {
1216e80583aSopenharmony_ci    this.isAddByDraggingFlag = isAddByDragging;
1226e80583aSopenharmony_ci  }
1236e80583aSopenharmony_ci
1246e80583aSopenharmony_ci  updateAppItemLayoutInfo(info, item): void {
1256e80583aSopenharmony_ci    const pageCount = info.layoutDescription.pageCount;
1266e80583aSopenharmony_ci    const row = info.layoutDescription.row;
1276e80583aSopenharmony_ci    const column = info.layoutDescription.column;
1286e80583aSopenharmony_ci    const layoutInfo = info.layoutInfo;
1296e80583aSopenharmony_ci    // current page has space
1306e80583aSopenharmony_ci    let isNeedNewPage = true;
1316e80583aSopenharmony_ci    pageCycle: for (let i = 0; i < pageCount; i++) {
1326e80583aSopenharmony_ci      for (let y = 0; y < row; y++) {
1336e80583aSopenharmony_ci        for (let x = 0; x < column; x++) {
1346e80583aSopenharmony_ci          if (this.isPositionValid(info, item, i, x, y)) {
1356e80583aSopenharmony_ci            Log.showDebug(TAG, `updateAppItemLayoutInfo isPositionValid: x:${x} y:${y} page:${i}`);
1366e80583aSopenharmony_ci            isNeedNewPage = false;
1376e80583aSopenharmony_ci            layoutInfo.push({
1386e80583aSopenharmony_ci              bundleName: item.bundleName,
1396e80583aSopenharmony_ci              typeId: item.typeId,
1406e80583aSopenharmony_ci              abilityName: item.abilityName,
1416e80583aSopenharmony_ci              moduleName: item.moduleName,
1426e80583aSopenharmony_ci              keyName: item.keyName,
1436e80583aSopenharmony_ci              badgeNumber:item.badgeNumber,
1446e80583aSopenharmony_ci              area: item.area,
1456e80583aSopenharmony_ci              page: i,
1466e80583aSopenharmony_ci              column: x,
1476e80583aSopenharmony_ci              row: y
1486e80583aSopenharmony_ci            });
1496e80583aSopenharmony_ci            break pageCycle;
1506e80583aSopenharmony_ci          }
1516e80583aSopenharmony_ci        }
1526e80583aSopenharmony_ci      }
1536e80583aSopenharmony_ci    }
1546e80583aSopenharmony_ci    if (isNeedNewPage) {
1556e80583aSopenharmony_ci      layoutInfo.push({
1566e80583aSopenharmony_ci        bundleName: item.bundleName,
1576e80583aSopenharmony_ci        typeId: item.typeId,
1586e80583aSopenharmony_ci        abilityName: item.abilityName,
1596e80583aSopenharmony_ci        moduleName: item.moduleName,
1606e80583aSopenharmony_ci        keyName: item.keyName,
1616e80583aSopenharmony_ci        badgeNumber:item.badgeNumber,
1626e80583aSopenharmony_ci        area: item.area,
1636e80583aSopenharmony_ci        page: pageCount,
1646e80583aSopenharmony_ci        column: 0,
1656e80583aSopenharmony_ci        row: 0
1666e80583aSopenharmony_ci      });
1676e80583aSopenharmony_ci      ++info.layoutDescription.pageCount;
1686e80583aSopenharmony_ci    }
1696e80583aSopenharmony_ci  }
1706e80583aSopenharmony_ci
1716e80583aSopenharmony_ci  updatePageDesktopLayoutInfo(info, item): boolean {
1726e80583aSopenharmony_ci    const pageCount = info.layoutDescription.pageCount;
1736e80583aSopenharmony_ci    const row = info.layoutDescription.row;
1746e80583aSopenharmony_ci    const column = info.layoutDescription.column;
1756e80583aSopenharmony_ci    // current page has space
1766e80583aSopenharmony_ci    let isNeedNewPage = true;
1776e80583aSopenharmony_ci    const curPageIndex = this.getPageIndex();
1786e80583aSopenharmony_ci    const max = pageCount - 1 > curPageIndex ? curPageIndex + 1 : pageCount - 1;
1796e80583aSopenharmony_ci    pageCycle: for (let i = curPageIndex; i <= max; i++) {
1806e80583aSopenharmony_ci      for (let y = 0; y < row; y++) {
1816e80583aSopenharmony_ci        for (let x = 0; x < column; x++) {
1826e80583aSopenharmony_ci          if (this.isPositionValid(info, item, i, x, y)) {
1836e80583aSopenharmony_ci            Log.showDebug(TAG, `updatePageDesktopLayoutInfo isPositionValid: x:${x} y:${y} page:${i}`);
1846e80583aSopenharmony_ci            isNeedNewPage = false;
1856e80583aSopenharmony_ci            item.page = i;
1866e80583aSopenharmony_ci            item.column = x;
1876e80583aSopenharmony_ci            item.row = y;
1886e80583aSopenharmony_ci            break pageCycle;
1896e80583aSopenharmony_ci          }
1906e80583aSopenharmony_ci        }
1916e80583aSopenharmony_ci      }
1926e80583aSopenharmony_ci    }
1936e80583aSopenharmony_ci    if (isNeedNewPage) {
1946e80583aSopenharmony_ci      item.page = curPageIndex + 1;
1956e80583aSopenharmony_ci      item.column = 0;
1966e80583aSopenharmony_ci      item.row = 0;
1976e80583aSopenharmony_ci    }
1986e80583aSopenharmony_ci    return isNeedNewPage;
1996e80583aSopenharmony_ci  }
2006e80583aSopenharmony_ci
2016e80583aSopenharmony_ci  private isPositionValid(info, item, page, startColumn, startRow): boolean {
2026e80583aSopenharmony_ci    const row = info.layoutDescription.row;
2036e80583aSopenharmony_ci    const column = info.layoutDescription.column;
2046e80583aSopenharmony_ci    if ((startColumn + item.area[0]) > column || (startRow + item.area[1]) > row) {
2056e80583aSopenharmony_ci      return false;
2066e80583aSopenharmony_ci    }
2076e80583aSopenharmony_ci    let isValid = true;
2086e80583aSopenharmony_ci    for (let x = startColumn; x < startColumn + item.area[0]; x++) {
2096e80583aSopenharmony_ci      for (let y = startRow; y < startRow + item.area[1]; y++) {
2106e80583aSopenharmony_ci        if (this.isPositionOccupied(info, page, x, y)) {
2116e80583aSopenharmony_ci          isValid = false;
2126e80583aSopenharmony_ci          break;
2136e80583aSopenharmony_ci        }
2146e80583aSopenharmony_ci      }
2156e80583aSopenharmony_ci    }
2166e80583aSopenharmony_ci    return isValid;
2176e80583aSopenharmony_ci  }
2186e80583aSopenharmony_ci
2196e80583aSopenharmony_ci  private isPositionOccupied(info, page, column, row): boolean {
2206e80583aSopenharmony_ci    const pageCount = info.layoutDescription.pageCount;
2216e80583aSopenharmony_ci    const layoutInfo = info.layoutInfo;
2226e80583aSopenharmony_ci    // current page has space
2236e80583aSopenharmony_ci    for (const layout of layoutInfo) {
2246e80583aSopenharmony_ci      if (layout.page == page) {
2256e80583aSopenharmony_ci        const xMatch = (column >= layout.column) && (column < layout.column + layout.area[0]);
2266e80583aSopenharmony_ci        const yMatch = (row >= layout.row) && (row < layout.row + layout.area[1]);
2276e80583aSopenharmony_ci        if (xMatch && yMatch) {
2286e80583aSopenharmony_ci          return true;
2296e80583aSopenharmony_ci        }
2306e80583aSopenharmony_ci      }
2316e80583aSopenharmony_ci    }
2326e80583aSopenharmony_ci    return false;
2336e80583aSopenharmony_ci  }
2346e80583aSopenharmony_ci
2356e80583aSopenharmony_ci  /**
2366e80583aSopenharmony_ci   * Changing the Desktop Page Number.
2376e80583aSopenharmony_ci   *
2386e80583aSopenharmony_ci   * @param idx: Page number
2396e80583aSopenharmony_ci   */
2406e80583aSopenharmony_ci  setPageIndex(idx: number): void {
2416e80583aSopenharmony_ci    Log.showInfo(TAG, 'setPageIndex: ' + idx);
2426e80583aSopenharmony_ci    AppStorage.setOrCreate('pageIndex', idx);
2436e80583aSopenharmony_ci  }
2446e80583aSopenharmony_ci
2456e80583aSopenharmony_ci  /**
2466e80583aSopenharmony_ci   * Get the Desktop Page Number.
2476e80583aSopenharmony_ci   */
2486e80583aSopenharmony_ci  getPageIndex(): number {
2496e80583aSopenharmony_ci    return AppStorage.get('pageIndex');
2506e80583aSopenharmony_ci  }
2516e80583aSopenharmony_ci}