private void  encodeStraightEdgeRecord(StraightEdgeRecord line, SwfEncoder w, int nbits)
		{
			if (line.deltaX == 0)
			{
				w.writeUBits(1, 2); // vertical line
				w.writeSBits(line.deltaY, nbits);
			}
			else if (line.deltaY == 0)
			{
				w.writeUBits(0, 2); // horizontal line
				w.writeSBits(line.deltaX, nbits);
			}
			else
			{
				w.writeBit(true); // general line
				w.writeSBits(line.deltaX, nbits);
				w.writeSBits(line.deltaY, nbits);
			}
		}
		private void  encodeStyleChangeRecord(SwfEncoder w, StyleChangeRecord s, int[] numFillBits, int[] numLineBits, int shape)
		{
			w.writeBit(s.stateNewStyles);
			w.writeBit(s.stateLineStyle);
			w.writeBit(s.stateFillStyle1);
			w.writeBit(s.stateFillStyle0);
			w.writeBit(s.stateMoveTo);
			
			if (s.stateMoveTo)
			{
				int moveBits = s.nMoveBits();
				w.writeUBits(moveBits, 5);
				w.writeSBits(s.moveDeltaX, moveBits);
				w.writeSBits(s.moveDeltaY, moveBits);
			}
			
			if (s.stateFillStyle0)
			{
				w.writeUBits(s.fillstyle0, numFillBits[0]);
			}
			
			if (s.stateFillStyle1)
			{
				w.writeUBits(s.fillstyle1, numFillBits[0]);
			}
			
			if (s.stateLineStyle)
			{
				w.writeUBits(s.linestyle, numLineBits[0]);
			}
			
			if (s.stateNewStyles)
			{
				w.flushBits();
				
				encodeFillstyles(s.fillstyles, w, shape);
				encodeLinestyles(s.linestyles, w, shape);
				
				numFillBits[0] = SwfEncoder.minBits(s.fillstyles.Count, 0);
				numLineBits[0] = SwfEncoder.minBits(s.linestyles.Count, 0);
				w.writeUBits(numFillBits[0], 4);
				w.writeUBits(numLineBits[0], 4);
			}
		}
		private void  encodeSoundInfo(SoundInfo info, SwfEncoder w)
		{
			w.writeUBits(0, 2); // reserved
			w.writeBit(info.syncStop);
			w.writeBit(info.syncNoMultiple);
			w.writeBit(info.records != null);
			w.writeBit(info.loopCount != SoundInfo.UNINITIALIZED);
			w.writeBit(info.outPoint != SoundInfo.UNINITIALIZED);
			w.writeBit(info.inPoint != SoundInfo.UNINITIALIZED);
			
			if (info.inPoint != SoundInfo.UNINITIALIZED)
			{
				w.write32((int) info.inPoint);
			}
			if (info.outPoint != SoundInfo.UNINITIALIZED)
			{
				w.write32((int) info.outPoint);
			}
			if (info.loopCount != SoundInfo.UNINITIALIZED)
			{
				w.writeUI16(info.loopCount);
			}
			if (info.records != null)
			{
				w.writeUI8(info.records.Length);
				for (int k = 0; k < info.records.Length; k++)
				{
					w.write64(info.records[k]);
				}
			}
		}
		public virtual void  encodeShape(Shape s, SwfEncoder w, int shape, int nFillStyles, int nLineStyles)
		{
			int[] numFillBits = new int[]{SwfEncoder.minBits(nFillStyles, 0)};
			int[] numLineBits = new int[]{SwfEncoder.minBits(nLineStyles, 0)};
			
			w.writeUBits(numFillBits[0], 4);
			w.writeUBits(numLineBits[0], 4);
			
			System.Collections.IEnumerator it = s.shapeRecords.GetEnumerator();
			//UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
			while (it.MoveNext())
			{
				//UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
				ShapeRecord record = (ShapeRecord) it.Current;
				if (record is StyleChangeRecord)
				{
					// style change
					w.writeBit(false);
					StyleChangeRecord change = (StyleChangeRecord) record;
					encodeStyleChangeRecord(w, change, numFillBits, numLineBits, shape);
				}
				else
				{
					// edge
					w.writeBit(true);
					EdgeRecord e = (EdgeRecord) record;
					bool straight = e is StraightEdgeRecord;
					w.writeBit(straight);
					int nbits = straight?calcBits((StraightEdgeRecord) e):calcBits((CurvedEdgeRecord) e);
					if (nbits < 2)
						nbits = 2;
					w.writeUBits(nbits - 2, 4);
					if (straight)
					{
						// line
						StraightEdgeRecord line = (StraightEdgeRecord) e;
						encodeStraightEdgeRecord(line, w, nbits);
					}
					else
					{
						// curve
						CurvedEdgeRecord curve = (CurvedEdgeRecord) e;
						w.writeSBits(curve.controlDeltaX, nbits);
						w.writeSBits(curve.controlDeltaY, nbits);
						w.writeSBits(curve.anchorDeltaX, nbits);
						w.writeSBits(curve.anchorDeltaY, nbits);
					}
				}
			}
			
			// endshaperecord
			w.writeUBits(0, 6);
			
			w.flushBits();
		}
		private void  encodeButtonCondAction(ButtonCondAction condAction, SwfEncoder w, bool last)
		{
			int pos = w.Pos;
			w.writeUI16(0);
			
			w.writeUBits(condAction.keyPress, 7);
			w.writeBit(condAction.overDownToIdle);
			
			w.writeBit(condAction.idleToOverDown);
			w.writeBit(condAction.outDownToIdle);
			w.writeBit(condAction.outDownToOverDown);
			w.writeBit(condAction.overDownToOutDown);
			w.writeBit(condAction.overDownToOverUp);
			w.writeBit(condAction.overUpToOverDown);
			w.writeBit(condAction.overUpToIdle);
			w.writeBit(condAction.idleToOverUp);
			
			new ActionEncoder(w, debug).encode(condAction.actionList);
			w.writeUI8(0); // end action byte
			
			if (!last)
			{
				w.writeUI16at(pos, w.Pos - pos);
			}
		}
		private void  encodeCxform(CXForm cxform, SwfEncoder w)
		{
			
			w.writeBit(cxform.hasAdd);
			w.writeBit(cxform.hasMult);
			
			int nbits = cxform.nbits();
			w.writeUBits(nbits, 4);
			
			if (cxform.hasMult)
			{
				w.writeSBits(cxform.redMultTerm, nbits);
				w.writeSBits(cxform.greenMultTerm, nbits);
				w.writeSBits(cxform.blueMultTerm, nbits);
			}
			
			if (cxform.hasAdd)
			{
				w.writeSBits(cxform.redAddTerm, nbits);
				w.writeSBits(cxform.greenAddTerm, nbits);
				w.writeSBits(cxform.blueAddTerm, nbits);
			}
			
			w.flushBits();
		}
		private void  encodeCxforma(CXFormWithAlpha cxforma, SwfEncoder w)
		{
			w.writeBit(cxforma.hasAdd);
			w.writeBit(cxforma.hasMult);
			
			int nbits = cxforma.nbits();
			w.writeUBits(nbits, 4);
			
			if (cxforma.hasMult)
			{
				w.writeSBits(cxforma.redMultTerm, nbits);
				w.writeSBits(cxforma.greenMultTerm, nbits);
				w.writeSBits(cxforma.blueMultTerm, nbits);
				w.writeSBits(cxforma.alphaMultTerm, nbits);
			}
			
			if (cxforma.hasAdd)
			{
				w.writeSBits(cxforma.redAddTerm, nbits);
				w.writeSBits(cxforma.greenAddTerm, nbits);
				w.writeSBits(cxforma.blueAddTerm, nbits);
				w.writeSBits(cxforma.alphaAddTerm, nbits);
			}
			
			w.flushBits();
		}
		private void  encodeMatrix(Matrix matrix, SwfEncoder w)
		{
			w.writeBit(matrix.hasScale);
			if (matrix.hasScale)
			{
				int nScaleBits = matrix.nScaleBits();
				w.writeUBits(nScaleBits, 5);
				w.writeSBits(matrix.scaleX, nScaleBits);
				w.writeSBits(matrix.scaleY, nScaleBits);
			}
			
			w.writeBit(matrix.hasRotate);
			if (matrix.hasRotate)
			{
				int nRotateBits = matrix.nRotateBits();
				w.writeUBits(nRotateBits, 5);
				w.writeSBits(matrix.rotateSkew0, nRotateBits);
				w.writeSBits(matrix.rotateSkew1, nRotateBits);
			}
			
			int nTranslateBits = matrix.nTranslateBits();
			w.writeUBits(nTranslateBits, 5);
			w.writeSBits(matrix.translateX, nTranslateBits);
			w.writeSBits(matrix.translateY, nTranslateBits);
			
			w.flushBits();
		}
		private void  encodeButtonRecord(ButtonRecord record, SwfEncoder w, int defineButton)
		{
			if (defineButton == flash.swf.TagValues_Fields.stagDefineButton2)
			{
				w.writeUBits(0, 2);
				w.writeBit(record.blendMode != - 1);
				w.writeBit(record.filters != null);
			}
			else
			{
				w.writeUBits(0, 4);
			}
			w.writeBit(record.hitTest);
			w.writeBit(record.down);
			w.writeBit(record.over);
			w.writeBit(record.up);
			
			w.writeUI16(dict.getId(record.characterRef));
			w.writeUI16(record.placeDepth);
			encodeMatrix(record.placeMatrix, w);
			
			if (defineButton == flash.swf.TagValues_Fields.stagDefineButton2)
			{
				encodeCxforma(record.colorTransform, w);
				if (record.filters != null)
				{
					this.encodeFilterList(record.filters, w);
				}
				if (record.blendMode != - 1)
				{
					w.writeUI8(record.blendMode);
				}
			}
		}
		public virtual void  encodeRect(Rect r, SwfEncoder w)
		{
			int nBits = r.nbits();
			w.writeUBits(nBits, 5);
			w.writeSBits(r.xMin, nBits);
			w.writeSBits(r.xMax, nBits);
			w.writeSBits(r.yMin, nBits);
			w.writeSBits(r.yMax, nBits);
			w.flushBits();
		}
		private void  encodeTextRecord(TextRecord record, SwfEncoder w, int type, int glyphBits, int advanceBits)
		{
			w.writeUI8(record.flags);
			
			if (record.hasFont())
			{
				w.writeUI16(dict.getId(record.font));
			}
			
			if (record.hasColor())
			{
				if (type == flash.swf.TagValues_Fields.stagDefineText2)
					encodeRGBA(record.color, w);
				else
					encodeRGB(record.color, w);
			}
			
			if (record.hasX())
			{
				w.writeSI16(record.xOffset);
			}
			
			if (record.hasY())
			{
				w.writeSI16(record.yOffset);
			}
			
			if (record.hasHeight())
			{
				w.writeUI16(record.height);
			}
			
			w.writeUI8(record.entries.Length);
			
			for (int i = 0; i < record.entries.Length; i++)
			{
				w.writeUBits(record.entries[i].Index, glyphBits);
				w.writeSBits(record.entries[i].advance, advanceBits);
			}
			w.flushBits();
		}
		private void  encodeMorphLinestyles(MorphLineStyle[] lineStyles, SwfEncoder w, int code)
		{
			if (lineStyles.Length >= 0xFF)
			{
				w.writeUI8(0xFF);
				w.writeUI16(lineStyles.Length);
			}
			else
			{
				w.writeUI8(lineStyles.Length);
			}
			
			for (int i = 0; i < lineStyles.Length; i++)
			{
				MorphLineStyle style = lineStyles[i];
				w.writeUI16(style.startWidth);
				w.writeUI16(style.endWidth);
				if (code == flash.swf.TagValues_Fields.stagDefineMorphShape2)
				{
					w.writeUBits(style.startCapsStyle, 2);
					w.writeUBits(style.jointStyle, 2);
					w.writeBit(style.hasFill);
					w.writeBit(style.noHScale);
					w.writeBit(style.noVScale);
					w.writeBit(style.pixelHinting);
					w.writeUBits(0, 5); // reserved
					w.writeBit(style.noClose);
					w.writeUBits(style.endCapsStyle, 2);
					if (style.jointStyle == 2)
					{
						w.writeUI16(style.miterLimit);
					}
				}
				if (!style.hasFill)
				{
					encodeRGBA(style.startColor, w);
					encodeRGBA(style.endColor, w);
				}
				if (style.hasFill)
				{
					encodeMorphFillstyle(style.fillType, w, code);
				}
			}
		}
		private void  encodeGradient(Gradient gradient, SwfEncoder w, int shape)
		{
			w.writeUBits(gradient.spreadMode, 2);
			w.writeUBits(gradient.interpolationMode, 2);
			w.writeUBits(gradient.records.Length, 4);
			for (int i = 0; i < gradient.records.Length; i++)
			{
				encodeGradRecord(gradient.records[i], w, shape);
			}
			if (gradient is FocalGradient)
			{
				w.writeFixed8(((FocalGradient) gradient).focalPoint);
			}
		}