//Copyright (C) 2000 Microsoft Corporation.  All rights reserved.

//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation.  See these other
//materials for detailed information regarding Microsoft code samples.

//THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.

namespace Scribble
{
using System;
using System.IO ;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

using Softelvdm.SftTabsNET;



/// <summary>
///    Summary description for Form2.
/// </summary>
public class ScribbleView : System.Windows.Forms.Form
{
    /// <summary> 
    ///    Required designer variable
    /// </summary>
    private System.ComponentModel.Container components;
    private ScribbleDoc myDoc;
    private MainWindow mainWin;

    public Point previousPoint;    // the last mouse pt in the stroke in progress
    public Stroke currentStroke;// the stroke in progress

    public ScribbleView(ScribbleDoc doc,MainWindow parent)
    {
        //
        // Required for Win Form Designer support
        //
        InitializeComponent();
        this.myDoc  = doc;
        this.MdiParent = parent; //Make this view Mdi child of the main window
        mainWin = parent;    

        // Add a new tab
        TabClass t = parent.sftTabs1.TabCollection.Add();  // create a new tab
        t.Tag1 = this; // save reference of view associated with this tab

        t.BackColorStart = Color.FromArgb(0xdd, 0xec, 0xfe);
        t.BackColorEnd = Color.FromArgb(0x81, 0xA9, 0xE2);
        t.BackColor = Color.FromArgb(0x81, 0xA9, 0xE2);
        t.BackColorSelectedStart = Color.FromArgb(0xDD, 0xEC, 0xFE);
        t.BackColorSelectedEnd = Color.FromArgb(0x81, 0xA9, 0xE2);
        t.BackColorActive = Color.FromArgb(0x81, 0xA9, 0xE2);
        SetTitle("");
    }

    /// <summary>
    ///    Clean up any resources being used
    /// </summary>
    protected override void Dispose( bool disposing )
    {
        // Find the tab that describes this form (we saved a reference
        // to the form object in the tab's Tag1 property)
        // We have to delete that tab because the MDI Child
        // is going away
        MainWindow parent = MdiParent as MainWindow;

        // remove the tab representing this form
        if (parent.sftTabs1 != null) {
            foreach (TabClass t in parent.sftTabs1.TabCollection) {
                if (t.Tag1 == this) {
                    parent.sftTabs1.TabCollection.RemoveAt(t.Index);
                    break;
                }
            }
        }
        if( disposing )
        {
            if (components != null) 
            {
                components.Dispose();
            }
        }
        base.Dispose( disposing );
    }

