/*
* CategoryManager.java
*/
package gnt;
import palm.conduit.*;
import java.io.*;
import java.util.*;
/* Copyright (c) 1997-2001 Palm Inc. or its subsidiaries. All rights reserved. */
/**
* Performs all actions related to synchronizing Categories between the PC and hand-held device.
*/
public class CategoryManager {
private int db;
SyncProperties props;
byte[] bytes; //the array of bytes from the hand-held device which contains the AppInfoBlock
/** Constructor
* @param props The SyncProperties object created while running the conduit.
* @param db The handle of the open database.
*/
// public CategoryManager(SyncProperties props, int db) {
// this.props = props;
// this.db = db;
// }
//
// /** Accesses the AppInfoBlock from the hand-held device and parses it into a Vector
// * of category objects.
// * @return A Vector of category objects
// */
// public Vector getHHCategories() throws IOException {
// //use the javasync api to read the AppInfoBlock from the AddressDB
// bytes = SyncManager.readDBAppInfoBlock(db, props.remoteNames[0]);
// return Category.parseCategories(bytes);
// }
//
// /*
// * Performs mirror synchronization of the hand-held and PC categories. This method
// * automatically reads categories from the hand-held device and writes the
// * synchronized categories back to the device.
// * First, the algorithm loops through all the Categories found on the device and
// * deletes those that have been deleted on the PC. Next the PC Categories
// * are compared to the device categories one at a time. Categories that are not found
// * in the device categories are deleted, categories with name modifications are
// * synchronized, etc. The synchronization logic assumes that each PC and device category
// * has a status field (isModified) to indicate that the Category has been modified.
// * The synchronization algorithm can be summarized by the following table:
// *
// * Palm Rec State | PC Rec State | Action |
// *
// * Add | No category | The category is added on the PC. |
// * No category | Add | The category is added on the handheld. |
// * Delete | No modify | The category is deleted on the PC. |
// * No modify | Delete | The category is deleted on the handheld. |
// * Modify | Delete | The device modifications are reflected on the PC. The PC category is not deleted. |
// * Delete | Modify | The PC modifications are reflected on the device. The device category is not deleted. |
// * Modify | No modify | The device modifications are reflected on the PC. |
// * No modify | Modify | The PC modifications are reflected on the device. |
// * Modify | Modify | If the modifications are identical, no action is taken. |
// * Modify | Modify | If the modifications are different, both categories are placed on both the PC and device. |
// *
// * @param pcCategories A Vector of category objects that exist on the PC
// * @param pcRecords A vector of record objects that exist on the PC
// * @return A Vector of synchronized category objects
// * @exception java.io.IOException thrown if cannot read the categories
// */
// public Vector synchronize(Vector pcCategories, Vector pcRecords) throws IOException{
//
// Vector hhCategories;
// Category hhCat, pcCat;
// boolean deleteCat;
//
// //parse out the category information from the device
// hhCategories = getHHCategories();
//
// if (props.syncType == props.SYNC_DO_NOTHING) {
//
// // Do nothing to the pcCategories
// return pcCategories;
//
// } else if (props.syncType == props.SYNC_HH_TO_PC) {
//
// // Copy HH categories to PC
// return hhCategories;
//
// } else if (pcCategories.size() == 0) {
//
// // This will initialize a test file of categories if the pc categories are empty
// // Copy HH categories to PC
// for (int i = 0; i < hhCategories.size(); i ++){
// hhCat = (Category)hhCategories.elementAt(i);
// hhCat.setIsModified(false);
// }
// writeHHCategories(hhCategories);
// return hhCategories;
//
// } else if (props.syncType == props.SYNC_PC_TO_HH) {
//
// // Copy the PC categories to the HH, done below.
//
// } else { // FastSync or SlowSync
//
// // If the PC has not yet be synced with, then set all the HH category flags so
// // those HH categories get added and not deleted
// if (props.firstDevice == props.SYNC_PC_FIRST_SYNC) {
// setDirtyCategoryFlags(hhCategories);
//
// // If the HH has not yet be synced with, then set all the PC category flags so
// // those PC categories get added and not deleted
// } else if (props.firstDevice == props.SYNC_HH_FIRST_SYNC) {
// setDirtyCategoryFlags(pcCategories);
//
// // If this is a slow sync that means that the last sync was with
// // a different PC, so set the category dirty flags on the HH
// // because they were cleared in the last sync.
// } else if (props.syncType == props.SYNC_SLOW) {
// setDirtyCategoryFlags(hhCategories);
// }
//
// // First search through the HH categories and delete the categories that
// // were deleted from the PC and need to be deleted from the HH.
// // A category needs to be deleted when the category exists on one side
// // and not the other and the dirty flag is off.
//
// for (int i = 0; i < hhCategories.size(); i ++){
//
// hhCat = (Category)hhCategories.elementAt(i);
//
// deleteCat = true;
//
// if (!hhCat.getName().equals("") && !hhCat.isModified() &&
// matchName(hhCat.getName(), pcCategories) == null &&
// matchId(hhCat.getId(), pcCategories) == null) {
//
// // The category has been deleted on the PC, so needs
// // to be deleted on the HH. Also, change all the
// // records under that category to be Unfiled.
// // Move records to unfiled - Report to Log
// try {
// SyncManager.changeCategory(db, hhCat.getIndex(), 0);
// } catch(SyncException e){
//
// Log.err("MemoCond Error: Error Changing Categories");
// e.printStackTrace();
// deleteCat = false;
// }
//
// if (deleteCat){
// Log.out("Handheld Category Deleted: " + hhCat.getName());
// hhCat.delete();
// }
// }
// else hhCat.setIsModified(false);
// }
//
// // Merge the PC categories into the HH categories
// for (int i = 0; i < pcCategories.size(); i++){
//
// pcCat = (Category)pcCategories.elementAt(i);
//
// if (!pcCat.getName().equals("")){
//
// hhCat = matchName(pcCat.getName(), hhCategories);
//
// if(hhCat != null){
//
// // PC catName exists on HH
// // catIndexes are different and HH index must be chosen
// if (pcCat.getIndex() != hhCat.getIndex()) {
// // Change the PC catIndex
// int oldCatIndex = pcCat.getIndex();
// pcCat.setIndex(hhCat.getIndex());
// // Update PC records belonging to that PC category
// // to it's new category index assigned from handheld
// updateRecordsCategory(pcRecords, oldCatIndex, pcCat.getIndex());
// }
// }
// else { // PC catName does not exist on HH
//
// // if PC catID exists on HH
// hhCat = matchId(pcCat.getId(), hhCategories);
// if (hhCat != null) {
// // If PC category was renamed, then replace the HH
// // catName with the PC catName
// if (pcCat.isModified()) {
//
// hhCat.setName(pcCat.getName());
//
// // If the indexes are different, change the PC catIndex
// } else if (pcCat.getIndex() != hhCat.getIndex()) {
// int oldCatIndex = pcCat.getIndex();
// pcCat.setIndex(hhCat.getIndex());
// // Update PC records belonging to that PC category
// // to it's new category index assigned from handheld
// updateRecordsCategory(pcRecords, oldCatIndex, pcCat.getIndex());
// }
// }
// else {
//
// // If the category exists on the PC but not on the HH and
// // the dirty flag is not on, the category must have been
// // deleted on the HH, therefore needs to be deleted on PC.
// if (!pcCat.isModified()) {
// // Report to Log
// Log.out("Desktop Category Deleted: " + pcCat.getName());
// pcCat.delete();
//
// } else { // New category from PC
//
// hhCat = (Category)hhCategories.elementAt(pcCat.getIndex());
//
// // PC catIndex does not exist on HH, so add PC category
// // as is to the HH Category Manager
// if (hhCat.getName().equals("")) {
// hhCat.setName(pcCat.getName());
// hhCat.setId(pcCat.getId());
//
// } else { // PC catIndex already exists
//
// // Find the next available catIndex on the HH
// int nextIndex = getNextIndex(hhCategories);
//
// if (nextIndex == -1) { // Category Manager is Full
//
// // Too many categories - Report to Log
// Log.out("MemoCond Error: Too Many Categories. Category not added to handheld device: " + pcCat.getName());
// } else {
//
// // Change PC catIndex to next available HH catIndex
// int oldCatIndex = pcCat.getIndex();
// pcCat.setIndex(nextIndex);
//
// // Add the PC Category
// hhCat = (Category)hhCategories.elementAt(nextIndex);
// hhCat.setName(pcCat.getName());
// hhCat.setId(pcCat.getId());
//
// // Update PC records belonging to that PC category
// // to it's new category index assigned from handheld
// updateRecordsCategory(pcRecords, oldCatIndex, pcCat.getIndex());
// }
// }
// }
// }
// }
// }
// }
// }
//
// //point the input categories at the synchronized hhCategories
// pcCategories = hhCategories;
//
// //write the categories back out to the AppInfoBlock on the device
// writeHHCategories(hhCategories);
// return hhCategories;
// }
//
// /** Writes a Vector of category objects back to the device.
// * @param hhCategories A Vector of category objects to be written to the device
// */
// public void writeHHCategories(Vector hhCategories) throws IOException{
// byte []tmp = Category.toBytes(hhCategories);
// System.arraycopy(tmp, 0, bytes, 0, tmp.length);
//
// //write the synchronized categories to the device
// SyncManager.writeDBAppInfoBlock(db, props.remoteNames[0], bytes);
// }
//
// private void setDirtyCategoryFlags(Vector hhCategories){
//
// for (int i = 0; i < hhCategories.size(); i++) {
// Category tempCategory = (Category)hhCategories.elementAt(i);
// tempCategory.setIsModified(true);
// }
// }
//
// //this method searches for a particular category name within a vector of categories
// private Category matchName(String name, Vector categories){
//
// Category category;
// String categoryName;
//
// for (int i = 0; i < categories.size(); i++) {
//
// category = (Category)categories.elementAt(i);
//
// categoryName = category.getName();
//
// if (categoryName != "" && name.equals(categoryName)) {
// return category;
// }
// }
// return null;
// }
// //this method searches for a particular category id within a vector of categories
// private Category matchId(int id, Vector categories){
//
// Category category;
//
// for (int i = 0; i < categories.size(); i++) {
//
// category = (Category)categories.elementAt(i);
//
// if (id == category.getId() && id != 0) {
// return category;
// }
// }
// return null;
// }
//
// private int getNextIndex(Vector categories) {
//
// int nextIndex = -1;
// Category tempCategory;
//
// for (int i = 0; i < categories.size(); i++) {
//
// tempCategory = (Category)categories.elementAt(i);
//
// if (tempCategory.getName().equals("")){
// nextIndex = tempCategory.getIndex();
// return nextIndex;
// }
// }
// return nextIndex;
// }
//
// private void updateRecordsCategory(Vector pcRecords, int oldCatIndex, int newCatIndex) {
//
// // Cycle throught the pcRecords vector and replace
// // the old cat index with the new cat index
// if (pcRecords != null) {
//
// Record pcRecord;
// pcRecords.trimToSize();
//
// for (int i = 0; i < pcRecords.size(); i++){
//
// pcRecord = (Record)pcRecords.elementAt(i);
// if (pcRecord.getCategoryIndex() == oldCatIndex)
// pcRecord.setCategoryIndex(newCatIndex);
// }
// }
// }
}