public SlidingBlockType(SlidingBlockType copy, int typeID)
 {
     SubBlocks = new ObservableCollection<Point>(copy.SubBlocks);        // Point is a struct so values will be copied
     SizeX = copy.SizeX;
     SizeY = copy.SizeY;
     TypeID = typeID;
 }
 void addTargetBlock(object o)
 {
     // Copy block to the target grid and add a new BlockType for it so that the target BlockType is unique for hashing purposes
     object[] args = (object[])o;
     int cellX = (int)args[0];
     int cellY = (int)args[1];
     int blockID = (int)args[2];
     clearTarget();
     // Create another BlockType clone of the target block
     SlidingBlockType targetBlockType = new SlidingBlockType(Blocks[blockID].BlockType, blockPalette.Count);
     // Add it to the palette
     blockPalette.Add(targetBlockType);
     // Update the BlockType of the target block on the main grid to this new BlockType
     Blocks[blockID].BlockType = targetBlockType;
     // Copy the block and add it to the target grid
     SlidingBlock block = new SlidingBlock(cellX, cellY, targetBlockType, blockID);
     TargetBlocks.Add(block);
 }
 void addToBlock(object o)
 {
     // Continue the creation of a new block on the main grid
     if (currentBlock == null) return;   // Return if creating a new block is not in progress
     object[] args = (object[])o;        // int cellX, int cellY, IEnumerable<Tuple<int, int>> subBlocks
     int cellX = (int)args[0];
     int cellY = (int)args[1];
     if (occupied[cellX, cellY]) return;
     clearTarget();
     occupied[cellX, cellY] = true;
     currentType.AddSubBlock(cellX - currentBlock.CellX, cellY - currentBlock.CellY);
     if (cellX < currentBlock.CellX)
         currentBlock.CellX = cellX;
     if (cellY < currentBlock.CellY)
         currentBlock.CellY = cellY;
     SlidingBlockType blockType = blockPalette.SingleOrDefault(b => b.Equals(currentType));
     if (blockType == null)
     {
         // Create and add a copy of currentType
         blockType = new SlidingBlockType(currentType, blockPalette.Count);
         blockPalette.Add(blockType);
     }
     currentBlock.BlockType = blockType;         // Current block's BlockType = matching BlockType from the palette
 }
 void addNewBlock(object o)
 {
     // Clear the target block and start the creation of a new block on the main grid
     object[] args = (object[])o;        // int cellX, int cellY
     int cellX = (int)args[0];
     int cellY = (int)args[1];
     clearTarget();
     if (!occupied[cellX, cellY])
     {
         currentBlock = new SlidingBlock(cellX, cellY,blockPalette[0], Blocks.Count);          // Create 1x1 block, BlockType 0, blockID is the index into Blocks
         currentType = new SlidingBlockType(blockPalette[0]);
         Blocks.Add(currentBlock);
         occupied[cellX, cellY] = true;
     }
 }
 public SlidingBlock(int cellX, int cellY, SlidingBlockType blockType, int blockID)
 {
     CellX = cellX;
     CellY = cellY;
     BlockType = blockType;
     BlockID = blockID;
 }