    /// <summary>
    ///    Required method for Designer support - do not modify
    ///    the contents of this method with the code editor
    /// </summary>
    private void InitializeComponent()
    {
        // 
        // ScribbleView
        // 
        this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
        this.BackColor = System.Drawing.Color.White;
        this.ClientSize = new System.Drawing.Size(373, 320);
        this.Name = "ScribbleView";
        this.Text = "ScribbleDoc";
        this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MouseDownHandler);
        this.Closing += new System.ComponentModel.CancelEventHandler(this.ClosingHandler);
        this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.MouseUpHandler);
        this.Closed += new System.EventHandler(this.ClosedHandler);
        this.Paint += new System.Windows.Forms.PaintEventHandler(this.PaintHandler);
        this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.MouseMoveHandler);

    }

    public void SetTitle(string fileName) {
        if (fileName == "") {
            // empty, new document
            if (myDoc.viewList.Count <= 1)
                this.Text = "New Document" + myDoc.docID.ToString();
            else
                this.Text = "New Document" + myDoc.docID.ToString() + ":" + myDoc.viewList.Count.ToString();
            fileName = "New Document";
        } else {
            // existing file
            if (myDoc.viewList.Count <= 1)
                this.Text = Path.GetFileName(fileName);
            else
                this.Text = Path.GetFileName(fileName) + ":" + myDoc.viewList.Count.ToString();
        }
        foreach (TabClass t in mainWin.sftTabs1.TabCollection) {
            if (t.Tag1 == this) {
                t.Text = this.Text;
                t.ToolTip = fileName;
                break;
            }
        }
    }
    private void MouseDownHandler(Object sender, MouseEventArgs e)
    {
        if(!this.Capture)
            return;

        try{
            Point p = new Point(e.X,e.Y);
            currentStroke = myDoc.NewStroke();
            currentStroke.pointArray.Add(p);// Add first point to the new stroke            
            previousPoint = p;
            
            this.Capture = true; // Capture the mouse until button up                        
        }
        catch(Exception ex) {
            MessageBox.Show(ex.ToString());
        }

    }


    private void MouseMoveHandler(Object sender,MouseEventArgs e)
    {
        if(!this.Capture)
            return;

        try{            
            Point p = new Point(e.X , e.Y);            
            currentStroke.pointArray.Add(p);
            Graphics g = this.CreateGraphics();
            g.DrawLine(myDoc.GetCurrentPen(),previousPoint,p);

            previousPoint = p;                            
        }
        catch (Exception ex) { 
            MessageBox.Show(ex.ToString());            
        }

    }


    private void MouseUpHandler(Object sender,MouseEventArgs e)
    {    
        //If the current stroke is null, ignore this event
        if(currentStroke==null)
            return;

        try{
            Point p= new Point(e.X,e.Y);
            currentStroke.pointArray.Add(p);
            Graphics g = this.CreateGraphics();
            g.DrawLine(myDoc.GetCurrentPen(),previousPoint,p);
                    
            previousPoint=p;    
            // Tell the stroke item that we're done adding points to it.
            // This is so it can finish computing its bounding rectangle.
            currentStroke.FinishStroke();            
            
            // Now that a stoke is added, inform all the views of the document about this
            myDoc.UpdateAllViews(this,currentStroke);       
        
            this.Capture = false;
        
        }
        catch (Exception ex) { 
            MessageBox.Show(ex.ToString());            
        }

    }

    private void PaintHandler(Object sender, PaintEventArgs e)
    {
        Rectangle rectClip = e.ClipRectangle;;
        rectClip.Inflate(1,1);
        Rectangle rectStroke;
                      
        for(int i=0; i < myDoc.strokeList.Count; i++)
        {
            Stroke st = (Stroke)myDoc.strokeList[i];
            rectStroke = st.GetBoundingRectangle();
            rectStroke.Inflate(1, 1); // avoid rounding to nothing
            if (!rectStroke.IntersectsWith(rectClip))
                continue;
            st.DrawStroke(e.Graphics) ;                        
        }        
    }

    public void ClosingHandler(Object sender, CancelEventArgs e)
    {
        if(myDoc.isDirty && myDoc.viewList.Count == 1)
        {
            DialogResult save = MessageBox.Show("Do you want to save changes ?","Scribble",MessageBoxButtons.YesNoCancel);
            if(save == DialogResult.Yes)
            {
                SaveFileDialog saveDlg = new SaveFileDialog();
                saveDlg.Filter = "Scribble Files (*.scb)|*.scb|All Files (*.*)|*.*";
                saveDlg.DefaultExt = ".scb";
                if (myDoc.docFileName == "") 
                    saveDlg.FileName = "Untitled";
                else
                    saveDlg.FileName = myDoc.docFileName;
                DialogResult res = saveDlg.ShowDialog ();
                
                if(res == DialogResult.OK)
                {
                    myDoc.SaveDocument(saveDlg.FileName);    
                    myDoc.viewList.Remove(this);
                    this.MdiParent=null;// remove this view(child) from the parent list
                }
                else if(res == DialogResult.Cancel)
                    e.Cancel = true;
                    
            }
                
            else if(save == DialogResult.Cancel)
                    e.Cancel = true; //If user selected 'Cancel',don't close the form
            
            else if(save == DialogResult.No)
            {
                myDoc.viewList.Remove(this);                
            }                
        }
        else
        {
            myDoc.viewList.Remove(this);                
        }        
    }

    public void ClosedHandler(Object sender,EventArgs e)
    {        
        //If there are no child views, then disable menu and toolbar items
        if (mainWin.MdiChildren.Length <= 1 )
            mainWin.DisableItems();                    
    }
    
    public ScribbleDoc GetDocument()
    {
        return myDoc;
    }


}
}