content: /*****************************************************************
   *   Licensed to the Apache Software Foundation (ASF) under one
   *  or more contributor license agreements.  See the NOTICE file
   *  distributed with this work for additional information
   *  regarding copyright ownership.  The ASF licenses this file
   *  to you under the Apache License, Version 2.0 (the
   *  "License"); you may not use this file except in compliance
   *  with the License.  You may obtain a copy of the License at
   *
   *    https://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing,
   *  software distributed under the License is distributed on an
   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   *  KIND, either express or implied.  See the License for the
   *  specific language governing permissions and limitations
   *  under the License.
   ****************************************************************/
  package org.apache.cayenne.swing.components.textpane;
  
  import java.awt.Color;
  import java.awt.Component;
  import java.awt.FontMetrics;
  import java.awt.Graphics;
  import java.awt.Insets;
  import javax.swing.JTextPane;
  import javax.swing.border.AbstractBorder;
  import javax.swing.text.Document;
  
  public class LineNumberedBorder extends AbstractBorder {
  	private int etalon;
  	private int lineNumberWidth;
  	private JCayenneTextPane pane;
  
  	public LineNumberedBorder(JCayenneTextPane pane) {
  		setEtalon(10);
  		this.pane = pane;
  	}
  
  	public Insets getBorderInsets(Component c) {
  		return getBorderInsets(c, new Insets(0, 0, 0, 0));
  	}
  
  	public Insets getBorderInsets(Component c, Insets insets) {
  		if (c instanceof JTextPane) {
  			int width = lineNumberWidth((JTextPane) c);
  			insets.left = width;
  		}
  		return insets;
  	}
  
  	/**
  	 * Returns the width, in pixels
  	 */
  	private int lineNumberWidth(JTextPane textPane) {
  		int lineCount = getEtalon();
  		setLineNumberWidth(textPane.getFontMetrics(textPane.getFont())
  				.stringWidth(lineCount + " "));
  		return getLineNumberWidth();
  	}
  
  	public void paintBorder(Component c, Graphics g, int x, int y, int width,
  			int height) {
  
  		java.awt.Rectangle clip = g.getClipBounds();
  
  		FontMetrics fm = g.getFontMetrics();
  		int fontHeight = fm.getHeight();
  		int ybaseline = y + fm.getAscent();
  
  		int startingLineNumber = (clip.y / fontHeight) + 1;
  
  		if (ybaseline < clip.y) {
  			ybaseline = y + startingLineNumber * fontHeight
  					- (fontHeight - fm.getAscent());
  		}
  
  
  		int yend = ybaseline + height;
  		if (yend > (y + height)) {
  			yend = y + height;
  		}
  
  		int lnxstart = x;
  		int widhtBorder = getLineNumberWidth() - 2;
  
  		g.setColor(new Color(255, 255, 224));
  		g.fillRect(lnxstart, 0, lnxstart + widhtBorder, yend);
  		g.setColor(new Color(214, 214, 214));
  		g.drawRect(lnxstart - 1, -1, lnxstart + widhtBorder, yend + 1);
  
  		int end = pane.getEndPositionInDocument();
  		Document doc = pane.getDocument();
  		int endline = doc.getDefaultRootElement().getElementIndex(end) + 1;
  			
  		while (startingLineNumber <= endline) {
  			g.setColor(Color.gray);
  			g.drawString(startingLineNumber + " ", lnxstart + 1, ybaseline);
  			ybaseline += fontHeight;
  			startingLineNumber++;
  		}
  
  		setEtalon(startingLineNumber-1);
  	}
  
  	public int getEtalon() {
  		return etalon;
  	}
  
  	public void setEtalon(int etalon) {
  		if(etalon<10){
  			etalon = 10;
  		}
  		this.etalon = etalon;
  	}
  
  	public int getLineNumberWidth() {
  		return lineNumberWidth;
  	}
  
  	public void setLineNumberWidth(int lineNumberWidth) {
  		this.lineNumberWidth = lineNumberWidth;
  	}
  }
  